使用RUST編寫OS(1)-獨立可運行程序

學習RUST同時學習OS


序言

本系列全部內容主要參考Writing an OS in Rust ,並加上個人理解以及閱讀過後認為可以補充的地方,以會參考舊文章Writing an OS in Rust (First Edition),以及Rust聖經,主要目的是學習OS,因此會跳過一些太重點於RUST語言的部分,歡迎參考原文。

創建項目

cargo new blog_os --bin 

--bin 說明我們要創立一個可執行文件而非lib

禁用標準庫

一般而言我們都會調用rust標準庫完成類似println!的效果,而因為我們要自行編寫操作系統所以可以先忽略標準庫

#![no_std]

實現panic處理函數

panic_handler定義了一個函數,會在panic時調用,因為現在現在時no_std的環境,所以需要自行編寫

use core::panic::PanicInfo;
 
#[panic_handler]
fn panic(_info : &PanicInfo) -> ! {
    loop{}
}
  • 類型PanicInfo的參數包含panic發生的文件名,代碼函數和可選錯誤訊息
  • 這個函數不返回(永遠不會正常結束)所以計為發散函數(never type) 寫為 !,因此裡面包了一個loop

eh_personality 語言項

  • eh_personality 語言標記函數,將被實現用於榐展開,當發生panic時,Rust將使用榐展開,確保內存都被釋放

禁用榐展開

  • Cargo.toml
[profile.dev]
panic = "abort"
 
[profile.release]
panic = "abort"

Start 語言項

  • 一般的具備標準庫的Rust會從一個名為crt0(C runtime zero)開始運行,他會建立一個適合運行C的環境,包含榐的創建和可傳入參數
  • 因為我們的程序禁用了標準庫,因此需要重寫入口點
  • 不使用預定入口點可以使用 #![no_main]
#![no_std]
#![no_main]
 
#[no_mangle]
pub extern "C" fn _start() -> ! {
    loop {}
}
 
  • 使用 #[no_mangle] 避免函數名被重整而導致linked找不到入口點