linux-0.01 読み (2)

仕方が無いので (?) Makefile から読んでみる事に。
まず、いっちゃんてっぺんのソレが以下。

all:    Image

Image: boot/boot tools/system tools/build
        objcopy  -O binary -R .note -R .comment tools/system tools/system.bin
        tools/build boot/boot tools/system.bin > Image

ええと tools/build という実行ファイルに boot/boot と tools/system.bin を吸わせて Image を出力している模様です。
その tools/build なルールは直下で定義されてて以下。

tools/build: tools/build.c
        $(CC) $(CFLAGS) \
        -o tools/build tools/build.c

tools/build.c は別途確認必要かなぁ。次に出てくるのが tools/system 関連なソレで以下。

boot/head.o: boot/head.s

tools/system:   boot/head.o init/main.o \
                $(ARCHIVES) $(LIBS)
        $(LD) $(LDFLAGS) boot/head.o init/main.o \
        $(ARCHIVES) \
        $(LIBS) \
        -o tools/system > System.map

head.S はこっち関連なのですね。別途確認な必要あり。あと ARCHIVES と LIBS は以下な定義。

ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o
LIBS    =lib/lib.a

上記なソレ達のルールは直下で定義されてて以下。

kernel/kernel.o:
        (cd kernel; make)

mm/mm.o:
        (cd mm; make)

fs/fs.o:
        (cd fs; make)

lib/lib.a:
        (cd lib; make)

このあたりも別途確認必要でしょうね。最後に boot/boot なルールが以下。

boot/boot:      boot/boot.s tools/system
        (echo -n "SYSSIZE = (";stat -c%s tools/system \
                | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s    
        cat boot/boot.s >> tmp.s
        $(AS86) -o boot/boot.o tmp.s
        rm -f tmp.s
        $(LD86) -s -o boot/boot boot/boot.o

先頭のソレは何してるんだろうか。コマンドで確認してみたら以下に置き換えられるのかな。

SYSSIZE = (96764 + 15) /16

色々眺めてて head.s って一体何なんでしょ、と思いつつ色々調べてたら LDFLAGS に秘密がある模様。

LDFLAGS =-s -x -M -Ttext 0 -e startup_32

ld の -e というオプションについては

  • e entry

entry をプログラムのエントリポイントを示すシンボルとして取り扱う

という記述が ld の man にありました。という事はカーネルのエントリポイントは startup_32 ルーチンである、という事になるのか。ちなみに LDFLAGS 使ってるのは tools/system 作る時のみ、という形になってますね。
なんとなくな流れとしては

  • boots なソレが boot sector にあってこいつが boot loader になってるクサい
  • tools/system が上記 boot loader から load されて startup_32 ルーチン起動

で、次は? って思いつつ head.s 見てみたらありますた。
startup_32 ルーチンの末端にて

	jmp after_page_tables

after_page_tables というラベルに jmp しとります。定義が以下。

.org 0x4000
after_page_tables:
	pushl $0		# These are the parameters to main :-)
	pushl $0
	pushl $0
	pushl $L6		# return address for main, if it decides to.
	pushl $main
	jmp setup_paging
L6:
	jmp L6			# main should never return here, but
				# just in case, we know what happens.

う、この先どーなるのか、が分からんぞ。setup_paging 難解。cr レジスタとかページング回路云々なあたりは intel なマニュアルを再読した方が良さげ。
これはちょっと違う意味で微妙な修行だなぁ。。

とりあえず

不明なのは stack に push した $main が取り出されて call されるのはどこなのだ、と。とりあえず、ログは残さずな方向でもう少し色々確認予定ッス。