3日目 その1
FDから読み込む部分は特に問題ないとおもいます。
(といいつつ自分は当初セグメントの設定がいい加減だったために大層苦労しましたが…)
次にharibote.S(haribote.nasに相当)を書きます。
.file "haribote.S" .code16gcc .text main: // 画面のモードを切り替える. movb $0x13, %al movb $0x00, %ah int $0x10 fin: // やることないので無限ループ hlt jmp fin
これも特に問題はないはすです。
リンカースクリプトharibote.lsは以下のとおり。
OUTPUT_FORMAT("binary") /* We want raw binary image */ /* Define memory layout */ /* Specify input and output sections */ SECTIONS { . = 0x8200; .text : { *(.text) } /* Executable codes */ .data : { *(.data) } /* Initialized data */ .bss : { *(.bss) } /* Uninitialized data */ .rodata : { *(.rodata*) } /* Constant data (R/O) */ }
ここでなぜ ". = 0x8200" (nasでの"ORG 0x8200"に相当)があるかというと、FDのデータは最初のセクタから0x8000に読み込まれるようになっていますが、haribote.Sの.textセクションはOS自作本とは異なりFD最初のセクタの直後に書き込まれる(後述のMakefile参照)ため、0x8000 + 0x200(1セクタ分)で0x8200にあることになるためです。
このためipl.S内でのjmp命令の先も0xc200ではなく0x8200になります。
あとはアセンブル&リンクしてFDイメージを作るのですが、アセンブルするファイルも増えたのでそろそろMakefileを書いてみます。
CC = gcc CFLAGS = -I./golibc -fno-common -Wall -O2 -c \ -finhibit-size-directive -fno-ident \ -fomit-frame-pointer -fcall-used-ebx TARGET = hello IPL = ipl HARIBOTE = haribote ${TARGET}.bin: ${IPL} ${HARIBOTE} dd if=/dev/zero of=$@ bs=512 count=2880 &> /dev/null dd if=${IPL} of=$@ conv=notrunc &> /dev/null dd if=${HARIBOTE} of=$@ conv=notrunc seek=1 &> /dev/null ${IPL}: ipl.o ipl.ls ld -T ipl.ls -o $@ ipl.o \ -Map ${IPL}.map --cref ${HARIBOTE}: haribote.o haribote.ls ld -T haribote.ls -o $@ haribote.o \ -Map ${HARIBOTE}.map --cref %.o: %.S Makefile ${CC} ${CFLAGS} $< clean: rm -f *.o *.map ${IPL} ${HARIBOTE} ${TARGET}.bin
hariboteが最初のセクタ(ipl)の直後に書き込まれているのがわかるとおもいます。
これでmakeコマンド1発でFDイメージのできあがりです。