syslinux引导扇区不支持ntfs文件系统_实战 FAT12 文件系统
1. 引言
經過一系列的文章,我們終于完成了從實地址模式跳轉到保護模式,并且實現了分段、分頁以及保護模式下的中斷與異常機制。
保護模式究竟“保護”了什么
可是我們除了最初的時候,在磁盤第一個扇區寫入一段代碼來實現最初“hello world”,此后,我們就一直用 DOS 來拉起我們的“操作系統”,那么,你是不是有種不夠盡興的感覺?明明說好要寫自己的操作系統,卻要用別人的操作系統來引導,我們能不能自己寫一個引導區呢?
答案當然是可以的,編寫一個引導區看起來是如此的容易,只需要創建一個新的文件,里面指定被載入內存的初始地址,然后在引導扇區的代碼中先將這個新的文件內容載入內存,再用一條跳轉指令,跳轉過去即可。
而這個“新的文件”就被稱為操作系統的 loader,他負責在操作系統啟動前進行一系列的準備工作,然后從實地址模式跳轉到保護模式,再加載內核。
2. 磁盤的基本概念
既然要讓引導扇區找到磁盤上的文件,那我們首先要來看看磁盤空間是如何構成的。
通常,磁盤擁有遠大于內存的容量,要想合理利用這些容量,就需要將他們進行劃分,讓數據能夠在各自的區域內,從而方便迅速定位數據。
2.1. 磁道、柱面和磁頭數
如圖所示,我們可以將硬盤看做是多個光盤的組合,而每個“光盤”都被稱為一個“盤片”,由于盤片位于硬盤盒內,不在暴露在空氣中,因此,盤片得以更加高速的旋轉,且數據密度也達到光盤所無法企及的程度,但其原理其實與光盤仍然非常類似。
而正如上面的圖上所示,硬盤中并不只有一個盤片,也不只有一個磁頭,所有的同心旋轉的盤片經由磁頭掃過的磁道共同構成了一個圓柱面,這就是“柱面”。
如上圖所示,借由盤片的旋轉,讓磁頭能夠讀取到的一圈圈軌道,就是“磁道”,數據就位于磁道上。
2.2. 扇區、簇與頁
每連續的 512 字節數據組成了一個扇區,若干個扇區又組成了一個簇,簇是磁盤空間分配的最小單位,也就是說,你即使創建一個 1 字節的文件,實際上這個文件至少也要占用磁盤 1 簇的空間。
而每次內存與磁盤的交互中,操作的最小單位就是一頁,1 頁由若干簇構成,通常是 4096B。
3. 經典文件系統?—?FAT12
FAT12 是一種“古老的”文件系統,到現在,軟盤所使用的文件系統也通常是 FAT12,但其他地方已經基本上沒有使用之處了。
不過現在的 FAT32 與 FAT12 從結構上來說是非常類似的,所以我們本文以 FAT12 來做講解,未來會有專門的文章來介紹各個文件系統之間的區別,敬請期待。
本文,我們以一個 1.44M 的軟盤為例進行介紹:
如上圖所示,一個 1.44M 的軟盤,可以劃分為 2879 個扇區,共分為圖上所示的五個區域。
3.1. 引導扇區
第一個扇區就是引導扇區,他的具體取值是固定的:
FAT12?引導扇區格式
| BS_jmpBoot | 3 | jmp?LABEL_START | nop | |
| BS_OEMName | 3 | 8 | 廠商名 | ‘ForrestY’ |
| BPB_BytsPerSec | 11 | 2 | 每扇區字節數 | 0x200(512) |
| BPB_SecPerClus | 13 | 1 | 每簇扇區數 | 0x01 |
| BPB_RsvdSecCnt | 14 | 2 | Boot記錄占用多少扇區 | 0x01 |
| BPB_NumFATs | 16 | 1 | 共有多少FAT表 | 0x02 |
| BPB_RootEntCnt | 17 | 2 | 根目錄文件數最大值 | 0xE0?(224) |
| BPB_TotSec16 | 19 | 2 | 扇區總數 | 0xB40(2880) |
| BPB_Media | 21 | 1 | 介質描述符 | 0xF0 |
| BPB_FATSz16 | 22 | 2 | 每FAT扇區數 | 0x09 |
| BPB_SecPerTrk | 24 | 2 | 每磁道扇區數 | 0x12 |
| BPB_NumHeads | 26 | 2 | 磁頭數 | 0x02 |
| BPB_HiddSec | 28 | 4 | 隱藏扇區數 | |
| BPB_TotSec32 | 32 | 4 | 如果BPB_TotSec16是0,由這個值記錄扇區數 | 0xB40(2880) |
| BS_DrvNum | 36 | 1 | 中斷13的驅動器號 | |
| BS_Reserved1 | 37 | 1 | 未使用 | |
| BS_BootSig | 38 | 1 | 擴展引導標記 | 0x29 |
| BS_VolD | 39 | 4 | 卷序列號 | |
| BS_VolLab | 43 | 11 | 卷標 | ‘OrangeS0.02’ |
| BS_FileSysType | 54 | 8 | 文件系統類型 | ‘FAT12’ |
| 引導代碼 | 62 | 448 | 引導代碼、數據及其他填充字符等 | |
| 結束標志 | 510 | 2 | 0xAA55 |
3.2. 文件分配表?—?FAT?表
FAT 表又叫“文件分配表”,從圖上可以看到,FAT12 具有兩個 9 扇區大小的 FAT 表。
FAT2 通常是 FAT1 的備份,兩者可以認為是一樣的。
在 FAT 表中,每 12 位被稱為一個 FAT 項(FAT Entry),第?0?個和第 1 個 FAT 項始終不使用,從第 2 個 FAT 項開始,每個 FAT 項對應數據區的一個簇,數據區首個簇號為 2,FAT Entry N 正好對應數據區簇號為 N 的簇。
每個 FAT 項中存儲的是當前文件的當前簇的下一個簇的簇號,如果值大于等于?0xFF8,那么就表示這已經是文件的最后一個簇,0xFF7 則表示這對應了一個壞簇。
3.3. 根目錄區
根目錄區存儲了若干條目錄條目,每個目錄條目長 32 字節,最多存儲 BPB_RootEntCnt 個條目。
因此可以得到公式:
根目錄區扇區數?=?(BPB_RootEntCnt * 32)/BPB_BytsPerSec。
BPB_RootEntCnt 和 BPB_BytsPerSec 就是上文中起始扇區中定義的相應字段。
目錄條目的存儲內容為:
FAT12?根目錄區目錄條目內容
| DIR_Name | 0xB | 文件名8字節,擴展名3字節 | |
| DIR_Attr | 0xB | 1 | 文件屬性 |
| 保留 | 0xC | 10 | |
| DIR_WrtTime | 0x16 | 2 | 最后修改時間 |
| DIR_WrtDate | 0x18 | 2 | 最后修改日期 |
| DIR_FstClus | 0x1A | 2 | 此條目對應的開始簇號 |
| DIR_FileSize | 0x1C | 4 | 文件大小 |
3.4. 數據區
毋庸多言,數據區存儲的就是文件的實際內容。
如果這個文件實際是一個目錄,那么這個簇實際存儲的就是這個目錄下文件構成的條目列表,具體信息與根目錄區中的條目格式相同。
4. FAT12?文件讀取過程
經過上述 FAT12 分區的介紹,我們就已經可以清楚的知道如何在一個 FAT12 類型的磁盤上尋找一個文件了:
獲取文件系統基本信息?—?讀取位于第?0?個扇區的起始扇區
計算數據區首個扇區?—?根據起始扇區中的?BPB_RootEntCnt?字段和?BPB_BytsPerSec?字段計算根目錄區大小,從而計算出數據區對應的扇區號
獲取根目錄中的文件?—?從19號扇區開始讀取根目錄區條目,找到?DIR_NAME?保存的相同文件名的文件或目錄,讀取對應的簇號?DIR_FstClus
獲取文件內容?—?通過?DIR_FstClus?存儲的簇號找到對應的?FAT?項,同時讀取數據區中對應的簇號的文件內容,并根據?FAT?項獲取下一簇號遞歸進行讀取,直到?FAT?項標識文件內容損壞或文件讀取完成
5. 實踐?—?如何創建軟盤
既然我們已經非常清楚了軟盤的文件系統結構,你是否想要實踐一下看看呢?是否一個軟盤的文件系統真的如我們上面所描述的就是這樣存儲的呢?
5.1. 創建軟盤鏡像
通過下面的命令可以實現一個虛擬軟盤鏡像文件的創建:
dd?if=boot.bin?of=boot.img?bs=512?count=1?conv=notrunc
5.2. 建立文件系統
通過下面的命令,可以將剛剛創建的軟盤格式化為對應的文件系統格式:
mkfs.vfat?floppy.img?/建格式化為vfat文件系統/
5.3. 向軟盤鏡像中添加文件
5.3.1. 創建掛載目標目錄
mkdir?/mnt/floppy
5.3.2. 掛載軟盤鏡像
mount?-o?loop?boot.img?/mnt/floppy
你也可以增加?-t vfat?參數指定文件系統格式。
5.3.3. 添加文件
對于已經掛載好的 loop 設備,你可以隨意去操作:
cp?hello.txt?/mnt/floppy
cp?world.txt?/mnt/floppy
rm?/mnt/floppy/hello.txt
5.3.4. 解除掛載
umount?/mnt/floppy
5.4. 查看虛擬軟盤鏡像文件內容
虛擬軟盤鏡像內容是一個二進制文件,我們可以通過 vim 來讀取:
vim?-b?boot.img
可是這樣打開后,你仍然會發現看到了一團亂碼,別急,通過下面的 vim 命令就可以切換到十六進制模式展示了:
:%!xxd?-g?1
6. 微信公眾號
歡迎關注微信公眾號,以技術為主,涉及歷史、人文等多領域的學習與感悟,每周三到七篇推文,只有全部原創,只有干貨沒有雞湯。
7. 附錄?1?—?系列歷史文章
7.1. 準備工作
計算機是如何啟動的?如何制作自己的操作系統
如何調試操作系統
7.2. 保護模式
操作系統的內存管理?—?分段與分頁、虛擬地址、邏輯地址、線性地址、物理地址
保護模式究竟“保護”了什么7.2.1. 分段
詳解?32?位保護模式與內存分段機制
進軍保護模式
保護模式進階?—?再回實模式
實戰局部描述符表?LDT
利用調用門實現特權級間跳轉(上)?—?原理篇
利用調用門實現特權級間跳轉(下)?—?實戰篇
7.2.2. 分頁
詳解操作系統分頁機制與實戰
實戰分頁機制實現?—?通過實際內存大小動態調整頁表個數
7.2.3.?中斷與異常
保護模式下的中斷和異常(上) -- 硬件原理篇
保護模式下的中斷和異常(下) -- 軟件實戰篇
總結
以上是生活随笔為你收集整理的syslinux引导扇区不支持ntfs文件系统_实战 FAT12 文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 二分法实现pow_Pyth
- 下一篇: 调用远程摄像头进行人脸识别_人脸识别技术