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