os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目
【0】README
- 0.0) source code from orange’s implemention of a os and for complete code , please visit https://github.com/pacosonTang/Orange-s-OS/blob/master/boot.asm
- 0.1)本代碼僅用于在 根目錄區(qū)條目中尋找 與 boot代碼定義的LoaderFileName 相同文件名 的 條目,僅此而已,該文件名是loader.bin,需要加載入內(nèi)存繼續(xù)運(yùn)行的代碼文件;(因為找到該文件后, 最后一句指令執(zhí)行了 jmp $,所以處理器執(zhí)行后就停在那里不動,所以這里沒有給出運(yùn)行結(jié)果示意圖)
- 0.2) 就本os而言,即orange’s os ,”在根目錄區(qū)尋找某文件對應(yīng)的根目錄條目“這個任務(wù) 是在 引導(dǎo)扇區(qū)中的引導(dǎo)程序boot 中完成的,而且 boot 后面還要完成 ”把 os 的 加載程序loader copy 到 0x09000:0100處“的任務(wù),注意這與linux 是不同的;
- 0.3)即是說,orange’s os 中的啟動程序boot 執(zhí)行了兩個任務(wù): os引導(dǎo)程序boot 在根目錄區(qū)尋找os加載程序文件loader 對應(yīng)的根目錄條目 + os引導(dǎo)程序boot 從扇區(qū)拷貝os加載程序loader文件到內(nèi)存(boot copy kernel to mem in the same method)
【1】Source Code
;—————————————————————————-
; 函數(shù)名: ReadSector
;—————————————————————————-
; 作用:
; 從第 ax 個 Sector 開始, 將 cl 個 Sector 讀入 es:bx 中, ax初始值=19
ReadSector:
; ———————————————————————–
; 怎樣由扇區(qū)號求扇區(qū)在磁盤中的位置 (扇區(qū)號 -> 磁道=柱面號, 起始扇區(qū), 磁頭號=磁面)
; 注意扇區(qū)號和起始扇區(qū)號不同;扇區(qū)號對于整個磁盤的全局索引值,而起始扇區(qū)號是本磁道的扇區(qū)索引值
; ———————————————————————–
; 設(shè)扇區(qū)號為 x
; ┌ 柱面號 = y >> 1
; x ┌ 商 y ┤
; ————– => ┤ └ 磁頭號 = y & 1
; 每磁道扇區(qū)數(shù) │
; └ 余 z => 起始扇區(qū)號 = z + 1
【2】把文件加載到內(nèi)存的步驟:尋找文件 + 定位文件 + 讀入內(nèi)存
- 2.1)尋找文件方法:
- 2.1.a) 將根目錄的第一個扇區(qū)(如第19個全局扇區(qū))讀入到起始地址為 es:bx=9000h:0100(該地址其實 是在軟盤中的數(shù)據(jù)區(qū)去了) ,循環(huán)下去的話,讀第20、21、….扇區(qū),而es:bx=9000h:0100 永不改變;
- 2.1.b) 因為一個 sector = 512Bytes, 而根目錄條目=32Bytes,所以一個扇區(qū)就含有16個條目,我們要遍歷這16個條目,并將條目中的DIR_NAME屬性(即文件名)和boot 代碼中靜態(tài)的 LoaderFileName 做比較,如果完全匹配的話,那該DIR_NAME所在的條目就是我們要找的根目錄條目, 如果不匹配話,轉(zhuǎn)向 步驟c;
- 2.1.c) add di, offeh , 使得di 指向該條目開頭(因為在發(fā)現(xiàn)條目中的DIR_NAME 與 LoaderFileName 不等的時候,di指向的是DIR_NAME 的下一個字節(jié)),然后 add di, 20h(32個字節(jié),一個條目大小為32字節(jié)) , di指向下一條目開頭,繼續(xù)循環(huán)比較;如果 第一個扇區(qū)的16個根目錄條目都比較完了,轉(zhuǎn)向步驟a,只不過該讀當(dāng)前扇區(qū)的下一個扇區(qū)了;
Return)該步驟完成后,若尋找文件成功,返回的是 滿足 DIR_NAME==LoaderFileName 的 根目錄條目;
(Attention): 你要知道根目錄條目是多么 的重要,因為它存儲有 (文件名 + 文件屬性 + 最后一次寫入時間 + 最后一次寫入日期 + 此條目對應(yīng)的開始簇號 + 文件大小) 等信息;這個根目錄條目 ,不可小覷;
- 2.1.c) add di, offeh , 使得di 指向該條目開頭(因為在發(fā)現(xiàn)條目中的DIR_NAME 與 LoaderFileName 不等的時候,di指向的是DIR_NAME 的下一個字節(jié)),然后 add di, 20h(32個字節(jié),一個條目大小為32字節(jié)) , di指向下一條目開頭,繼續(xù)循環(huán)比較;如果 第一個扇區(qū)的16個根目錄條目都比較完了,轉(zhuǎn)向步驟a,只不過該讀當(dāng)前扇區(qū)的下一個扇區(qū)了;
2.2)定位文件方法(本代碼還未涉及到):(參見 http://blog.csdn.net/pacosonswjtu/article/details/48391467 【2.2】文件分配表-FAT 看個荔枝)“
如FAT所在扇區(qū)(一個扇區(qū)512字節(jié))存儲值為:F0 FF FF FF 8F 00 FF FF FF FF FF FF 09 A0 00 FF , 0F 00 00 ;
則簇號分別為:0-FF0 1-FFF 2-FFF 3-008 4-FFF 5-FFF 6-FFF 7-FFF 8-009 9-00A A-FFF
如果根目錄去中有條目記載某文件A 的 DIR_FstClus=3的話,則對應(yīng)第3個FAT項,結(jié)合上一行,我們知道FAT3==008,所以下一個簇號是8-009 , 以此類推9-00A、 A-FFF。FFF就表示這個簇是最后一個簇了。
Conclusion:找出該文件在數(shù)據(jù)區(qū)中對應(yīng)的所有簇,就定位了該文件了;2.3)讀入內(nèi)存方法(先定位全局扇區(qū),再對寄存器編程):
(上圖錯誤更正)應(yīng)該是怎樣由扇區(qū)號求扇區(qū)在磁盤中的位置,不是定位文件;
如何讀取扇區(qū)內(nèi)容到內(nèi)存? 參見 source code 中的 ReadSector 函數(shù)。
【3】總結(jié)
3.1)首先你要想,尋找文件? 為什么要尋找文件,是因為,我們boot代碼要加載loader 代碼進(jìn)入內(nèi)存,而loader代碼在軟盤上(硬盤)上,所以我們就要在軟盤上尋找該文件。
為什么boot和loader 不寫在同一個程序中?因為 引導(dǎo)扇區(qū)只裝的下最多 512B,所以要把boot程序和 loader 程序分開來存放,然后再由 boot 跳轉(zhuǎn)到 loader程序去執(zhí)行;3.2)怎樣尋找? 要知道FAT12軟盤中的 根目錄區(qū)條目存儲有 所有文件的相關(guān)信息,最重要的就是文件名。通過 利用ReadSector函數(shù) 實現(xiàn) “怎樣由扇區(qū)號求扇區(qū)在磁盤中的位置 (扇區(qū)號 -> 磁道=柱面號, 起始扇區(qū), 磁頭號=磁面)”的功能【暫且叫定位扇區(qū)功能,因為一個扇區(qū)最直觀的表示是全局扇區(qū)號,而扇區(qū)在軟盤中的表示是由3個維度來進(jìn)行:磁頭號(盤面號0,1),磁柱=磁道號,該磁道的上的扇區(qū)號來確定】,
我們就把根目錄區(qū)的第一個全局扇區(qū)號(循環(huán),就進(jìn)入當(dāng)前扇區(qū)的下一個扇區(qū)號),如FAT12 的根目錄區(qū)第一個扇區(qū)號為19(相對于根目錄區(qū)而言是1,而對于全局而言是19),傳入ReadSector函數(shù),將傳入的扇區(qū)內(nèi)容讀入到 es:bx;下一步,我們就把 es:bx中的根目錄條目的FIR_NAME 和 boot代碼中靜態(tài)寫死的文件名LoaderFileName 進(jìn)行比較;- 3.2.1)若相等,則文件尋找成功,返回當(dāng)前所比較的根目錄條目(即是LoaderFileName ==DIR_NAME所在的條目)。要知道一個扇區(qū)=512Bytes,一個根目錄條目=32Bytes,所以一個扇區(qū)==16個根目錄條目, 所以要在es:bx 處比較16次,是個循環(huán)比較;
- 3.2.2)如果比較不成功,全局扇區(qū)號加1(當(dāng)前為19,加1為20,以此類推),循環(huán)下去,直到找到與LoaderFileName 相等的 根目錄條目,或者,遍歷完 根目錄條目的所有扇區(qū)(如 根目錄條目扇區(qū)數(shù)量為14,當(dāng)然,這個是由FAT12的引導(dǎo)扇區(qū)設(shè)置的,可以變化的)
(Attention):其實,你也看到了,要尋找文件,免不了要去定位全局扇區(qū)號(磁頭號,磁道號,該磁道上的扇區(qū)號),定位后,還要讀取該扇區(qū)到內(nèi)存的某個位置,讀入后,還要對該內(nèi)存的某些特定值進(jìn)行比較操作,比較結(jié)果有成功,有失敗;成功后,返回的是比較成功的當(dāng)前根目錄條目值;這就知道了Loader文件在 根目錄區(qū)的描述了,包括(文件名 + 文件屬性 + 最后一次寫入時間 + 最后一次寫入日期 + 此條目對應(yīng)的開始簇號 + 文件大小),接下來,我們就把 Loader 文件加載到內(nèi)存,準(zhǔn)備開始運(yùn)行該Loader文件了。source code 參見 p114.asm >> https://github.com/pacosonTang/Orange-s-OS/blob/master/p114.asm
總結(jié)
以上是生活随笔為你收集整理的os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业邮箱怎么搭建(企业邮箱搭建)
- 下一篇: 个人怎么抢注被删除的域名(个人怎么抢注被