Closed5

Rust で走る「ゼロからの OS 自作入門」メモ

ちゅるりちゅるり

OS を作りたくなってきたので「ゼロからの OS 自作入門」を始めることにした。本では C/C++ で実装を進めているが、そのままやるのも性に合わないので Rust でやることにした。

ちゅるりちゅるり

0 章

  • 商用レベルの OS を作るのであれば Linux を改造してディストリビューションを作るのが手っ取り早い
  • 本書では UEFI で起動し、Intel64 モードで動き、ページング方式のメモリ管理を行い、USB3.0 ドライバを搭載し、fs を持つような OS を作る
    • POSIX には準拠しない
  • 開発時、本書では Clang + LLVM で進めるが、GCC を使っても良い
    • 実行は安い実機でも、QEMU でも、WSL でもいい
  • 質問があれば osdev.jp へ
ちゅるりちゅるり

1 章

  • バイナリを一から打ち込んで Hello, World する UEFI アプリケーションを作る
  • 本書では okteta を Ubuntu で使っているが、自分は M2 Mac なので Hex Fiend でバイナリ打ちをする
    • M2 Mac(Sonoma, 14.7) 上の qemu-system-x86_64 v9.1.0 でこれを動かそうとするとエラーが出た
ちゅるりちゅるり

2 章

  • EDK II の環境構築から始まるが、Rust でやるのであまり関係ないかも
  • https://zenn.dev/link/comments/7f556e70155996 を参考にプロジェクト作成
    • uefi-rs を使用
      • 2024/9/18 現在、uefi-rs は v0.32 で構造体ベースの API 提供を非推奨にしたことから同じコードを書くと大量の警告が出る。自分は v0.31 に落とすことで対応したが、誰か 0.32 でぜひ進めてほしい...
      • サンプルのコードに加えて panic-handler も書く必要がありそう。自分は下のようなコードを書いて対応した
        • しかし VSCode の rust-analyzer v0.3.2112 拡張機能 + rustc 1.83.0-nightly (c52c23b6f 2024-09-16) の構成でこのハンドラに対し、エディタ上で found duplicate lang item 'panic_impl' the lang item is first defined in crate 'std' (which test depends on) first definition in 'std' loaded from /home/XXX/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-e0ee872a6f64065a.rlib エラーが出る(no-std を指定しているのにも関わらず...)。バグだろうか、コンパイルは通るので放置しているが、詳細な調査が必要そうだ。
    • Rust は nightly version でないとダメそう(-Z フラグを使うので)
    • プロジェクトに dev.sh を作成し、中に次のコードを書き、cargo watch -- ./dev.sh を実行することで自動ビルドがされるようにした
    • Ubuntu(OS を走らせる側)にプロジェクトを作成し、M2 Mac から Remote SSH 経由でマシンに接続して作業している
    • ビルド後の実行の操作だけ Ubuntu 上から行う(ここも自動化したい...)
  • 2024/9/23 追記
    • vec などの Global Allocator 実装が必要なものを使おうとするとないぞ!と怒られてしまっていたが、extern crate uefi_services; を記述することによって解決した。uefi_services にその実装があるようだ。

dev.sh

clear
cargo build -Zbuild-std -Zbuild-std-features=compiler-builtins-mem --target x86_64-unknown-uefi

main.rs

// efi_main 関数に続いて
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
    loop{}
}
このスクラップは5ヶ月前にクローズされました