自己動手從零寫桌面操作系統GrapeOS系列教程——22.文件系統與FAT16

學習操作系統原理最好的方法是自己寫一個簡單的操作系統。


新買的硬盤和優盤在第一次使用時需要格式化,有時候還需要分區。這是爲什麼呢?分區和格式化到底是幹啥呢?本講將爲大家解開這些疑惑。

一、文件系統

1.分區

首先說一下分區,我們平時看到的C盤、D盤等就是一個個分區。硬盤第一個扇區的一部分固定空間叫做分區表,劃分分區就是在這個分區表中記錄一下各分區的信息,包括各個分區從哪個扇區開始,到哪個扇區結束等。由於GrapeOS所用虛擬硬盤的空間大小隻有4MB,沒必要分區,所以我們在MBR中也沒有填寫分區表。

2.格式化

格式化是在某個分區上做的。如果一個盤沒有做分區,那就將整個盤作爲一個分區看待,GrapeOS就是這樣的。大家如果對硬盤或優盤做過格式化就會知道,格式化的時候會讓你選擇一種文件系統,常見的選項有NTFS、FAT32、exFAT等。所謂格式化就是將某種文件系統的信息寫入到這個分區的一部分扇區上。那什麼是文件系統呢?下面來簡單介紹一下。

3.文件系統

計算機一開始是沒有文件和文件系統概念的。前面我們學習了對硬盤的讀寫,我們知道對硬盤的讀寫是按扇區爲單位進行的。在讀寫硬盤的時候我們有用到文件的概念嗎?沒有。到目前爲止,我們用的虛擬硬盤上並沒有任何文件系統,就和剛買的新硬盤一樣,但並不影響我們讀寫硬盤。但是在沒有文件系統的情況下實際使用會非常麻煩。比如你將多個文件寫入到硬盤上,你需要記錄每個文件存放在了那些扇區上;如果爲一個文件增加了一些內容,需要多佔用一些扇區,你需要知道哪些扇區是空閒的。這些問題都是需要文件系統處理的。早期的計算機之所以沒有文件系統也能用是因爲當時的每個外部存儲器上的數據都是爲某一件事專用的,有配套的程序做處理,並不能像現在隨意往硬盤裏存放各種文件。總之,文件系統是爲了方便在硬盤或其它存儲設備上存儲數據而抽象出來的一種數據管理方式。只說是抽象出來的,這個不好理解,文件系統有很多種,需要結合一種具體的文件系統講解才能明白。下面我們介紹一下GrapeOS中用的文件系統FAT16。

二、FAT16

1.FAT16空間分佈

首先大家需要明白兩個概念,文件屬性和文件內容。文件屬性一般包含文件名稱、大小、修改日期等信息。文件內容是指文件內具體包含的東西,比如一個文本文件,它的內容就是裏面的文本信息。
在FAT16文件系統中,一般會將硬盤或某個分區劃分爲5個部分:引導扇區、FAT1表、FAT2表、根目錄區、數據區。如下圖所示:

  • 引導扇區就是硬盤或分區的第一個扇區。
  • 根目錄區存放的就是根目錄中文件和文件夾的屬性信息。
  • 數據區存放的是所有文件和文件夾的內容。
  • FAT1表和FAT2表存放的是文件內容的簇號,也就是記錄每個文件的內容存放在了哪些扇區中。簇是FAT16數據區中的一個空間單位,每個簇等於若干個扇區,具體等於多少個扇區,需要在引導扇區中設置。在GrapeOS中每個簇設置等於一個扇區。簇是FAT16中用來存放文件數據的基本單位,不可分割,一個簇內的空間不能一部分屬於一個文件,而另一部分屬於另一個文件。比較特殊的一點是數據區中的簇號不是從0開始的,而是從2開始的。
    FAT2表是FAT1表的備份,大小完全相同,正常情況下里面的數據也完全相同。如果發生不正常的情況可以用FAT2表中的數據恢復FAT1表。在GrapeOS中我們不考慮這種不正常的情況,所以捨棄了FAT2表。如下圖所示:

2.FAT16引導扇區

FAT16文件系統引導扇區結構表:

名稱 偏移 長度 內容 GrapeOS的值
BS_jmpBoot 0 3 一個短跳轉指令 jmp boot_start nop
BS_OEMName 3 8 廠商名稱 GrapeOS
BPB_BytsPerSec 11 2 每扇區字節數 0x0200
BPB_SecPerClus 13 1 每簇扇區數 0x01
BPB_RsvdSecCnt 14 2 保留扇區數(引導扇區的扇區數) 0x0001
BPB_NumFATs 16 1 FAT表的份數 0x01
BPB_RootEntCnt 17 2 根目錄可容納的目錄項數 0x0200
BPB_TotSec16 19 2 扇區總數 0x2000(4MB)
BPB_Media 21 1 介質描述符 0xf8
BPB_FATSz16 22 2 每個FAT表扇區數 0x0020
BPB_SecPerTrk 24 2 每磁道扇區數 0x0020
BPB_NumHeads 26 2 磁頭數 0x0040
BPB_HiddSec 28 4 隱藏扇區數 0x00000000
BPB_TotSec32 32 4 如果BPB_TotSec16是0,由這個值記錄扇區數。 0x00000000
BS_DrvNum 36 1 int 13h的驅動器號 0x80
BS_Reservedl 37 1 未使用 0x00
BS_BootSig 38 1 擴展引導標記 0x29
BS_VolID 39 4 卷序列號 0x00000000
BS_VolLab 43 11 卷標 Grape OS
BS_FileSysType 54 8 文件系統類型 FAT16
引導代碼及其它 62 448 引導代碼、數據及其它填充字符等
結束標誌 510 2 0xAA55 0xAA55

