osdev-jpでは、OS開発に有用な情報を収集し公開しています
ソースコード https://github.com/osdev-jp/elf_haribote
変更したところメモ
.hrb
アプリの起動処理の横に、.elf
アプリの起動処理を付け足す。.hrb
のヘッダに依存しているので、場合分けして .elf
にも対応させる必要もある。(hrb_api
関数)objcopy -I coff-i386 apilib.lib -O elf32-i386 libapi.a
.elf
アプリの生成に使うリンカスクリプト.text
, .data
, .bss
セクションに加えて .stack
, .malloc
セクションを生成。STACK
と MALLOC
は使われないので、2 行を削除しても良い。STACK
と MALLOC
の定義はこちらへ。ELF バイナリの生成には、i386-elf をターゲットにビルドした GCC (+ LD) が必要。
「自作エミュレータで学ぶx86アーキテクチャ」の開発ツールセット tolset_p86 に含まれるビルド済み GCC を使うのがお手軽。 次に示す app_make_elf.txt は、tolset_p86 を tolset_h と同じ階層に展開してある前提のスクリプトになっている。
TOOLPATH = ../../z_tools/
INCPATH = ../../z_tools/haribote/
APILIBPATH = ../apilib/
HARIBOTEPATH = ../haribote/
TOOLPATH86 = ../../../tolset_p86/z_tools/
ELFGCCPATH = $(TOOLPATH86)i386-elf-gcc/bin/
export PATH:=$(subst /,\,$(TOOLPATH86));$(ELFGCCPATH);$(PATH)
MAKE = $(TOOLPATH)make.exe -r
MAKEFONT = $(TOOLPATH)makefont.exe
EDIMG = $(TOOLPATH)edimg.exe
IMGTOL = $(TOOLPATH)imgtol.com
GOLIB = $(TOOLPATH)golib00.exe
COPY = copy
DEL = del
NASM = #(TOOLPATH86)nasm.exe
CC = $(ELFGCCPATH)i386-elf-gcc-4.9.2.exe -I$(INCPATH) -I../ -Os -Wall -fleading-underscore -fno-unwind-tables -fno-asynchronous-unwind-tables
LD = $(ELFGCCPATH)ld.exe -L$(APILIBPATH) --nmagic
LDSCRIPT = ../haribote_elf.lds
# デフォルト動作
default :
$(MAKE) $(APP).elf
# ファイル生成規則
$(APP).elf : $(APP).o $(APILIBPATH)libapi.a Makefile $(LDSCRIPT) ld_variables.lds ../app_make_elf.txt
$(LD) -T$(LDSCRIPT) -o $(APP).elf $(APP).o -lapi
haribote.img : ../haribote/ipl11.bin ../haribote/haribote.sys $(APP).elf \
Makefile ../app_make.txt
$(EDIMG) imgin:../../z_tools/fdimg0at.tek \
wbinimg src:../haribote/ipl11.bin len:512 from:0 to:0 \
copy from:../haribote/haribote.sys to:@: \
copy from:$(APP).elf to:@: \
copy from:../nihongo/nihongo.fnt to:@: \
imgout:haribote.img
# 一般規則
%.o : %.c ../apilib.h Makefile ../app_make_elf.txt
$(CC) -c -o $*.o $*.c
# コマンド
run :
$(MAKE) haribote.img
$(COPY) haribote.img ..\..\z_tools\qemu\fdimage0.bin
$(MAKE) -C ../../z_tools/qemu
full :
$(MAKE) -C $(APILIBPATH)
$(MAKE) $(APP).elf
run_full :
$(MAKE) -C $(APILIBPATH)
$(MAKE) -C ../haribote
$(MAKE) run
clean :
-$(DEL) *.o
-$(DEL) haribote.img
src_only :
$(MAKE) clean
-$(DEL) $(APP).elf
app_make_elf.txt の中で LD に渡しているリンカスクリプトの中身を示す。
ENTRY(_HariMain)
INCLUDE ld_variables.lds
SECTIONS
{
. = SIZEOF_HEADERS;
.text : { *(.text) }
"file offset of data" = .;
. = 0;
.stack : AT("file offset of data") {
. = STACK;
}
.data : {
*(.rodata*) *(.data)
}
.bss : { *(.bss) }
.malloc : {
. += MALLOC;
}
}
はりぼて OS ではコード領域とデータ領域をそれぞれ別のセグメントに格納するため、アプリから見た両者の先頭アドレスはともに 0 となる。したがって、途中で . = 0;
として、ロケーションカウンタを 0 にリセットしている。(これだけでは「ファイル内での配置オフセット」も 0 にリセットされてしまうので、AT("file offset of data")
としてファイル内ではコード領域の直後に配置されるように調整する。)