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
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
140
The Efficiency Paradox and How to Save Yourself and the World
hollycummins
1
450
Symfony Mapper Component
soyuka
2
740
たのしいparse.y
ydah
3
120
Effective Signals in Angular 19+: Rules and Helpers
manfredsteyer
PRO
0
110
rails stats で紐解く ANDPAD のイマを支える技術たち
andpad
1
290
命名をリントする
chiroruxx
1
410
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
Haze - Real time background blurring
chrisbanes
1
510
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
220
暇に任せてProxmoxコンソール 作ってみました
karugamo
2
720
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
280
Featured
See All Featured
Docker and Python
trallard
42
3.1k
Six Lessons from altMBA
skipperchong
27
3.5k
Designing for humans not robots
tammielis
250
25k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
Embracing the Ebb and Flow
colly
84
4.5k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Building an army of robots
kneath
302
44k
We Have a Design System, Now What?
morganepeng
51
7.3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
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