日曜日, 5月 03, 2009

Linux i386 Boot Code HOWTO

LDP HOWTO-INDEX
Linux i386 Boot Code HOWTO


  • 静的なカーネル改変
    カーネルイメージは以下のように構成されている
    [bootsect][setup][[head][misc][compressed_kernel]

    ブートプロセスの詳細を理解しよう。このプロセスは以下のような論理的なステージに分割することが可能である:
    1. BIOS がブートデバイスを選択する。
    2. BIOS がブートデバイスから [bootsect] をロードする。
    3. [bootsect] が [setup] および [[head][misc][compressed_kernel]] をロードする。
    4. [setup] が実行され、 [head](it is at 0x1000 or 0x100000) にジャンプする。
    5. [head] が [misc] 中のカーネルの展開関数を呼び出す。
    6. [misc] が [compressed_kernel] を展開し、0x100000 からのアドレスに置く。
    7. 高レベルの初期化(linux/arch/i386/kernel/head.S 中の startup_32 から開始される) が行なわれる。

  • LKM なしでの動的なカーネル改変


ブートストラップ


/* Absolute addresses */
#define ABS(x) ((x) - _start + 0x7c00)
/* Print message string */
#define MSG(x) movw $ABS(x), %si; call message

.text
.code16
.globl _start
_start:
MSG(test_string)
loop: jmp loop

test_string: .string "test boot sector!"

/*
* Use BIOS "int 10H Function 0Eh" to write character in teletype mode
* %ah = 0xe %al = character
* %bh = page %bl = foreground color (graphics modes)
*/
1:
movw $0x0001, %bx
movb $0xe, %ah
int $0x10 /* display a byte */
message:
lodsb
cmpb $0, %al
jne 1b /* if not end of string, jmp to display */
ret

partion_table:
/* パーティションテーブル(16byte * 4)が格納されている */
. = _start + 446

boot_signature:
/* 最後の2バイトはブートシグニチャというマジックナンバになっている */
. = _start + 510
.word 0xaa55


コンパイルは次の通り.boot はちょうど 512 バイトになる.
$ gcc -c -O2 -nostdinc -fno-builtin boot.S -o boot.o
$ gcc -nostdlib -Wl,-N,-Ttext,7c00 -o boot.exec boot.o
$ objcopy -O binary boot.exec boot
$ dd if=boot of=a.img conv=notrunc

0 件のコメント: