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
Hello World in coreboot
Search
d0iasm
July 20, 2019
Programming
3
880
Hello World in coreboot
「第15回 カーネル/VM探検隊&懇親会@東京」での発表資料です。
https://kernelvm15.peatix.com/
d0iasm
July 20, 2019
Tweet
Share
More Decks by d0iasm
See All by d0iasm
WebAssembly outside of the browser
d0iasm
12
3.8k
FFI: RustとWebAssemblyとJavaScriptと
d0iasm
1
1.3k
Other Decks in Programming
See All in Programming
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
250
AIネイティブなプロダクトをGolangで挑む取り組み
nmatsumoto4
0
120
XSLTで作るBrainfuck処理系
makki_d
0
210
ドメインモデリングにおける抽象の役割、tagless-finalによるDSL構築、そして型安全な最適化
knih
11
1.9k
Perplexity Slack Botを作ってAI活用を進めた話 / AI Engineering Summit プレイベント
n3xem
0
670
都市をデータで見るってこういうこと PLATEAU属性情報入門
nokonoko1203
1
540
FormFlow - Build Stunning Multistep Forms
yceruto
1
190
セキュリティマネジャー廃止とクラウドネイティブ型サンドボックス活用
kazumura
1
190
Bytecode Manipulation 으로 생산성 높이기
bigstark
2
360
型付きアクターモデルがもたらす分散シミュレーションの未来
piyo7
0
800
Java on Azure で LangGraph!
kohei3110
0
160
KotlinConf 2025 現地で感じたServer-Side Kotlin
n_takehata
1
220
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
24
1.7k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
Build The Right Thing And Hit Your Dates
maggiecrowley
36
2.8k
Optimizing for Happiness
mojombo
379
70k
Balancing Empowerment & Direction
lara
1
340
Thoughts on Productivity
jonyablonski
69
4.7k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
137
34k
Making Projects Easy
brettharned
116
6.2k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Transcript
Hello World in coreboot 土井麻未 @d0iasm
@d0iasm • 大学院生(人工生命の研究) • コンピュータがどうやって動くのか知り たい • 勉強すればするほどわからないと いうお気持ち
ざっくり ”Hello World” まで BIOS OS User Program Reset Hello,
World! ※ 今回の話ではベアメタルプログラミングを考慮しません
もう少し詳しく ”Hello World” まで Bootloader ハードウェア 初期化 Compiler ブートローダ 呼び出し
リソースの分配 • メモリ • プロセス • デバイス ディスクから kernelをロード ユーザー空間 システムコー ル BIOS/UEFI OS User Program Reset Hello, World!
もっと詳しく知りたい! 問題点 • OS (Linux kernel) に関する情報は見つかるが、BIOSの情報が少なす ぎる ➡ 実際のコードを読んで開発するしかない ➡ GSoCの一貫でOSSプロジェクトであるcorebootに参加
What is GSoC • Google Summer of Code • 学生にオープンソースプロジェクトに参加してもらお
うというイベント • 2019年は5月28日から8月20日までが開発期間 (3ヶ月) • お金もらえます https://summerofcode.withgoogle.com/
https://coreboot.org/ • ベンダー依存のBIOS/UEFIを置き換えることを目 的としたファームウェア • オープンソースプロジェクト • リセットされたらまず実行されるコード • 生成物(coreboot.rom)をROM/Flashに書き込
んで使う • Chrome book等で使用されている What is coreboot
GSoC Project in coreboot https://coreboot.org/ • “Adding QEMU/AArch64 Support to
Coreboot” ◦ corebootにQEMU/AArch64のサポートを追加 ◦ ボードの移植作業 • ゴールは以下のコマンドが動くこと $ qemu-system-aarch64 -bios coreboot.rom ...
coreboot payload • corebootはpayloadに処理を渡すだけ • corebootから ◦ 直接Linuxを起動できる ◦ GRUB2などのブートローダを起動できる
◦ 自分の書いたプログラムを起動できる ざっくりcorebootの仕組み Reset OS User Program
ざっくりcorebootの仕組み • 以下の3つのステージに分かれる ◦ Bootblock ◦ Romstage ◦ Ramstage •
最初のステージ以外は圧縮されている ◦ ROM/FlashのサイズはDRAMと比べ、小 さいため coreboot Reset
ざっくりcorebootの仕組み • Bootblock ◦ CPU/SoC/boardの初期化 ◦ Romstageの解凍&呼び出し • Romstage ◦
DRAM初期化 ◦ Ramstageの解凍&呼び出し • Ramstage ◦ 周辺機器初期化 ◦ Payloadの解凍&呼び出し Bootblock Bootblock Reset Ramstage Romstage coreboot.rom
プロジェクトの方針 “Adding QEMU/AArch64 Support to Coreboot” • 既にQEMU/ARMの実装があるので、これをベースにする ◦ ボード固有の部分を実装するだけ
▪ virtマシンを選択 簡単そう……?
プロジェクトの方針 “Adding QEMU/AArch64 Support to Coreboot” • 既にQEMU/ARMの実装があるので、これをベースにする ◦ ボード固有の部分を実装するだけ
▪ virtマシンを選択 簡単そう……? ➡ そんなに甘くない
立ちはだかる壁1 クロス環境でデバッグどうするの問題 • シリアルコンソールの初期化が済んでいないと、本当に何も出力されない • multi-gdb を使ってクロス環境デバッグを試みた……がうまくいかず
立ちはだかる壁1 クロス環境でデバッグどうするの問題 解決法:無限ループを仕込む 1. アセンブラで無限ループの関数を作る 2. バグがありそうなところに無限ループへのジャンプ命令を追加する bl loop 3.
QEMUのmonitor モード (Ctrl-a c) でプログラムカウンタとリターンアドレ スが無限ループの位置を指しているか (qemu) info registers PC=00000000xxxxxxxx // プログラムカウンタ X30=00000000xxxxxxxx // リターンアドレス
立ちはだかる壁2 QEMUのオプションわからん問題 • 開発当初は、以下のコマンドで十分だと思っていたが、例外大量発生 $ qemu-system-aarch64 -bios coreboot.rom -machine virt
-cpu cortex-a53 現在のコマンド $ qemu-system-aarch64 -bios coreboot.rom -M virt,secure=on,virtualization=on -cpu cortex-a53 -nographic -m 1024M
立ちはだかる壁2 QEMUのオプションわからん問題 • -machine secure=on: EL3を有効化 • -machine virtualization=on: EL2を有効化
ARMv8 Exception Levels “Fundamentals of ARMv8-A”より引用
立ちはだかる壁2 QEMUのオプションわからん問題 なんでオプションが徐々に増えていった? ➡ QEMUのvirtマシンのデフォルトはEL3/EL2が無効だから QEMUのオプションのデフォルト値を確かめるすべは 実装コードのコメント……(ドキュメントどこ)
立ちはだかる壁3 最初のステージでメモリ使えない問題 問題点:起動直後からDRAMを初期化するまでは、メモリが使えない • 通常、BIOSはアセンブリ言語で書かれていることが多い(らしい) • corebootでは、約2%はアセンブリ、残りはほぼC言語(行で計測) $ find ./src/
-name "*.c" | xargs wc -l // 500571 total $ find ./src/ -name "*.S" | xargs wc -l // 10859 total • gccを使用してコンパイル
立ちはだかる壁3 最初のステージでメモリ使えない問題 • Bootblock ◦ CPU/SoC/boardの初期化 ◦ Romstage の解凍&呼び出し •
Romstage ◦ DRAM初期化 ◦ Ramstage の解凍&呼び出し • Ramstage ◦ 周辺機器初期化 ◦ Payload の解凍&呼び出し Bootblock Bootblock Ramstage Romstage coreboot.rom C asm
立ちはだかる壁3 最初のステージでメモリ使えない問題 問題点 Bootblockステージの一部はC言語で書かれている にも関わらず、DRAMは使えない • スタック使えない ◦ ローカル変数使えない •
グローバル変数使えない 使えるのはレジスタだけ coreboot.rom Bootblock Bootblock Ramstage Romstage C asm
立ちはだかる壁3 最初のステージでメモリ使えない問題 corebootで用いられている解決法 解決法1:C言語からレジスタしか使わないアセンブリを生成する 解決法2:キャッシュをDRAMとして使用する(Cache-As-Ram)
立ちはだかる壁3 最初のステージでメモリ使えない問題 解決法1:C言語からレジスタしか使わないアセンブリを生成する ➡ ROMCCという特殊なコンパイラを使用する • ローカル変数を全てCPUレジスタにマップ • call命令とスタックはサポートしない • corebootで2003年から2005年頃まで使用されていた
ROMCC: https://github.com/coreboot/coreboot/blob/master/util/romcc/romcc.c
立ちはだかる壁3 最初のステージでメモリ使えない問題 解決法1:C言語からレジスタしか使わないアセンブリを生成する ROMCCの問題点 • コードは1つのファイルに書かれており、25,000行 • 開発者のEric Biedermanに依存 •
x86だけに対応 ➡ PowerPCやMIPSなどの他アーキテクチャで使いたいが、難しい
立ちはだかる壁3 最初のステージでメモリ使えない問題 corebootで用いられている解決法 解決法1:C言語からレジスタしか使わないアセンブリを生成する ➡ 厳しい 解決法2:キャッシュをDRAMとして使用する(Cache-As-Ram) ➡ 現在の主流
立ちはだかる壁3 最初のステージでメモリ使えない問題 解決法2:キャッシュをDRAMとして使用する(Cache-As-Ram) • CAR / Non-Eviction modeとも呼ばれる • x86では、CPUキャッシュを使用
• ARMでは、SRAMがキャッシュとしてSoC上にあるので、SRAMを使用
立ちはだかる壁3 最初のステージでメモリ使えない問題 x86では、CPUキャッシュをDRAMとして使用 • CPUキャッシュをwrite-backモードで有効化する // CR0.CD (30bit目, Cache disable)とCR0.NW
(29bit目, Not-write through) を0に設定する andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax movl %eax, %cr0 • CPUをNon-Evictionモードにする(=キャッシュの追い出しをしない) movl $NoEvictMod_MSR, %ecx // $NoEvictMod_MSR=0x2e0 rdmsr // Write the content of MSR[ECX] to EDX:EAX. https://github.com/coreboot/coreboot/blob/master/src/cpu/intel/car/non-evict/cache_as_ram.S
立ちはだかる壁3 最初のステージでメモリ使えない問題 x86では、CPUキャッシュをDRAMとして使用 • 全てのメモリアクセスがキャッシュだけで完結する • 実質、キャッシュ=メモリ キャッシュ DRAM CPU
立ちはだかる壁3 最初のステージでメモリ使えない問題 ARMでは、SRAMがキャッシュとしてSoC上にあるので、SRAMを使用 • ROM内のコードをSRAM内にリロケーションする SRAM DRAM SoC CPU ROM
0x00000000 0x48000000 メモリアドレスはQEMU VExpressより https://github.com/qemu/qemu/blob/master/hw/arm/vexpress.c ROM内に あったcode
立ちはだかる壁3 最初のステージでメモリ使えない問題 よくわかってない点:SRAMってキャッシュとして使用されているはずなのに、な んでアドレス持ってるの?(誰か教えて) SRAM DRAM CPU ROM 0x00000000 0x48000000
メモリアドレスはQEMU VExpressより https://github.com/qemu/qemu/blob/master/hw/arm/vexpress.c ROM内に あったcode SoC
立ちはだかる壁3 最初のステージでメモリ使えない問題 (再掲)問題点 Bootblockステージの一部はC言語で書かれている にも関わらず、DRAMは使えない • スタック使えない ◦ ローカル変数使えない •
グローバル変数使えない ➡ SRAMにコードをリロケーションすれば 良さそう coreboot.rom Bootblock Bootblock Ramstage Romstage C asm
立ちはだかる壁3 最初のステージでメモリ使えない問題 更なる問題点 • ターゲットマシン(QEMU, virt)はSRAM搭載せず coreboot.rom Bootblock Bootblock Ramstage
Romstage C asm
立ちはだかる壁3 最初のステージでメモリ使えない問題 わからなくなったので、開発者Slackで聞いてみた ➡ QEMUはアプリケーションなので既にDRAMは動いている ➡ それを使えば良いじゃない(いいのか?) 現在の実装 実行開始時に、ROM内にあるコードをDRAMにリロケーション
“Hello World” はできたの?
“Hello World” はできたの? まだです。 (プロジェクト開始から約2ヶ月経過)
進捗 • メインのコードはほぼ完成 • あとは、任意のpayload(Linux/LinuxBoot/任意のFIT)が動くことを確 認するだけ ➡ 現在、LinuxBootをpayloadとして実行すると、最後の処理の方で例 外が発生しているが、自分のコードからなのか、payloadから発生している のかよくわからない
進捗 ➡ 現在、LinuxBootをpayloadとして実行すると、最後の処理の方で例 外が発生しているが、自分のコードからなのか、payloadから発生している のかよくわからない ➡ corebootの1番最後では、例外レベルをEL3からEL2に移動する際に、 Eret(Exception Return)を使用 ➡ 例外発生しているのは正しい挙動なのでは……?(わからん) Eret:ELR_EL3レジスタにセットしたアドレスにリターンする
まとめ • BIOSのコードを読んだり書いたりして勉強した • わからないことは更に増えた ◦ DRAM初期化って結局何してるのかよくわからん ◦ ハードウェア周りの単語全然わからん ▪
SPI?PCI?SDRAM?SuperI/O?ACPI?AHB?などなど
(おまけ) 似た名前・機能のプロダクトありすぎ問題 • coreboot • U-Boot • Libreboot • LinuxBoot
• LinuxBIOS(corebootのかつての名前) • PPCBoot(U-Bootのかつての名前) • OpenBIOS • SeaBIOS