從上表中可以看到,FAT16引導扇區中前62個字節是有固定格式的,FAT16的格式化就是將上表中的格式數據寫入到引導扇區中。上表中的數據並非每一行都有用,我們用到的有:BPB_BytsPerSec、BPB_SecPerClus、BPB_RsvdSecCnt、BPB_NumFATs、BPB_RootEntCnt、BPB_TotSec16、BPB_FATSz16。根據這些信息就能推斷出GrapeOS的硬盤FAT16扇區分佈:

3.FAT16目錄項

文件夾也叫目錄,文件和文件夾的屬性都存儲在目錄項中,在根目錄和其它目錄中存放的是一個一個的目錄項,也就是說文件夾的內容就是目錄項列表。每個目錄項有32個字節,具體結構如下:

名稱 偏移 長度 描述
DIR_Name 0 11 文件名8字節,擴展名3字節
DIR_Attr 11 1 目錄項屬性(0x10代表文件夾,0x20代表文件)
保留位 12 10 保留位
DIR_WrtTime 22 2 最後一次寫入時間
DIR_WrtDate 24 2 最後一次寫入日期
DIR_FstClus 26 2 起始簇號
DIR_FileSize 28 4 文件大小

每個扇區可以存放16個目錄項。

4.FAT表和FAT表項

前面我們講到,在FAT16的數據區中是以簇爲單位編號的,簇號從2開始依次遞增。FAT16的簇號是用16位二進制數表示的,這也是FAT16中16的含義。除了前2個簇號不用,最後的16個簇號有特殊用途,FAT16最多可以管理216-2-16=65518個簇。
在目錄項中,DIR_FstClus存放的是起始簇號。如果一個文件或文件夾的內容在一個簇裏放不下,需要多個簇,其它簇號需要記錄到FAT表中。在FAT16的FAT表中,每兩個字節是一個FAT表項,每個FAT表項代表一個簇,從第一個FAT表項開始依次代表簇0、簇1、簇2、簇3、簇4等等,用來表示每個簇是否已被佔用或下一個簇。對於每個FAT表項,如果它的值是0表示該簇未使用,可以用來存放新數據,對於一個剛格式化完的硬盤,FAT表中除了前2個表項,其它表項應該都是0。如果FAT表項的值不爲0,表示該簇已被佔用,而且這個值就是文件內容下一個簇的簇號,這樣就實現了文件內容在數據區中的鏈式存儲。從目錄項中拿到文件的起始簇號,在起始簇號對應的FAT表項中的值就是存放文件內容的第二個簇號,在第二個簇號對應的FAT表項中的值就是存放文件內容的第三個簇號……舉個例子,比如一個文件的起始簇號是5,在第5個FAT表項中存放的是文件內容的第2個簇號,假設第2個簇號是8,則會在第8個FAT表項中存放第3個簇號,以此類推,就像鏈表一樣,直到下一個簇號大於等於0xfff8,表示文件內容結束,請見下圖。

上圖中表示這個文件共佔用3個簇的空間,簇號分別是5、8、9。我們只要把這個簇鏈表中每個簇的數據從數據區裏讀取出來,並按簇鏈表的順序存放在一起就是文件的完整內容。
FAT表項取值說明:

FAT表項 實例值 描述
0 0xfff8 磁盤表示字(實際無用,設爲0即可。)
1 0xffff 第一個簇不可用(實際無用,設爲0即可。)
2
3
……
0x0003
0x0004
……
0x0000:可用簇
0x00020xffef:已用簇,標識下一個簇的簇號<br>0xfff00xfff6:保留簇
0xfff7:壞簇
0xfff8~0xffff:文件的最後一個簇

前面我們已經提到,GrapeOS的FAT表有32個扇區,每個扇區有256個FAT表項,則共有8192個FAT表項。由於數據區簇號是從2開始的,FAT表中的前2個FAT表項不使用,也就是最多能管理8190個簇。我們這裏一個簇等於一個扇區,所以這裏的FAT表最多能管理8190個扇區。而我們這裏的數據區共8127個扇區,FAT表大小夠用了。


視頻版地址:https://space.bilibili.com/1688387238
配套的代碼與資料在:https://gitee.com/jackchengyujia/grapeos-course
GrapeOS操作系統交流QQ羣:643474045

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章