日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)本代碼僅用于在 根目錄區條目中尋找 與 boot代碼定義的LoaderFileName 相同文件名 的 條目,僅此而已,該文件名是loader.bin,需要加載入內存繼續運行的代碼文件;(因為找到該文件后, 最后一句指令執行了 jmp $,所以處理器執行后就停在那里不動,所以這里沒有給出運行結果示意圖)
  • 0.2) 就本os而言,即orange’s os ,”在根目錄區尋找某文件對應的根目錄條目“這個任務 是在 引導扇區中的引導程序boot 中完成的,而且 boot 后面還要完成 ”把 os 的 加載程序loader copy 到 0x09000:0100處“的任務,注意這與linux 是不同的
  • 0.3)即是說,orange’s os 中的啟動程序boot 執行了兩個任務: os引導程序boot 在根目錄區尋找os加載程序文件loader 對應的根目錄條目 + os引導程序boot 從扇區拷貝os加載程序loader文件到內存(boot copy kernel to mem in the same method)

【1】Source Code


;—————————————————————————-
; 函數名: ReadSector
;—————————————————————————-
; 作用:
; 從第 ax 個 Sector 開始, 將 cl 個 Sector 讀入 es:bx 中, ax初始值=19
ReadSector:
; ———————————————————————–
; 怎樣由扇區號求扇區在磁盤中的位置 (扇區號 -> 磁道=柱面號, 起始扇區, 磁頭號=磁面)
; 注意扇區號和起始扇區號不同;扇區號對于整個磁盤的全局索引值,而起始扇區號是本磁道的扇區索引值
; ———————————————————————–
; 設扇區號為 x
; ┌ 柱面號 = y >> 1
; x ┌ 商 y ┤
; ————– => ┤ └ 磁頭號 = y & 1
; 每磁道扇區數 │
; └ 余 z => 起始扇區號 = z + 1

push bpmov bp, spsub esp, 2 ; 辟出兩個字節的堆棧區域保存要讀的扇區數: byte [bp-2]mov byte [bp-2], cl ; 在調用者中, cl 被賦值為1, mov cl, 1push bx ; 保存 bxmov bl, [BPB_SecPerTrk] ; bl: 除數 , BPB_SecPerTrk DW 18 ; 每磁道扇區數div ; y 在 al 中, z 在 ah 中 , div 被除數A 默認存放在AX中(16位以內) 或 AX 和 DX中(32位,DX存放高16位,AX存放低16位)inc ah ; z ++mov cl, ah ; cl <- 起始扇區號mov dh, al ; dh <- yshr al, 1 ; y >> 1 (y/BPB_NumHeads)mov ch, al ; ch <- 柱面號and dh, 1 ; dh & 1 = 磁頭號pop bx ; 恢復 bx; 至此, "柱面號, 起始扇區, 磁頭號" 全部得到mov dl, [BS_DrvNum] ; 驅動器號 (0 表示 A 盤) ,BS_DrvNum DB 0; 中斷 13 的驅動器號 .GoOnReading:mov ah, 2 ; 讀mov al, byte [bp-2] ; 讀 al 個扇區int 13hjc .GoOnReading ; 如果讀取錯誤 CF 會被置為 1, ; 這時就不停地讀, 直到正確為止add esp, 2pop bpret

