我們知道在setup.S中所設定ㄉgdt有兩ㄍ描述子,一ㄍ是資料段一ㄍ是程式段,而且它們都只能定址到128mb,我們說明一下描述子好ㄌ:
我只說明那個G位元:0則段界限之Granularity(粒度)為byte,1則段界限之Granularity(粒度)為4Kbytes。因此來看一下setup.Sㄉ描述子:
.word 0x7FFF # limit 128mb 0x7fff*4k=128mb
.word 0x0000 # base address=0
.word 0x9A00 # code read/exec
.word 0x00C0 # granularity=4096, 386
其他部分請自行參考"自己動手寫作業系統"一書。
既然它進入保護模式,但僅設為可定址到128mb,那麼當它ljmp $KERNEL_CS, $(TSTLOAD <<4)之後,它勢必再重新設定一次gdt,所以你在head.s中又看到一個gdt表。接著就是設定idt,這部分以後再來談;接下來作一些CPU相關判斷,然後才是要進入C語言的殿堂。
leal _dl_start@GOTOFF(%ebx), %eax
call *%eax
call do_test
Reloc.c中ㄉvoid _dl_start(void),另一ㄍ是main.c的void do_test(void)。
"void _dl_start(void)"其實這ㄍROUTINE很難懂,若你也看不懂,也可先跳過,只知道它和ELF檔案格式有關,因為我們用C寫ㄉ這些ROUTINEㄉEntry和符號表可能尚未全部定位好,所以才呼叫這個函式。因此這ㄍ函式與記憶體測試和架構無關,若你懂ㄉ話也請你教教我。
以下這ㄍ網址有關於這方面ㄉ知識:Before main()。
void do_test(void)當然就是我門要談ㄉ重點ㄌ‧‧‧待續。