GRUBからカーネルを起動する
Multiboot Specification(マルチブート仕様)について
GRUB(Grand Unified Bootloader)は、「Multiboot Specification」に準拠したブートローダーです。
Multiboot Specificationとは、ブートローダーとOS間のインターフェースを規定するものであり、自作OS(または自作カーネル)をMultiboot Specificationに準拠させることで、GRUBから自作OSを起動することが可能となります。
参考:Multiboot Specification version 0.6.95
自作OS(自作カーネル)をMultiboot Specificationに準拠させる。
ここでは、最小構成のカーネルとして以下のファイルを用意します。
multiboot.h
loader.S
kernel.c
Makefile
マルチブートヘッダの作成する。
マルチブート用のヘッダーファイル「multiboot.h」を作成します。
$ cat 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
カーネルローダに適用する。
カーネルのファイル先頭部分(カーネルローダ)をMultiboot Specificationに準拠させます。
$ cat loader.S
#include "multiboot.h"
.text
.code32 /* 32bit-protectmode */
.intel_syntax noprefix /* Intel-style, not use AT&T-style */
.global _start
_start:
jmp entry
.align 4
.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(自作カーネル)を用意する。
ここでは、文字列を出力するだけのカーネルを用意しています。
$ cat kernel.c
#include "multiboot.h"
void
main(void)
{
unsigned short *screen = (unsigned short *)0xB8000;
char *msg = "Start kernel!";
char ch;
while((ch=*msg++))
*screen++ = ((0x0F)<<8) | ch;
while(1);
}
Makefileの作成
カーネルを「elf形式」で作成して、「0x100000」に配置する必要があります。
$ cat Makefile
CC = gcc
CFLAGS = -pipe -ffreestanding -fno-common -fno-builtin \
-fomit-frame-pointer -Os -Wall -c
LD = ld -nostdlib --oformat binary
all: kernel.elf
kernel.elf: kernel.o loader.o
$(LD) -Ttext=0x100000 --oformat elf32-i386 -o kernel.elf \
loader.o kernel.o
loader.o: loader.S
$(CC) $(CFLAGS) -o loader.o loader.S
%.o: %.c
$(CC) $(CFLAGS) -masm=intel $*.c
.PHONY: clean
clean:
rm -f *.o
rm -f *.elf
以上の作業が完了した後、makeコマンドを実行して「kernel.elf」を作成します。
GRUBブートイメージに自作OSを導入する。
イメージファイル(GRUBブートフロッピーの作成)に自作OSを配置して、GRUBから起動できるように設定します。
grub.conf(memu.lst)について
GRUBの起動設定はgrub.conf(またはmemu.lst)で行います。
なお、VineLinuxやCentOSのGRUBでは、grub.confのみ参照しているようです。
念のため、grub.confとmenu.lstを両方用意しておきます
$ cat grub.conf
# デフォルト起動メニュー
default=0
# メニュー選択タイムアウト
timeout=0
# booting menu
title osname
root (fd0)
kernel /kernel.elf
boot
イメージファイルに配置する。
イメージファイルをマウントして、自作OSとGRUB設定ファイルを配置します。
$ mkdir floppy
# sudo mount -t vfat -o loop fd.img ./floppy
# sudo cp kernel.elf ./floppy/.
# sudo cp grub.conf ./floppy/boot/grub/grub.conf
# sudo cp grub.conf ./floppy/boot/grub/menu.lst
# sudo umount ./floppy
以上で作成した「fd.img」をVirtualBoxなどの仮想化ソフトウェアから起動すると、自作OSを起動させることができます。