Rust

Writing an OS in Rust (Second Edition) #1


x64向けOSをRustで書くチュートリアルをなぞってやるだけ

https://os.phil-opp.com/freestanding-rust-binary/


nightlyをつかう

ディレクトリを作ってその中でrustup override add nightlyする

nightlyはfeatureフラグを使っていろいろな機能を有効にできる.

#![feature(asm)]ならインラインアセンブラが有効になる.


プロジェクトを作る

cargo new weed-os --bin --edition 2018

これで2018年版のコンパイラをつかうプロジェクトが作られた.

早速main.rsを編集する.

no_stdフラグをファイルの先頭に足すがビルドが通らない.まずprintln!マクロは使用できない.これはstdの範囲にある.なぜなら標準出力はOSにより用意されるからだ.

#![no_std]

fn main() {
}

これでもビルドが通らない.

☻  cargo build

Compiling weed-os v0.1.0
error: `#[panic_handler]` function required, but not found

error: language item required, but not found: `eh_personality`

error: aborting due to 2 previous errors

error: Could not compile `weed-os`.

panic_handlerlanguage itemeh_personalityが不足している.


language item

language itemはコンパイラが内部的に使う関数と型である.laguage itemを独自に実装するには型チェックも行われないし難易度が高く信頼性がひくい


eh_personalityの解決

eh_personalityはstack unwinding(callスタックを崩す役割)を行う関数の実装に必要.Rustはpanicが起こったときにstack unwindingを自動的に行う.stack unwidingは実装が大変.LinuxではlibunwindなどがあるがOSのライブラリは使用できない.したがって今回はstack unwindをoffにする.

Cargo.tomlに以下のようなものを追加する.

[profile.dev]

panic = "abort"

[profile.release]
panic = "abort"

これでbuild時とrelease時にpanic on abortさせる.

これでビルドしてみる.

☻  cargo build

Compiling weed-os v0.1.0
error: requires `start` lang_item

error: aborting due to previous error

error: Could not compile `weed-os`.

To learn more, run the command again with --verbose.


startの不足

rustはCのランタイムライブラリcrt0(C Run Time Zero)を用いて起動される.crt0はスタックなどの準備を行う.後にRustのruntimeを起動してmainへ実行が移る.しかしベアメタルにはcrtもRustのランタイムも存在しない.


entrypointの上書き

今回はエントリポイントを直接上書きすることにする,Mac OSの場合はstack link binaryが有効でないので,以下のようにライブラリをリンクする.

cargo rustc -- -Z pre-link-arg=-lSystem