Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RustでOS開発はじめの一歩

nasa
December 19, 2023

 RustでOS開発はじめの一歩

nasa

December 19, 2023
Tweet

More Decks by nasa

Other Decks in Technology

Transcript

  1. 動作環境 • platform: QEMU riscv64 • build target: riscv64gc-unknown-none-elf #

    .cargo/config.toml [build] target = "riscv64gc-unknown-none-elf" [target.riscv64gc-unknown-none-elf] runner = """ qemu-system-riscv64 \ -machine virt \ -bios default \ --no-reboot \ -nographic \ -serial mon:stdio \ -kernel """
  2. main関数を動かす リンカースクリプトで任意の アドレスにプログラムを配置する .entryシンボルを8020_0000に配置 OUTPUT_ARCH( "riscv" ) ENTRY( _entry )

    SECTIONS { . = 0x80200000; .text : { *(.entry) *(.text .text.*) } .rodata : { *(.rdata .rodata .rodata.*) } .data : { *(.data .data.*) } .bss : { *(.bss bss.*) } }
  3. main関数を動かす main.rsで.entryを定義 これで関数_entryが呼ばれる // src/main.rs #![no_std] #![no_main] #[no_mangle] #[link_section =

    ".entry"] pub fn _entry() { main(); } #[inline] fn main() { loop {} } #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }
  4. 関数呼び出し // src/main.rs static INIT_SP: [u8; 4096 * 1024] =

    [0; 4096 * 1024]; static STACK_SIZE: usize = 4096 * 1024; // 4MB pub unsafe fn _entry() { // NOTE: スタックポインタの初期値を設定する // NOTE: スタックは下位に伸びていくのでINIT_SP + STACK_SIZEを設定 しSTACK_SIZE分の領域を確保 asm!("la sp, INIT_SP", "ld a0, STACK_SIZE", "add sp, sp, a0",); main(); } SPを初期化 誰からも変更されないように配列を定義し末尾アドレスを利用
  5. メモリアロケーターの実装 global_allocatorディレクティブで登録出来る GlobalAllocトレイトを実装している必要がある #[global_allocator] static mut ALLOCATOR: BumpAllocator = BumpAllocator::new();

    pub struct BumpAllocator { arena: RefCell<[u8; ARENA_SIZE]>, next: Cell<usize>, } unsafe impl GlobalAlloc for BumpAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 {} unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} }
  6. 自己紹介 HN: nasa (Asan Kondo) nasaが欲しい • github: k-nasa •

    x(twitter): nasa_desu お仕事: MLOpsっぽいこと、DSの生産性改善
  7. (余談) 遭遇したバグたち • 一度出力した文字が出力できない 「Hel?o W?r?d.」が出力される ◦ 原因: SP初期化していないから •

    カーネル起動時に有効化していないタイマ割り込みが発生して死ぬ ◦ 原因1: エラーコードがズレてた。。本当は`address misaligned` ◦ 原因2: アライメントを考慮していなかった • プロセス切り替え時にSPが意図通り切り替わらない ◦ 原因: 調査中。涙