Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RustでOS開発はじめの一歩
Search
nasa
December 19, 2023
Technology
7.6k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RustでOS開発はじめの一歩
https://uniquevision.connpass.com/event/303687/
nasa
December 19, 2023
More Decks by nasa
See All by nasa
難解な自己紹介プログラムを書く
nasa_desu
1
410
鉄は熱いうちに打て - Kaigi Effect LT大会
nasa_desu
2
610
リンカを変えてgo buildを 速く出来るか
nasa_desu
2
4k
ログから学ぶgo build
nasa_desu
4
1.6k
goのメモリアロケーターの話
nasa_desu
1
840
GoとRust - 並行処理編
nasa_desu
5
4.2k
Other Decks in Technology
See All in Technology
ブラウザアプリの継続的パフォーマンスモニタリング (序) / Continuous Browser Application Performance Monitoring; Act 1
moznion
0
110
Autonomous AI Databaseサービス・アップデート(FY27)/ adb-service-update-jp-fy27
oracle4engineer
PRO
0
130
Jetpack Compose で挑む新聞紙面UI ─ 複合ジェスチャー・ポリゴン記事領域・適応的ページ構成という3つの壁/droidkaigi2026
nikkei_engineer_recruiting
0
240
多摩川(.dev)ランニング入門 / Tamagawa.dev#3
fujiwara3
3
400
Oracle Cloud Infrastructure IaaS 新機能アップデート 2026/6 - 2026/8
oracle4engineer
PRO
0
120
AIで実装は速くなった。なのにプロダクトは速くならない。職能の壁を越えて価値のフローを設計する
nwiizo
7
7.4k
Amazon Quick on DesktopがIAM Identity Centerで動かない理由
yukiogawa
0
110
Genie Code ワークショップ 応用編 / Genie-Code-Workshop-advanced
databricksjapan
PRO
0
360
Guerilla InnerSource in enterprises, during the AI hype
onenashev
PRO
0
150
20260903 Tokyo Jazug Night #62 | Azure エンジニアよ、 その環境は本当にセキュアか?
olivia_0707
1
630
コスト最適化の「めんどくさい」を AWS FinOps Agent でチョット楽にする
classmethod_kaz
0
270
AIエージェントの開発・提供におけるセキュリティリスクの論点と対策
flatt_security
2
610
Featured
See All Featured
We Are The Robots
honzajavorek
0
350
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
510
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
450
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
470
Chasing Engaging Ingredients in Design
codingconduct
0
300
Between Models and Reality
mayunak
4
450
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.7k
Music & Morning Musume
bryan
47
7.4k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
590
Transcript
RustでOS開発はじめの一歩 UV Study: Rust LT会 Dec. 19 2023 - nasa
発表のモチベ • 最近RustでOSを書いている • これまでCLIツールやライブラリをRustで実装してきた • OSだと普段書いているコードが普通には動作しない • どんな違いがあるのか話したい
動作環境 • 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 """
ベアメタル環境 • OSによりプログラムがホスティングされない • 自分の書いたプログラムを動かし始めるまでの環境がない • time, io, fsなどOSの上に構成されている標準機能が使えない •
メモリアロケーターも無いのでVec, String等が使えない
ベアメタル環境
main関数を動かす
main関数を動かす QEMU riscvのdefault biosは0x80200000を実行する
main関数を動かす プログラムを0x8020_0000に配置し呼出す
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.*) } }
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 {} }
関数呼び出しをサポートしたい
関数呼び出し みんな大好き関数呼び出し。 というかプログラムを書く上でほぼ必須 • 関数呼び出しが出来ない。。 • inlineオプションを付けると呼び出せる fn a() {
b() } fn b() { c() } pub fn _entry() { main(); } #[inline] fn main() { loop {} }
関数呼び出し • 関数呼び出しが出来ない。。 • inlineオプションを付けると呼び出せる • (正確には関数を呼ぶとローカル変数の値がおかしくなる) なぜこれらが起きるのか
関数呼び出し • 関数呼び出し時にスタック領域が確保される • しかしSPの初期値は0 • SPを初期化する必要があった
関数呼び出し // 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を初期化 誰からも変更されないように配列を定義し末尾アドレスを利用
動的メモリ確保したい
動的メモリ確保 StringやVec,Boxが普通に使いたくなる これらはallocクレートに定義されている (stdが存在する場合はstdの一部)
動的メモリ確保 allocを使うにはメモリアロケーターを実装する必要がある (heaplessクレートを利用するとアロケーターの実装無しでString, Vec等が使 える)
メモリアロケーターの実装 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) {} }
メモリアロケーターの実装 bump allocatorを採用 heapの始点から終点まで順次割り当 てていくだけ フラグメンテーションを一切考慮してい ない 実装が超簡単なので採用
まとめ
まとめ • 普段Rustを書く時に色んなものに乗っかっている事が分かった • OSの機能以外にブート、メモリアロケーター、スタックポインタを気にする 必要があった 「俺の戦いはこれからだ!!」
自己紹介 HN: nasa (Asan Kondo) nasaが欲しい • github: k-nasa •
x(twitter): nasa_desu お仕事: MLOpsっぽいこと、DSの生産性改善
(余談) 遭遇したバグたち • 一度出力した文字が出力できない 「Hel?o W?r?d.」が出力される ◦ 原因: SP初期化していないから •
カーネル起動時に有効化していないタイマ割り込みが発生して死ぬ ◦ 原因1: エラーコードがズレてた。。本当は`address misaligned` ◦ 原因2: アライメントを考慮していなかった • プロセス切り替え時にSPが意図通り切り替わらない ◦ 原因: 調査中。涙
ご清聴ありがとうございました!