經過閱讀Makefile和build.c可知,bootsect.s 編譯後的bootsect 是整個系統的第一段程序,它佔用軟盤的前512字節。
linuxquestion: 系統爲何認爲軟盤是一個啓動盤,並從bootsect開始執行?
ans: 先來講說系統爲何它被認爲是啓動盤?考慮一個極端狀況,使用命令dd if='/dev/zero' of='floppy.img bs=512 count=1
製做一個軟盤鏡像(全部內容均爲0),使用Bochs啓動。此時會提示它不是啓動盤。
實際上,計算機判斷啓動盤的方式很簡單:使用魔數,第510和511字節(最後兩字節)爲 ** 55aa 。
question:如何保證目標文件大小是512字節?
ans:在彙編程序中使用 .org ** 指令。
ios
因此,爲了保證軟盤是啓動盤,在bootsect.s 中使用了這樣的代碼:編程
.org 508 root_dev: .word ROOT_DEV boot_flag: .word 0xAA55那麼,若是要如何本身製做一個啓動盤呢?知道了魔數的概念後,很容易寫一個C語言程序製做一個啓動盤(只是Bochs再也不提示沒有啓動盤了)。在Linux中,有一些比較方便的工具能夠完成這個任務:使用剛纔提到的dd製做一個鏡像,在使用hexedit工具把魔數改好就能夠了!
___
接下來,具體看看bootsect的程序。
從 _start 開始,這裏是程序入口。第一個關鍵動做是:rep movw
,其中,rep的做用是執行下面這個指令cx次,movw是複製一個字(兩個字節)ds:si處內容到es:di處。再看看前面幾行對寄存器的賦值,容易理解,這段代碼就是:將0x7c00處代碼複製512字節到0x9c00處。
接下來,使用Bios中斷int 0x13
從軟盤讀取setup模塊和system模塊,其中,讀取Sysetm模塊時,因爲該模塊比較大,因此同時容int 0x10
在屏幕打印提示內。當一切準備就緒,一行jmpi 0,SETUPSEG
跳轉到Setup模塊,至此,完成本身的使命。
總結一下,bootsect.s有如下幾行關鍵代碼:rep movw
,int 0x13
,int 0x10
,jmpi 0,SETUPLEN
,.org 508
,.word 0xAA55
,分別完成了這樣幾個任務 : 複製自身到0x9c00,讀取Setup和System模塊,跳轉到Setup,保證啓動區大小,插入魔數製成啓動盤。工具