"全ての設計は、最初の512バイトから始まる。"
OSを起動するという行為は、
実はソフトウェアにとって最も物理に近い儀式である。
ボタンが押され、電源が入り、BIOSが動き出し、
そして、「最初の512バイト」が読み込まれる。
それが、**ブートローダ(Bootloader)**だ。
この章では、アセンブリによる最小構成のブートローダを通して、
BIOSという先史時代の遺産との対話を開始しよう。
ブートローダとは何か?
ブートローダとは:
- 電源投入後、最初に実行されるユーザー定義コード
- BIOSやUEFIから制御を受け取り、OSカーネルへと制御を渡す
存在である。
x86の伝統的ブートシーケンスでは:
- BIOSがハードウェア初期化を行う(POST)
- デバイスからMBR(Master Boot Record)を読み込む
- MBRの先頭512バイトを物理アドレス
0x7C00
にロード - そこからコード実行を開始する
つまり、自作OSの最初の命令は、このMBRにある。
MBRの制約と要件
サイズ:512バイト固定
- BIOSは**セクタ単位(512バイト)**で読み込む
- この制限の中で、コード+ブートシグネチャを収める必要がある
ブートシグネチャ:0x55AA
- MBRの末尾2バイト(
0x1FE
,0x1FF
)に0x55
と0xAA
がなければ、
BIOSはそのセクタを「ブートローダ」と認識しない
実行環境:リアルモード(Real Mode)
- 16bit
- セグメント:オフセットアドレッシング
- レジスタ:AX, BX, CX, DX, SI, DI, SP, BP + セグメントレジスタ
- 直接扱えるメモリ:1MB未満
この条件の中で、最初の意志=ブートローダを書く必要がある。
最小構成のブートローダ(例)
以下は「画面に文字を1つ表示してハルトする」ブートローダの例:
[BITS 16]
[ORG 0x7C00]
start:
mov ah, 0x0E ; テレタイプ出力機能(BIOSサービス)
mov al, 'A' ; 出力文字
int 0x10 ; BIOS割り込みで文字出力
cli ; 割り込み禁止
hlt ; ハルト(止まる)
times 510 - ($ - $$) db 0 ; パディング
dw 0xAA55 ; ブートシグネチャ
この512バイト(実際は数十バイト)は:
- BIOSが読み込み
- 実行を開始し
- レジスタや割り込みを通じて、物理デバイスと通信している
つまりこれは、**「設計者が世界と最初に交わす会話」**である。
ビルドと書き込み:自作ブートローダの起動
NASMなどのアセンブラでビルド:
nasm -f bin bootloader.asm -o boot.img
仮想マシンで起動(QEMUなど):
qemu-system-i386 -fda boot.img
この1文字の表示に、設計思想、物理空間、そして歴史が詰まっている。
BIOSという「幽霊」との対話
BIOSは今や過去の遺産と化しつつある。
だが、その影響力は根強い。
- ブート時の割り込み呼び出し(INT 0x10, 0x13など)
- 16bit環境前提の命令体系
- MBR構造
これらは、現代のUEFIが台頭した今も、エミュレーションや互換層として生きている。
ブートローダを書くという行為は、
この幽霊たちと対話し、自らの意志を通すという構造的交渉なのだ。
なぜブートローダを書くのか?
- 自作OS開発の起点として
- アーキテクチャ理解のための実験として
- コンピュータが何をどう始めるのかを知るために
- 制約下で設計する力を鍛えるために
そして何より、
すべてのソフトウェアの“原初の1命令”がここにあるからだ。
結語:512バイトに込められた意志
ブートローダは、わずか512バイトしかない。
だがそこには、
- 世界の立ち上げ
- 意志の伝播
- 設計者の声
が詰まっている。
何かを作るとは、世界に介入すること。
そしてその最初の接触点が、ブートローダである。
"OSを起動するとは、世界を一から立ち上げることであり、そのすべては、512バイトという小さな宇宙に始まる。"