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
800
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.1k
Other Decks in Programming
See All in Programming
Macとオーディオ再生 2024/11/02
yusukeito
0
370
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
24k
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
110
Flutterを言い訳にしない!アプリの使い心地改善テクニック5選🔥
kno3a87
1
170
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
【Kaigi on Rails 2024】YOUTRUST スポンサーLT
krpk1900
1
330
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
Remix on Hono on Cloudflare Workers
yusukebe
1
290
初めてDefinitelyTypedにPRを出した話
syumai
0
400
Pinia Colada が実現するスマートな非同期処理
naokihaba
4
220
Featured
See All Featured
RailsConf 2023
tenderlove
29
900
Teambox: Starting and Learning
jrom
133
8.8k
Docker and Python
trallard
40
3.1k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Code Review Best Practice
trishagee
64
17k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
6.9k
Gamification - CAS2011
davidbonilla
80
5k
We Have a Design System, Now What?
morganepeng
50
7.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
27
4.3k
Done Done
chrislema
181
16k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
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