rrxv6 : 記憶體管理 Rust memory allocator

故事是這樣子的,雖然在上上篇的 Context Switch 我們曾經預告過因為 static 的問題, 可能要停更一段時間,但後來沒停更,static 問題很快就用 spin 提供的 no_std Mutex 解決了。
不過,no_std Mutex 雖然解決 static 不用手爆 constructor 的問題,同時卻產生了另一個問題:stack overflow。

因為呼叫 static variable constructor 會用到 os process 的 stack,static variable size 一大,os process 的 stack 就會被吃乾抹淨。
所以問題來了,我們必須要儘可能的縮小 static variable 的尺寸,像上篇把 process 的 context 全塞在裡面是不可能的 (為了讓 code 動起來我把 process 數量降到剩 2 個),因此下一步就很清楚了,必須挑戰作業系統裡一大難題:記憶體管理

...

rrxv6 : spin mutex

故事是這樣子的,上一篇我們使用 unsafe 來操作 global variable,並用這個做到 cooperative multitask, 很不幸的這個方法是不行的,包括幾個問題:

  1. 身為 Rustacean 非不得已怎麼可以用 unsafe 呢?這樣狂用 unsafe 根本離經叛道
  2. 當 static 的型態複雜到一個程度的時候,這樣手爆資料型態絕不是方法,一定要使用 default 才行。

稍微搜尋一下之後,果然找到一個可行的方案,用社群提供的 crate spin , 可以在 #[no_std] 的狀況下提供 Mutex(有關如何實作 Rust Mutex,' 可以參見這篇文章

...

rrxv6 : Context Switch 與 Global Data

首先先預告一下,這篇有可能會是本系列連續更新的最後一篇,更新完這篇之後我要去閉關念書(看 code)一段時間,原因我等等會說明。

上一篇我們提到在 rust 裡面實作實際對應實體暫存器的程式碼,同時也確定這些程式碼可以真的提供無額外成本的虛擬化, 這篇順著 mini-arm-os 的腳步,來實作 Context Switch;timer 的設定我們先跳過,畢竟這篇還不會實作到 timer interrupt 觸發 context switch。

...

rrxv6 : Embedded Rust

上一回我們看到我們用 rust 寫了一些底層的 code,當然,這個寫法並不好看,有沒有更漂亮的寫法呢? 這篇參考了 rust cortex-m 的寫法, 以及強者我同學在 Google 大殺四方的小新大大分享的文 A guide to better embedded C++

...

rrxv6 : stack pointer

上一篇我們成功讓 assembly 執行一個 jump 跳進 Rust 函式,但這樣其實一點用也沒有,畢竟只會 loop 的作業系統並不是一個很好的作業系統; 這篇我們就參考一下 xv6 的開機流程,然後試著用 Rust 重新實作。

...

rrxv6 : riscv Hello World in OS

故事是這樣子的,大概六月中的時候,小弟因緣際會空出一些時間,因為武肺持續三級警戒只能待在家裡,除了打混摸魚之外順便看了一下別人寫的翻譯文 embedonomicon,翻完之後看看 rust cortex-m 都被人做走了,那有什麼東西可以玩的呢?
有一天晚上上床的時候就想到了,剛好最近在想看一下 MIT 教學用的作業系統 xv6,看看究竟可以用的作業系統是怎麼實作的, 而 xv6 本來是針對 x86 處理器,最近才被移植到新的 riscv 處理器上, 也有人把 xv6 用 rust 重新實作 ,那我是不是能如下圖,填上這個表格最後一個空格呢?

C Rust
x86 xv6 legacy xv6-rust
Riscv xv6-riscv 404 Not Found
...

在 2021 年要如何開發 Rust 裸機程式:函式庫

這應該是裸機程式的最後一篇了,回顧一下第一篇所說,到現代幾個進化的點,

  1. Rustup
  2. cargo config
  3. rlibc
  4. 用 library

前三點我們已經看過了

  1. 用 rustup 來安裝 target,雖然我後來想了一下,覺得這並不是 rust 勝過 C 而是 LLVM 勝過 gcc,rust 只是站在 LLVM 的肩膀上所以看得更遠而已。
  2. cargo config 就如前文所述,利用 .cargo/config 來設定編譯目標,以及連結時的 linker script ,只要套用不同的 config 就能對不同目標編譯。
  3. rlibc 可能比較隱晦一點,但 rlibc 要提供的 memset/memcpy/memmove ,在 core::ptr 裡面已經提供了核心的實作了,所以不需要再引入 rlibc。

最後就是用 library 啦,在前面的篇章都沒提到這個,為什麼?

...

在 2021 年要如何開發 Rust 裸機程式:.bss 和 .data

現在的 main 程式現在只能使用 stack variable,還不能使用 static 變數,因為我們在 linker 內只放了 .text 區段, static 變數 所用的 .data(已初始化)、.bss(未初始化) 都還沒準備。

...

在 2021 年要如何開發 Rust 裸機程式:分離核心與 exception handler

我們的最小程式現在能進到 reset_handler 了,但重要的是能進到使用者寫的 main 函式,不然這個 kernel 也沒用。 我們先把我們的 main.rs 改成 lib.rs,rt 編成 library 之後,類似 FreeRTOS 的感覺,再搭配使用者寫的 main.rs 編成完整的執行檔; 使用者寫的 main.rs 可以呼叫 kernel 提供的服務函式。

...

在 2021 年要如何開發 Rust 裸機程式:reset handler

我們的目標先訂在 arm cortex m3 的處理器, m3 處理器參考 arm 官方的開發文件, 在 arm 處理器一上電的時候,會從記憶體位址 0x0 的地方讀取兩個值:

  1. 0x0 是初始的 stack pointer value。
  2. 0x4 是 reset exception handler。
...