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.6k
FFI: RustとWebAssemblyとJavaScriptと
d0iasm
1
1.1k
Other Decks in Programming
See All in Programming
Synchronizationを支える技術
s_shimotori
1
150
Vue3の一歩踏み込んだパフォーマンスチューニング2024
hal_spidernight
3
3.1k
Universal Linksの実装方法と陥りがちな罠
kaitokudou
1
220
『ドメイン駆動設計をはじめよう』のモデリングアプローチ
masuda220
PRO
8
440
Progressive Web Apps für Desktop und Mobile mit Angular (Hands-on)
christianliebel
PRO
0
110
Vitest Browser Mode への期待 / Vitest Browser Mode
odanado
PRO
2
1.7k
【Kaigi on Rails 2024】YOUTRUST スポンサーLT
krpk1900
1
250
/←このスケジュール表に立ち向かう フロントエンド開発戦略 / A front-end development strategy to tackle a single-slash schedule.
nrslib
1
590
OpenTelemetryでRailsのパフォーマンス分析を始めてみよう(KoR2024)
ymtdzzz
4
1.6k
CSC509 Lecture 08
javiergs
PRO
0
110
Pinia Colada が実現するスマートな非同期処理
naokihaba
2
160
CSC509 Lecture 09
javiergs
PRO
0
110
Featured
See All Featured
GraphQLの誤解/rethinking-graphql
sonatard
66
9.9k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Testing 201, or: Great Expectations
jmmastey
38
7k
Measuring & Analyzing Core Web Vitals
bluesmoon
1
40
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
[RailsConf 2023] Rails as a piece of cake
palkan
51
4.9k
The Cost Of JavaScript in 2023
addyosmani
45
6.6k
Designing on Purpose - Digital PM Summit 2013
jponch
115
6.9k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
For a Future-Friendly Web
brad_frost
175
9.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
32
2.4k
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