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
第13回Kernel/VM勉強会発表資料
Search
orumin
July 22, 2017
Programming
1.7k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
第13回Kernel/VM勉強会発表資料
2017/07/22 に行なわれた Kernel/VM 勉強会の発表資料です。
orumin
July 22, 2017
More Decks by orumin
See All by orumin
あのころの iPod を どうにか再生させたい
orumin
2
3k
ヴィンテージマシンと付き合う - kernel/vm online 5
orumin
0
1.3k
むかしの RISC、むかしの Unix
orumin
7
3.9k
Fundamental of architecture to implementing OS on AArch64
orumin
3
5.8k
Kernel/VM Kansai #9
orumin
0
1k
Kernel/VM #14 発表資料
orumin
1
660
Unikernels report
orumin
2
550
第12回カーネル/VM探検隊
orumin
0
410
第11回 Kernel/VM探検隊 発表資料
orumin
1
620
Other Decks in Programming
See All in Programming
AmebaブログはKMPから卒業します
kmars0605
0
310
エージェントを使い続けるためのメタワーク / Meta-work for keeping using the agent
rkaga
6
2.1k
GraphQL の onError と Nullability のこれから
quramy
0
200
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
400
まずはコードより業務と向き合う:テーブル解体のためにPdMを呼んだ話
sakawe_ee
0
110
Goコンパイラを作ってGoをもっと理解する / Build a Go compiler to better understand Go
ikura_hamu
0
110
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
2
250
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
6
1.3k
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
2k
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
6.1k
[2026-10-14](C)Re:ゼロから始める異世界生活〜始まりの終わりと終わりの始まり〜
tosite
0
280
ChromeでローカルLLM
ryu1013
0
190
Featured
See All Featured
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
450
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
740
A Tale of Four Properties
chriscoyier
163
24k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
320
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
470
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Transcript
C 以外でのベアメタルプログラミング XXX Jul 22th, 2017 1 / 27
自己(事故)紹介 orumin Twitter ID: @kotatsu_mi 最近自宅のサーバの電源と PT3 が雷に撃たれました。 雷サージ対策は忘れずにやろうね! アンテナ線にも電話線にもサージプロテクタは存在する
2 / 27
緒言 ベアメタルプログラミング いわゆる freestanding 環境 libc 他が存在しない みなさんよくやってますよね? よくつかわれるのは C
や C++ どうして C をつかうのか 3 / 27
ベアメタルプログラミングと C メリット 生ポインタで特定のアドレスへの I/O 操作といったことが簡単にでき る,また,この分野で枯れており,ノウハウも豊富 デメリット 型システムが貧弱,最近のクールな言語機能が使えない 4
/ 27
C 以外でベアメタルプログラミング 複数の代替手段 D 言語,C♯,Rust … (いますぐ採用するとかなくても)今後のために C 以外でやるノウハウも得てお かないとそのうち死ぬので
Rust 既にかなりの規模のそれなりにちゃんと動く OS が作られている(Redox)実績 C♯ も 2011 年ぐらいから Cosmos という OS があったりする C♯ でのベアメタルプログラミングも調べて話そうとすると話者の力量不足でどっち つかずの内容になるので割愛しました そのうちやるかも? 5 / 27
Rust OCaml と C++ の血を感じる言語 ML 系の強力な型システム 所有権など,独特だが C++ を既に知ってる人間がわりと違和感なく使える強力な
機能 nightly コンパイラで freestanding をサポート stable 入りはまだですかー! 様々な機能や設計が C++ のカウンターっぽい c.f.) 過去の KernelVM での @omasanori さんの発表 https://speakerdeck.com/omasanori/rustru-men-yi-qian-fa-biao-ban 6 / 27
Rust(nightly)のインストールとテスト $ curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain=nightly
-y $ . ~/.cargo/env $ cargo new --bin hello-rust 7 / 27
Rust のテスト 右のようなディレクトリツリーが出来あがる 作成されるファイルは下例 実行は cargo run cargo は gem
みたいなもの。ビルドツールか つパッケージマネージャ。 Rust のパッケージは https://crates.io に ある hello-rust Cargo.toml src/ main.rs [package] name = ”hello-rust” version = ”0.1.0” authors = [”orumin <
[email protected]
>”] [dependencies] fn main() { println!(”Hello, world!”); } 8 / 27
Rust でベアメタルをするにはどうすれば良いか UEFI apps を例に step-by-step で紹介します! Linux の人は手元で試してみてください TL;DR
https://github.com/orumin/rust-uefi-sample.git を clone して make run rust-uefi-sample/ Makefile Cargo.toml x86_64-unknown-efi.json src/ lib.rs 9 / 27
Cargo.toml [package] name = ”uefi-sample” version = ”0.1.0” authors =
[”orumin <
[email protected]
>”] [dependencies] uefi = { git = ”https://github.com/orumin/rust-uefi” } rlibc = ”1.0” [lib] crate-type = [”staticlib”] [profile.dev] panic = ”abort” [profile.release] panic = ”abort” 10 / 27
Cargo.toml パッケージ名や依存パッケージを記述 [lib] セクションをつくり,src/lib.rs を記述するとライブラリとして作られる 今回はオブジェクトファイルだけ作成して手動でリンクしたかった 依存パッケージは名前だけ書いておくと crates.io からもってくる path
= に続けてパスを記述すると他のディレクトリのプロジェクトを依存に指定 git = に続けて Git repo を記述すると自動で clone とビルドしてくれます 11 / 27
target json Cargo は json で custom ターゲットを作れる { ”arch”:
”x86_64”, ”os”: ”efi”, ”llvm-target”: ”x86_64-efi-none-gnu”, ”target-endian”: ”little”, ”target-pointer-width”: ”64”, ”function-sections”: false, ”no-compiler-rt”: true, ”data-layout”: ”e-m:e-i64:64-f80:128-n8:16:32:64-S128”, ”linker”: ”x86_64-efi-pe”, ”linker-flavor”: ”ld”, ”pre-link-args”: [ ”subsystem”, ”10” ] } 12 / 27
target json 今回は UEFI 向けに PE バイナリを作りたいので target の json
を記述 arm-none-eabi などでも記述 ただの x86_64 の ELF なら要らないかも? 13 / 27
ソースコード #![no_std] #![feature(asm)] #![feature(intrinsics)] #![feature(lang_items)] extern crate uefi; extern crate
rlibc; use core::mem; #[allow(unreachable_code)] #[no_mangle] pub extern ”win64” fn efi_main(hdl: uefi::Handle, sys: uefi::SystemTable) -> uefi::Status { uefi::initialize_lib(&hdl, &sys); let bs = uefi::get_system_table().boot_services(); let rs = uefi::get_system_table().runtime_services(); 14 / 27
ソースコード uefi::get_system_table().console().write(”Hello, World!\n\rvendor: ”); uefi::get_system_table().console().write_raw(uefi::get_system_table().vendor()); uefi::get_system_table().console().write(”\n\r”); loop { } uefi::Status::Success
} #[no_mangle] pub fn abort() -> ! { loop {} } #[no_mangle] pub fn breakpoint() -> ! { loop {} } #[no_mangle] pub extern ”C” fn _Unwind_Resume() -> ! { loop {} } #[lang = ”eh_personality”] #[no_mangle] pub extern fn rust_eh_personality() {} 15 / 27
ソースコード #[lang = ”panic_fmt”] #[no_mangle] pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
_file: &’static str, _line: u32) -> ! { loop {} } 16 / 27
ソースコード解説 #![no_std] 標準ライブラリをリンクしなくなる 標準ライブラリのうち,アーキテクチャ非依存な便利機能は core ライブラリを use すれば使えるものもある 17 /
27
no_std でフォーマット出力 e.g.) use core::fmt::Write; impl Write for Writer {
fn write_str(&mut self, s: &str) -> core::fmt::Result { 引数でうけた文字列 s について出力を自分で実装; Ok(()) // 失敗なら Err(foo) でエラーの値返す } } これだけで,write!() マクロの実装が得られる let mut w = Writer {}; write!(w, ”foo {}”, bar).unwrap(); 18 / 27
#![feature(lang_items)] eh_personality とか panic_fmt とか eh_personality GCC の personality 関数の代わりのシンボル
LLVM で言語の例外ハンドリングに使う unwind panic_fmt Rust で panic!() を使うときのシンボル デバッグ文字列出力とか作っておくと良い 19 / 27
extern extern “C” などとすると C 互換の ABI になる #[no_mangle] 付けると名前マングルをしない
既存のライブラリを置き換える何かを作るのにもべんりかも UEFI は x86_64 だと Microsoft’s 64-bit call convention を使う extern “win64” で対応 20 / 27
ではビルドをしてみましょう $ cargo install xargo $ xargo build --target x86_64-unknown-efi
Xargo を導入 cargo build の際に core ライブラリなどをターゲットのアーキでビルドしてく れる 素の cargo だとヘンなアーキテクチャ使うのに core をそこに合わせてビルドしな いといけない 21 / 27
binutils とリンク 今回は UEFI ターゲットの PE バイナリを作りたいので普通の binutils だとダメ $
curl -O https://orum.in/distfiles/x86_64-efi-pe-binutils.tar.xz $ mkdir -p $PWD/toolchain $ tar xf x86_64-efi-pe-binutils.tar.xz -C $PWD/toolchain $ export PATH=$PATH:$PWD/toolchain/usr/bin/ $ pushd $ cd target/x86_64-unknown-efi/debug $ ar x *.a $ popd $ x86_64-efi-pe-ld --gc-sections --oformat pei-x86-64 \ --subsystem 10 -pie -e efi_main \ -o bootx64.efi \ target/x86_64-unknown-efi/debug/*.o 22 / 27
実行 $ dd if=/dev/zero of=fat.img bs=1k count=1440 $ mformat -i
fat.img -f 1440 :: $ mmd -i fat.img ::/EFI $ mmd -i fat.img ::/EFI/BOOT $ mcopy -i fat.img bootx64.efi ::/EFI/BOOT $ curl -O https://orum.in/distfiles/ovmf.fd $ qemu-system-x86_64 -enable-kvm -net none -m 1024 \ -bios ovmf.fd -usb -usbdevice disk::fat.img 23 / 27
これだと見えづらいので…… https: //github.com/orumin/rust-uefi-sample/blob/master/src/lib.rs Graphic Output Protocol の取得,設定 BLT 24 /
27
conclusion Rust 便利 C 以外でもベアメタルしたい! 25 / 27
こぼれ話1 質問:@nullpo_head さん「自作 OS 勉強会だと Box が使えなくて辛いとかあっ たけどどうやってるの? 」 回答:
「まだそこらへんがっつりやるステージに入れてないが,そもそも Box と かは自前実装する方法があるので問題がないと思う。 」 https://rust-lang-ja.github.io/the-rust-programming-language-ja/ 1.6/book/custom-allocators.html 実は上記の通り公式ドキュメントがある ベアメタル以外でも使えるのでゲームエンジンとかやる人にも良いのではないか 26 / 27
こぼれ話2 Rust のコンパイラ機能 #[start] 特定のシンボルの前(たとえば pub fn app_main() とかの前の行)に付けておく と,エントリポイントにしてくれる
#[link_section = “.test_section”] この行のところが ELF の.test_section になる。便利。 27 / 27