【2】把文件加載到內存的步驟:尋找文件 + 定位文件 + 讀入內存

  • 2.1)尋找文件方法:
    • 2.1.a) 將根目錄的第一個扇區(如第19個全局扇區)讀入到起始地址為 es:bx=9000h:0100(該地址其實 是在軟盤中的數據區去了) ,循環下去的話,讀第20、21、….扇區,而es:bx=9000h:0100 永不改變;
    • 2.1.b) 因為一個 sector = 512Bytes, 而根目錄條目=32Bytes,所以一個扇區就含有16個條目,我們要遍歷這16個條目,并將條目中的DIR_NAME屬性(即文件名)和boot 代碼中靜態的 LoaderFileName 做比較,如果完全匹配的話,那該DIR_NAME所在的條目就是我們要找的根目錄條目, 如果不匹配話,轉向 步驟c;
    • 2.1.c) add di, offeh , 使得di 指向該條目開頭(因為在發現條目中的DIR_NAME 與 LoaderFileName 不等的時候,di指向的是DIR_NAME 的下一個字節),然后 add di, 20h(32個字節,一個條目大小為32字節) , di指向下一條目開頭,繼續循環比較;如果 第一個扇區的16個根目錄條目都比較完了,轉向步驟a,只不過該讀當前扇區的下一個扇區了;
      Return)該步驟完成后,若尋找文件成功,返回的是 滿足 DIR_NAME==LoaderFileName 的 根目錄條目;
      (Attention): 你要知道根目錄條目是多么 的重要,因為它存儲有 (文件名 + 文件屬性 + 最后一次寫入時間 + 最后一次寫入日期 + 此條目對應的開始簇號 + 文件大小) 等信息;這個根目錄條目 ,不可小覷;
  • 2.2)定位文件方法(本代碼還未涉及到):(參見 http://blog.csdn.net/pacosonswjtu/article/details/48391467 【2.2】文件分配表-FAT 看個荔枝)“

  • 如FAT所在扇區(一個扇區512字節)存儲值為: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的話,則對應第3個FAT項,結合上一行,我們知道FAT3==008,所以下一個簇號是8-009 , 以此類推9-00A、 A-FFF。FFF就表示這個簇是最后一個簇了。
    Conclusion:找出該文件在數據區中對應的所有簇,就定位了該文件了;

  • 2.3)讀入內存方法(先定位全局扇區,再對寄存器編程):

    (上圖錯誤更正)應該是怎樣由扇區號求扇區在磁盤中的位置,不是定位文件;

  • 如何讀取扇區內容到內存? 參見 source code 中的 ReadSector 函數。


【3】總結

  • 3.1)首先你要想,尋找文件? 為什么要尋找文件,是因為,我們boot代碼要加載loader 代碼進入內存,而loader代碼在軟盤上(硬盤)上,所以我們就要在軟盤上尋找該文件。
    為什么boot和loader 不寫在同一個程序中?因為 引導扇區只裝的下最多 512B,所以要把boot程序和 loader 程序分開來存放,然后再由 boot 跳轉到 loader程序去執行;

  • 3.2)怎樣尋找? 要知道FAT12軟盤中的 根目錄區條目存儲有 所有文件的相關信息,最重要的就是文件名。通過 利用ReadSector函數 實現 “怎樣由扇區號求扇區在磁盤中的位置 (扇區號 -> 磁道=柱面號, 起始扇區, 磁頭號=磁面)”的功能【暫且叫定位扇區功能,因為一個扇區最直觀的表示是全局扇區號,而扇區在軟盤中的表示是由3個維度來進行:磁頭號(盤面號0,1),磁柱=磁道號,該磁道的上的扇區號來確定】,
    我們就把根目錄區的第一個全局扇區號(循環,就進入當前扇區的下一個扇區號),如FAT12 的根目錄區第一個扇區號為19(相對于根目錄區而言是1,而對于全局而言是19),傳入ReadSector函數,將傳入的扇區內容讀入到 es:bx;下一步,我們就把 es:bx中的根目錄條目的FIR_NAME 和 boot代碼中靜態寫死的文件名LoaderFileName 進行比較;

    • 3.2.1)若相等,則文件尋找成功,返回當前所比較的根目錄條目(即是LoaderFileName ==DIR_NAME所在的條目)。要知道一個扇區=512Bytes,一個根目錄條目=32Bytes,所以一個扇區==16個根目錄條目, 所以要在es:bx 處比較16次,是個循環比較;
    • 3.2.2)如果比較不成功,全局扇區號加1(當前為19,加1為20,以此類推),循環下去,直到找到與LoaderFileName 相等的 根目錄條目,或者,遍歷完 根目錄條目的所有扇區(如 根目錄條目扇區數量為14,當然,這個是由FAT12的引導扇區設置的,可以變化的)
  • (Attention):其實,你也看到了,要尋找文件,免不了要去定位全局扇區號(磁頭號,磁道號,該磁道上的扇區號),定位后,還要讀取該扇區到內存的某個位置,讀入后,還要對該內存的某些特定值進行比較操作,比較結果有成功,有失敗;成功后,返回的是比較成功的當前根目錄條目值;這就知道了Loader文件在 根目錄區的描述了,包括(文件名 + 文件屬性 + 最后一次寫入時間 + 最后一次寫入日期 + 此條目對應的開始簇號 + 文件大小),接下來,我們就把 Loader 文件加載到內存,準備開始運行該Loader文件了。source code 參見 p114.asm >> https://github.com/pacosonTang/Orange-s-OS/blob/master/p114.asm

總結

以上是生活随笔為你收集整理的os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。