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
810
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.7k
FFI: RustとWebAssemblyとJavaScriptと
d0iasm
1
1.2k
Other Decks in Programming
See All in Programming
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
utgwkk
1
370
Jakarta EE meets AI
ivargrimstad
0
240
The Efficiency Paradox and How to Save Yourself and the World
hollycummins
1
440
Haze - Real time background blurring
chrisbanes
1
510
rails stats で紐解く ANDPAD のイマを支える技術たち
andpad
1
290
短期間での新規プロダクト開発における「コスパの良い」Goのテスト戦略」 / kamakura.go
n3xem
2
170
DevFest Tokyo 2025 - Flutter のアプリアーキテクチャ現在地点
wasabeef
5
900
第5回日本眼科AI学会総会_AIコンテスト_3位解法
neilsaw
0
170
Symfony Mapper Component
soyuka
2
730
ソフトウェアの振る舞いに着目し 複雑な要件の開発に立ち向かう
rickyban
0
890
From Translations to Multi Dimension Entities
alexanderschranz
2
130
return文におけるstd::moveについて
onihusube
1
980
Featured
See All Featured
For a Future-Friendly Web
brad_frost
175
9.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
Facilitating Awesome Meetings
lara
50
6.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
A designer walks into a library…
pauljervisheath
204
24k
How STYLIGHT went responsive
nonsquared
95
5.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
How to Ace a Technical Interview
jacobian
276
23k
The Cult of Friendly URLs
andyhume
78
6.1k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
Mobile First: as difficult as doing things right
swwweet
222
9k
Documentation Writing (for coders)
carmenintech
66
4.5k
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