Mmukoブートシーケンス – QEMUで起動する小さなスタンドアロンCカーネル
Mmuko Boot Sequence – a tiny freestanding C kernel that boots in QEMU (github.com)
要約
この記事は、QEMUエミュレータ上で起動する、スタンドアロンの小さなC言語カーネル「MMUKO」について解説しています。ホストOSのCランタイムに依存しないフリースタンディングコードとして実装されており、BIOS直接起動とGRUBマルチブートの2つの起動パスがサポートされています。開発に必要なツールチェーンや、カーネル内でプログラムを実行する方法についても説明されています。
全文翻訳
MMUKO QEMU ブート・スキャフォールド
重要な区別:
- gistにある
mmuko-boot.cは通常のホスト型Cプログラムです。printf、malloc、calloc、およびホストOSのCランタイムを使用します。 - QEMUはファームウェア、ブートセクタ、カーネル、またはディスクイメージを起動します。起動時にはホスト型Cランタイムが存在しないため、MMUKOはスタンドアロンコードとして実行する必要があります。
このスキャフォールドは2つの起動パスをサポートします。
パスA: このWindowsマシンでの直接BIOS起動
このパスは、MinGW + QEMUセットアップで一般的に使用されるツールを使用します:
asgccldqemu-system-i386
生のブートイメージをビルドします:
.\build-direct.ps1
実行します:
qemu-system-i386 -drive format=raw,file=build\mmuko-direct.img,if=ide,index=0 -display none -serial stdio -no-reboot
カーネルは意図的に最後に停止するため、QEMUはCtrl+Cで停止するまで実行し続けます。
直接起動パスは次のように機能します:
boot16.sが512バイトのBIOSブートセクタとして開始します。- ディスクLBA 1から
kernel-flat.binをメモリの0x10000にロードします。 - 32ビット保護モードに切り替えます。
kernel-entry.sにジャンプします。kernel-entry.sがkernel.c内のkernel_main()を呼び出します。
パスB: GRUBマルチブート
GRUBパスは、ローダーとしてGRUBマルチブートを使用します:
- GRUBがカーネルを32ビット保護モードで起動します。
kernel_main()が画面とシリアル出力を初期化します。mmuko_boot()がMMUKOのブートフェーズを実行します。mmuko_program_main()がブート成功後に実行されます。
ファイル
boot.asm- マルチブートのエントリポイントとスタック設定。boot16.s- 直接BIOS起動ブートセクタ。kernel-entry.s- 直接起動フラットカーネルのエントリポイント。kernel.c- スタンドアロンMMUKOブートモデルとサンプルMMUKOプログラム。linker.ld- GRUBのためにカーネルを1 MiBに配置します。linker-flat.ld- 直接起動カーネルを0x10000に配置します。grub.cfg- GRUBメニューエントリ。Makefile- ISOをビルドし、QEMUで実行します。build-direct.ps1- Windows上で直接BIOS起動イメージをビルドします。
ツールチェーン
Windows上での最も簡単な方法は、WSLまたはMSYS2に以下をインストールすることです:
nasmi686-elf-gccgrub-mkrescuegrub-filexorrisoqemu-system-i386make
Debian/Ubuntuライクな環境では、QEMU/GRUB/NASMは通常次のようにインストールできます:
sudo apt install make nasm grub-pc-bin grub-common xorriso qemu-system-x86
i686-elf-gccクロスコンパイラは引き続き必要です。まだお持ちでない場合は、OSDevスタイルのクロスコンパイラを使用するか、Makefileを既存のスタンドアロンi386コンパイラに合わせて調整してください。
GRUBビルドと実行
make
make run
QEMUはVGAテキストを表示し、同じログが-serial stdioでシリアルにも書き込まれます。
プログラムを記述する場所
kernel.c内のこの関数を編集します:
static void mmuko_program_main(MMUKO_System *sys)
その関数は、このスキャフォールドにおける最初のMMUKO「プログラム」です。mmuko_boot(sys)がBOOT_OKを返した後にのみ実行されます。