1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GRUBからCカーネルを起動する

1
Posted at

目的

GRUBから直接C言語で書いた自作カーネル(ただHELLOと表示するだけ)を起動する手順をまとめます。

以前自作OSを作っていた時は、ブートローダや、32bitモードに切り替える処理を自分で書いており、C言語コードへ移行するまでにかなり苦労しましたが、GRUBを使うと勝手にやってくれるようなので試してみます。
https://github.com/ooe1220/KansoOS/blob/master/src/kernel/switch32.asm

GRUBと言えば複数のOSを選択して起動する機能が先に浮かびますが、こんな機能があることは知りませんでした。

コード

kmainに跳ぶ処理です。

start.asm
bits 32
global start
extern kmain

align 4
mb_header:
    dd 0x1BADB002        ; magic
    dd 0x0               ; flags
    dd -(0x1BADB002 + 0x0) ; checksum

start:
    cli
    mov esp, 0x90000     ; 適当なスタック
    call kmain
    hlt

VGAの画面を一旦全て空で上書きしてから、HELLOを表示するだけです。

kernel.c
void kmain(void) {
    volatile unsigned char *vid = (unsigned char *)0xB8000;
    
    // 画面全体を空白(0x20)+白文字/黒背景(0x07)で埋める
    for (int i = 0; i < 80 * 25 * 2; i += 2) {
        vid[i]     = ' ';   // 文字コード
        vid[i + 1] = 0x07;  // 属性(白/黒)
    }
    
    const char *msg = "HELLO";
    int i = 0;
    for (int j = 0; msg[j]; j++) {
        vid[i++] = msg[j];   // ASCII
        vid[i++] = 0x07;     // 白文字/黒背景
    }
    for (;;) asm ("hlt");
}
link.ld
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS {
    . = 0x100000;
    .text : { *(.text) }
    .data : { *(.data) }
    .bss  : { *(.bss) }
}

GRUBの設定

grub.cfg
set timeout=0
set default=0
menuentry "mykernel" {
    multiboot /boot/kernel.bin
    boot
}

起動ディスクの作成

grub-mkrescue命令でGRUBのブートローダ等を書き込んでいます。

nasm -f elf32 start.asm -o start.o
gcc -m32 -ffreestanding -nostdlib -c kernel.c -o kernel.o
ld -m elf_i386 -T link.ld -o kernel.bin start.o kernel.o

grub-file --is-x86-multiboot kernel.bin

mkdir -p iso/boot/grub
cp kernel.bin iso/boot/kernel.bin
cp grub.cfg iso/boot/grub/grub.cfg
grub-mkrescue -o myos.iso iso

実行結果

QEMU

GRUBが色々処理をしているのか、自作ブートローダから立ち上げた時よりも画面表示に時間が少しだけかかりました。

qemu-system-i386 -cdrom myos.iso
截图 2026-08-11 20-41-21

dynabook SS M10 11L/2実機

sudo dvd+rw-format -blank=fast /dev/sr0
sudo growisofs -dvd-compat -Z /dev/sr0=myos.iso
20260811204044_66285c7bb5191eb491aafe379dfdc603

GRUBで初めに実行される命令

biosからkernel.cが呼ばれる間にGRUBが何をしているか全てを理解するのは難しいですが、せめて初めの数十行くらいを見てみようと思います。
初めに実行されるコードを逆アセンブルします。

xorriso -indev myos.iso -report_el_torito plain
xorriso -indev myos.iso -osirrox on -extract boot/grub/i386-pc/eltorito.img eltorito_extracted.img
dd if=eltorito_extracted.img of=cdboot_extracted.img bs=512 count=1
ndisasm -b 16 eltorito_extracted.img > disasm.txt

大変なのであまり深くは読みませんが、文字表示のint 0x10やディスク読み込みのint 0x13が見えます。

00000000  E80000            call 0x3
00000003  EB3B              jmp short 0x40
00000005  0000              add [bx+si],al
00000007  0010              add [bx+si],dl
00000009  0000              add [bx+si],al
0000000B  008D0B00          add [di+0xb],cl
0000000F  00EB              add bl,ch
00000011  7100              jno 0x13
00000013  008A9461          add [bp+si+0x6194],cl
00000017  B300              mov bl,0x0
00000019  0000              add [bx+si],al
0000001B  0000              add [bx+si],al
0000001D  0000              add [bx+si],al
0000001F  0000              add [bx+si],al
00000021  0000              add [bx+si],al
00000023  0000              add [bx+si],al
00000025  0000              add [bx+si],al
00000027  0000              add [bx+si],al
00000029  0000              add [bx+si],al
0000002B  0000              add [bx+si],al
0000002D  0000              add [bx+si],al
0000002F  0000              add [bx+si],al
00000031  0000              add [bx+si],al
00000033  0000              add [bx+si],al
00000035  0000              add [bx+si],al
00000037  0000              add [bx+si],al
00000039  0000              add [bx+si],al
0000003B  0000              add [bx+si],al
0000003D  0000              add [bx+si],al
0000003F  005B31            add [bp+di+0x31],bl
00000042  C08ED0BC00        ror byte [bp-0x4330],byte 0x0
00000047  60                pusha
00000048  8ED8              mov ds,ax
0000004A  8EC0              mov es,ax
0000004C  BEDD7C            mov si,0x7cdd
0000004F  2E668B8F0D00      mov ecx,[cs:bx+0xd]
00000055  6609C9            or ecx,ecx
00000058  7476              jz 0xd0
0000005A  6681C1FF070000    add ecx,0x7ff
00000061  66C1E90B          shr ecx,byte 0xb
00000065  2E668BB70900      mov esi,[cs:bx+0x9]
0000006B  E80500            call 0x73
0000006E  EA00002008        jmp 0x820:0x0
00000073  6631C0            xor eax,eax
00000076  6A10              push byte +0x10
00000078  6646              inc esi
0000007A  6650              push eax
0000007C  6656              push esi
0000007E  680008            push word 0x800
00000081  6650              push eax
00000083  6A10              push byte +0x10
00000085  6631FF            xor edi,edi
00000088  89E6              mov si,sp
0000008A  8B7C10            mov di,[si+0x10]
0000008D  6639CF            cmp edi,ecx
00000090  7603              jna 0x95
00000092  6689CF            mov edi,ecx
00000095  897C02            mov [si+0x2],di
00000098  6651              push ecx
0000009A  B442              mov ah,0x42
0000009C  CD13              int 0x13
0000009E  7316              jnc 0xb6
000000A0  B442              mov ah,0x42
000000A2  CD13              int 0x13
000000A4  7310              jnc 0xb6
000000A6  D1EF              shr di,1
000000A8  7423              jz 0xcd
000000AA  897C10            mov [si+0x10],di
000000AD  897C02            mov [si+0x2],di
000000B0  B442              mov ah,0x42
000000B2  CD13              int 0x13
000000B4  72F0              jc 0xa6
000000B6  89F8              mov ax,di
000000B8  C1E007            shl ax,byte 0x7
000000BB  014406            add [si+0x6],ax
000000BE  66017C08          add [si+0x8],edi
000000C2  6659              pop ecx
000000C4  6629F9            sub ecx,edi
000000C7  75C1              jnz 0x8a
000000C9  83C412            add sp,byte +0x12
000000CC  C3                ret
000000CD  BEEA7C            mov si,0x7cea
000000D0  B40E              mov ah,0xe
000000D2  31DB              xor bx,bx
000000D4  AC                lodsb
000000D5  CD10              int 0x10
...(省略)
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?