GRUBでOSを起動する

前回はフロッピーイメージファイルに GRUB をインストールした。今回はその GRUB から OS を起動する。

GRUB とは

GRUB とは,Multiboot Specification に準拠したブートローダーである。
Multiboot Specification とはブートローダーと OS 間のインターフェースを規定するもので,次のような背景から開発された。
「今日までに作成された多くの OS は独自のブートローダーを持っている。そのため,OS をインストールするたびにブートローダーをインストールしなければならないし,一つのマシンに複数の OS を共存させるのが困難である」
OS開発者は,Multiboot Specification で規定された少量の規定を満たすだけで,この規格に準拠したブートローダーから起動でき,前記の問題を解決した OSバイナリを作成できる。Multiboot Specification 開発者は,すべての OS がこの規格に準拠し前述の問題が解決される事を望んでいるし,僕らは Multiboot Specification を良い戦略だと思うから,この規格に従うことにしよう。

自作OS を Multiboot Specification に準拠させる

この仕事は非常に簡単だ。カーネルのバイナリの先頭に,規定された少量のヘッダーを加えるだけでいい。このヘッダーはマルチブートヘッダーと呼ばれる。

次のようなファイル multiboot.h を用意して:

#define MULTIBOOT_HEADER_MAGIC          0x1BADB002
#define MULTIBOOT_HEADER_FLAGS          0x00000000
#define MULTIBOOT_HEADER_CHECKSUM       -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS)
#define KERNEL_STACK_SIZE               0x100000

OS の先頭である head.S に次のようにマルチブートヘッダーを書き加えた:

#include "multiboot.h"

        .text
        .code32                         // 32bit-protectmode
        .intel_syntax noprefix          // I hate AT&T-style
        .global _start
_start:
        jmp entry
        .align 4
        // multiboot header
        .long MULTIBOOT_HEADER_MAGIC
        .long MULTIBOOT_HEADER_FLAGS
        .long MULTIBOOT_HEADER_CHECKSUM

entry:
        push    ebx                     // push multiboot_info structure pointer
        push    eax                     // push MBOOT_HEADER_MAGIC

        jmp     main                    // jmp kernel main

ブートローダーは OS をメモリ 0x100000 へ読み込み,今回は ELFバイナリを作成したいので,リンカーには次のようなオプションを追加した:

ld -Ttext=0x100000 --oformat elf32-i386 ...

イメージファイルの作成

作成したカーネルを,前回作成したイメージファイルのルートディレクトリにコピーする

GRUBからの起動

ここでイメージファイルを起動すれば,ブートローダーである GRUB のシェルが表示される。
このシェルで次のようなコマンドを打ち込み,OS を起動させる。
起動するデバイスを指定する:

root (fd0)

次のようなコマンドでルートディレクトリのファイル一覧が表示できる:

cat /[Tab]

先ほどルートディレクトリに置いたカーネルを指定する:

kernel /kernel.elf

ここで問題が無ければ,次のように打ち込んで OS が起動できる:

boot

GRUBの設定ファイル

毎回先ほどのようなコマンドを打ち込み,OS を起動するのは面倒なので menu.lst という GRUB の設定ファイルを作成しよう。
次のような menu.lst をイメージファイルの /boot/grub へ置けば,GRUB 起動時に OS が自動起動されるようになる:

default=0
timeout=0

title my_os
root (fd0)
kernel /kernel.elf