Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RustでOS開発はじめの一歩
Search
nasa
December 19, 2023
Technology
7.7k
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
420
鉄は熱いうちに打て - Kaigi Effect LT大会
nasa_desu
2
620
リンカを変えてgo buildを 速く出来るか
nasa_desu
2
4k
ログから学ぶgo build
nasa_desu
4
1.6k
goのメモリアロケーターの話
nasa_desu
1
860
GoとRust - 並行処理編
nasa_desu
5
4.2k
Other Decks in Technology
See All in Technology
AWSDirectConnectの構築の進め方を整理してみた
masa_my
1
170
日本AIベンチャーレポート2026
kentarofujii
0
210
ドメインエキスパートは いかにして AI を使って プロダクト開発をするか
tatsuyashiraishi
1
140
野蛮なアジャイル [サイボウズ発!]組織の常識を覆した反骨のスクラム実践記 / Barbaric Agile - Enterprise Agile Study Group
ama_ch
0
140
CTO Night|NotionのAIエージェントとFDE
kzkhykw1991
0
310
DevelopersIO2026 -バックアップは“消されないこと”が9割-
yoshida0129
0
380
LambdaWebFunctionsを試してみた / exploring-lambda-web-functions
koukihosaka
1
400
AI秘書と毎日働くのはもう当たり前。開発以外の業務に足りない機能をどう埋める?
minorun365
PRO
0
380
JAWSUG TOHOKU 青森支部 「LoGoチャット」のAWS移行で 乗り越えたこと
taketakekaho
0
400
AWS DevOps Agentはどこまで任せられるか 〜機能の現在地と、機能拡張の実践〜
nyankotaro
0
200
背中から、背中へ ー 社外コミュニティで学んだ「雑に背中を押す」という恩送り ー / easygoing encouragement and pay forward to community
naitosatoshi
0
170
Gemini Intelligence 入門 ― AppFunctions と Gemini Nano
takuroabe
0
370
Featured
See All Featured
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
WCS-LA-2024
lcolladotor
0
900
Between Models and Reality
mayunak
4
500
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
610
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
From π to Pie charts
rasagy
1
410
Optimizing for Happiness
mojombo
378
71k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
740
How to make the Groovebox
asonas
2
2.5k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
450
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が意図通り切り替わらない ◦ 原因: 調査中。涙
ご清聴ありがとうございました!