Share
Embed
Hello World in coreboot
「第15回 カーネル/VM探検隊&懇親会@東京」での発表資料です。
https://kernelvm15.peatix.com/
d0iasm
July 20, 2019
Transcript
39 slides
-
ざっくり ”Hello World” まで BIOS OS User Program Reset Hello,
World! ※ 今回の話ではベアメタルプログラミングを考慮しません -
もう少し詳しく ”Hello World” まで Bootloader ハードウェア 初期化 Compiler ブートローダ 呼び出し
リソースの分配 • メモリ • プロセス • デバイス ディスクから kernelをロード ユーザー空間 システムコー ル BIOS/UEFI OS User Program Reset Hello, World! -
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マシンを選択 簡単そう……? ➡ そんなに甘くない -
立ちはだかる壁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”より引用 -
立ちはだかる壁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 最初のステージでメモリ使えない問題 解決法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 最初のステージでメモリ使えない問題 解決法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 最初のステージでメモリ使えない問題 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 -
まとめ • BIOSのコードを読んだり書いたりして勉強した • わからないことは更に増えた ◦ DRAM初期化って結局何してるのかよくわからん ◦ ハードウェア周りの単語全然わからん ▪
SPI?PCI?SDRAM?SuperI/O?ACPI?AHB?などなど -
(おまけ) 似た名前・機能のプロダクトありすぎ問題 • coreboot • U-Boot • Libreboot • LinuxBoot
• LinuxBIOS(corebootのかつての名前) • PPCBoot(U-Bootのかつての名前) • OpenBIOS • SeaBIOS