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イメージのできあがりです。