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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
390
鉄は熱いうちに打て - Kaigi Effect LT大会
nasa_desu
2
590
リンカを変えてgo buildを 速く出来るか
nasa_desu
2
3.9k
ログから学ぶgo build
nasa_desu
4
1.5k
goのメモリアロケーターの話
nasa_desu
1
820
GoとRust - 並行処理編
nasa_desu
5
4.2k
Other Decks in Technology
See All in Technology
ご挨拶「10周年を迎える共創ラボのこれまでとこれから」
iotcomjpadmin
0
180
MySQL & MySQL HeatWave Report - June 2026
freshdaz
0
300
AWS Summit の片隅で、体育座りしながらコミュニティがにぎわう理由を考えた
k_adachi_01
2
340
Tech-Verse 2026_Keynote
lycorptech_jp
PRO
0
130
Baseline対応のDOMの型定義を作った
uhyo
3
660
LiDAR SLAMの実装とセンサ融合 ~Lie群からContinuous-Time LIOまで~
naokiakai
1
940
AWS Blocks を触ってみた/first-tach-aws-blocks
fossamagna
2
140
AIエージェントとPhysical AIが拓く製造業の変革(ハノーバーメッセリキャップ)
iotcomjpadmin
0
210
AIに「使われる」時代のSaaS戦略 〜既存WebAPIのMCPサーバー化における開発ノウハウ〜
ekispert_api
0
290
CVE-2026-20833_脆弱性対応とAES 化について
jukishiya
0
350
Text-to-SQLをAgentCoreで実現し、生成されるSQLの精度を定量的に評価する
yakumo
2
500
テスト設計の本質を改めて考えてみる~生成AIを活用する時代だからこそ、作ったテストの説明性を高めよう~
yamasaki696
1
290
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
220
Utilizing Notion as your number one productivity tool
mfonobong
4
340
Embracing the Ebb and Flow
colly
88
5.1k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
760
Accessibility Awareness
sabderemane
1
150
Game over? The fight for quality and originality in the time of robots
wayneb77
1
220
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Skip the Path - Find Your Career Trail
mkilby
1
160
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
960
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
330
Chasing Engaging Ingredients in Design
codingconduct
0
230
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が意図通り切り替わらない ◦ 原因: 調査中。涙
ご清聴ありがとうございました!