- 人は複雑なものと、単にややこしいだけのものを区別する。複雑さは興味深いと見なされるが、ややこしさは有害だと見なされる。x86_64 CPUのセットアップ過程は、その大半がややこしさに属する。
- BIOSによって読み込まれたブートセクタから、CPUを16ビットのリアルモードから64ビットのロングモードへ設定する方法を解説する。この設定は基本的なものであり、さらに多くの作業が必要となる。
- Intel 64 および IA-32 アーキテクチャ・ソフトウェア開発者マニュアル、アセンブラ(nasmを使用)、QEMUが必要。x86アセンブリと言語としてのnasm構文を理解している必要がある。
出発点: BIOS
- リセット後、x86 CPUは"リアルモード"にある。このモードでは基本オペランドサイズが16ビットである。セグメンテーションを使って1MBのメモリをアドレス指定できる。
- BIOS後に最初に実行されるコードはブートセクタにある。BIOSはシステム内で
0xaa55 で終わる最初のセクタを探し、そのブートセクタをメモリアドレス 0x7c00 に読み込む。
- BIOSが提供するのは512バイトだけであり、これを使ってブートローダーの残りの部分をブートストラップしなければならない。
ブートセクタの設定
- 簡単なブートセクタを用意し、BIOSルーチンを使って画面にメッセージを表示して停止させる。これにより、ツールが正しく動作するか確認できる。
- アセンブリコードとMakefileを使ってブートセクタを設定する。
ステップ1 – ディスクから第2段階を読み込む
- ブートローダーは2段階に分けられる。第1段階はブートセクタ内のコードで、BIOSが読み込むすべての部分である。第1段階の唯一の目的は、第2段階をメモリに読み込むことだ。
- 第2段階では、16ビットのリアルモードから32ビットの保護モードへ切り替える。保護モードではBIOSルーチンを使えない。ディスクからセクタを読み込むのは、はるかに複雑になる。
- BIOSを使ってディスクにアクセスする方法を説明する。
32ビット保護モード
- CPUをリアルモード(16ビット)から保護モード(32ビット)へ切り替える。保護モードでは、セグメンテーションを使ってメモリ保護を実装する。
- 保護モードへ切り替える前に、グローバルディスクリプタテーブル(GDT)を定義する必要がある。GDTはメモリ内に連続した構造として定義される。
- GDTを定義し、保護モードへ切り替える方法を解説する。
64ビットロングモード
- ロングモードへ切り替える前に、CPUは保護モードにあり、かつページングが有効化されていなければならない。保護モードはすでに設定されているが、ページングが必要となる。
- ページングはセグメンテーションに代わって、仮想アドレス空間や権限などを管理する。ロングモード移行のためのページテーブルを作成する方法を解説する。
- ロングモード移行用のGDTを定義し、保護モードからロングモードへ切り替える方法を説明する。
GN⁺のまとめ
- この記事は、x86_64 CPUを16ビットのリアルモードから64ビットのロングモードへ設定する過程を詳しく説明している。これにより、ブートローダーやOSカーネル開発への理解を深められる。
- BIOS、ブートセクタ、保護モード、ロングモードなど多様な概念を扱い、各段階で必要となるアセンブリコードと設定方法を提供している。
- この記事はOS開発に関心のある人に有用で、特にx86アーキテクチャへの深い理解を与えてくれる。類似の機能を持つプロジェクトとしては「Writing a Simple Operating System – from Scratch」がある。
1件のコメント
Hacker Newsのコメント