codefans

          導航

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          統計

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          程序設計鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          [開發教程]FAT 12 文件系統簡介

          小謝 發表于 2005-8-26 11:51:06

            有不少朋友在論壇或是發郵件給我,問關于FAT12的問題。對一些開發操作系統的朋友來說,軟盤或軟盤鏡像是不可或缺的系統載體,我們的操作系統要在存儲介質上操作就幾乎不可能離開文件系統,如果想了解一下FAT12、FAT16、FAT32之類的Windows 用過的文件系統,可以去:http://www.yesky.com/20030313/1656880.shtml 
          如果想全面地了解硬盤結構,文件系統原理,下面的一系列文章是很不錯的材料:
          http://www.sjhf.net/Article/sjhfdoc/200404/1.html
          http://www.sjhf.net/Article/sjhfdoc/200404/2.html
          http://www.sjhf.net/Article/sjhfdoc/200404/3.html
          http://www.sjhf.net/Article/sjhfdoc/200404/4.html
          http://www.sjhf.net/Article/Index.html

            本文主要介紹以3.5英寸的1.44M標準格式化的FAT12文件系統的軟盤為介紹對象。這里強調那么多是因為:1.44M的軟盤格式化可以不是1.44M,可以大于也可以小于;格式化的文件系統也可以不是FAT12。

            為什么會出現正常的1.44M軟盤格式化后可大可小的情況呢?從軟盤及軟盤驅動器原理出發,軟盤的尋址方式(可以認為是讀取數據的方式)是:CHS,C = Cylinder(柱面),H = Header(磁頭),S = Sector(扇區)。標準地格式化后,磁盤將被格式化為 每面80磁道(80個同心圓,柱面),每個磁道有18個扇區,每個扇區是 512字節,那么高密3.5英寸軟盤的容量為:2×80×18×512 = 1474560 Byte = 1440 KB = 1.44 MB。然而,軟盤可以不格式為80磁道,每個磁道也可以不是18扇區,這是題外話,如果您有興趣,可以用古老的HDCopy試試。

            文件存儲到磁盤上時至少要占用1個扇區,即使這個文件只有1個字節,如果文件有513字節,那就得占用2個扇區,下一個文件就不能用這只使用了一個字節的扇區。即軟盤以扇區為單位存儲文件。現在用下面的假設來說明本文的目的:
            假設只有18個扇區的磁盤,以 0 - 17 編址,如果一個文件保存在 1 - 6扇區,另一文件保存在 7 - 16扇區,如果我們對第一個文件增加了內容,又需要一個扇區來保存它,但由于文件連續存儲, 7號扇區是第二個文件的,我們當然不能用它,只有最后留有一個扇區可用,我們會不會把第二個文件先挪到8-17扇區以騰出一個扇區來給第一個文件使用呢?當只有少數兩個文件的時候可以,但有很多文件的時候會變得麻煩起來。如果我們用一個表來表示有一個文件占用了 1-6扇區 和 17扇區,那事情就簡單了——我們不必為文件不連續而煩惱。這個表就叫它:文件分配表(File Allocation Table)。那怎樣才能知道這個文件存儲的文件名和文件存放的起始扇區?再建一個表,用于存放文件名、起始扇區、文件創建時間、文件實際大小等等資料,這個表叫:文件目錄表(File Directory Table)。將這兩個表放在磁盤指定的位置,以便操作系統使用,磁盤的其它扇區全都用來存放文件的實際內容,這就構成了有文件系統的磁盤。

            磁盤上,0面0磁道第1扇區用于存放引導程序,如果這512字節最后兩個字節分別是0x55,0xAA(一個字是0xAA55),稱為可引導標志,BIOS會將這512字節讀取出來執行,操作系統便是利用這里來實現引導的。標識軟盤是不是FAT12并不是沒有根據的,在這512字節中,還有一個設備頭用于標識這個軟盤(設備),例子如下:

          ;===========================================================================
          ; 程序執行的第一條指令必須是跳轉(如果你想使用FAT12這類文件系統的磁盤)

          ; 必須占用3字節
          ;===========================================================================
          jmp SHORT main ; 2 bits,跳轉到主程序執行
          nop            ; 1 bit
          ;===========================================================================
          ; FAT12 文件系統頭,從NYAOS 借過來的,可以參考相關的文檔以獲得更多細節
          ; 這個塊會讓 Winimage 認出編譯后的二進制文件為有效的引導文件
          ; 如果不使用這個塊,Winimage將不會將其作為引導程序處理
          ; 但我們可以借助其它方法和工具處理,比如DEBUG
          ;===========================================================================
          bsOEM       db "ExOS0.02"               ; OEM String,任意你喜歡的8字節ASCII碼
          bsSectSize  dw 512                      ; Bytes per sector
          bsClustSize db 1                        ; Sectors per cluster
          bsRessect   dw 1                        ; # of reserved sectors
          bsFatCnt    db 2                        ; # of fat copies
          bsRootSize  dw 224                      ; size of root directory
          bsTotalSect dw 2880                     ; total # of sectors if < 32 meg
          bsMedia     db 0xF0                     ; Media Descriptor
          bsFatSize   dw 9                        ; Size of each FAT
          bsTrackSect dw 18                       ; Sectors per track
          bsHeadCnt   dw 2                        ; number of read-write heads
          bsHidenSect dd 0                        ; number of hidden sectors
          bsHugeSect  dd 0                        ; if bsTotalSect is 0 this value is
                                                  ; the number of sectors
          bsBootDrv   db 0                        ; holds drive that the bs came from
          bsReserv    db 0                        ; not used for anything
          bsBootSign  db 29h                      ; boot signature 29h
          bsVolID     dd 0                        ; Disk volume ID also used for temp
                                                  ; sector # / # sectors to load
          bsVoLabel   db "NO NAME    "            ; Volume Label
          bsFSType    db "FAT12   "               ; File System type <- FAT 12文件系統
          ;===========================================================================
          ; Main start here
          ;===========================================================================
          main:
          #至于如何引導計算機,可以參考我Blog里的more.asp?name=xemean&id=2

            0面0道第2扇區到第10扇區的9個扇區是FAT表的存放位置,為了預防,0面0道的第11扇區到1面0道第1扇區的9個扇區是第2個FAT表的存放位置,這第2個FAT是備用的,當第一個FAT出了問題里,可以用第2個FAT。1面0道的第2扇區起到1面0道的第15扇區(共14個扇區)用于存放 FDT。FDT沒有備份,所以沒有第二個FDT。這里要注意的是,磁盤為了讀寫的速度,0面0道的18個扇區接下來的是 1面0道的扇區,而不是0面1道,因為0面0道跟1面0道同在一個柱面上(同心圓),只是用的磁頭不同。

            FAT12 中,每個文件分配表項只占12位(bit),即1.5字節(byte),每個表項代表一個扇區,在這里,磁盤只有扇區的概念,磁盤里所有扇區都被類似于上一段提到的磁盤讀寫方式線性地編址(LBA),不再有CHS。這里還要提一提簇的概念:DOS會把2個扇區作為一簇,那么文件就要以簇為單位讀寫。簇的大小通常根據磁盤的大小設定,以盡可能少浪費磁盤空間為本。

            FAT12每個表項的值指出文件存放的下一個扇區號,同時也是表項入口。比如如果文件的存放的第一個扇區是002,那系統首先找FAT的002,在002處得到一個值003,表示文件下一個扇區是003號,再接著003表項找,得到006...,表項的值含義如下:
          000 - 此簇未用;FF8 - FFF 該簇為文件的最后一簇;FF0 - FF7,此簇為壞,不可用;其它值表示文件下一簇的簇號。
            下面的圖來說明FAT的基本原理:
          表項編號  值(16位)   備注 
          000   | FF0  | <- 000 項 001項為表頭,1字節 0xF0表示存儲介質
          001   | FFF  | <- 2、3字節為 0xFFFF ,固定值,FAT標志
          002   | 003  | <- 文件下一簇為003
          003   | 005  | <- 下一簇:005
          004   | FF7  | <- 壞簇,不可用
          005   | 011  | <- 下一簇:011
          ........................................
          011   | FF8  | <- 該文件結束
          012   | 000  | <- 可用簇
          .......................................
          根據上表,我們可以知道,一個文件占用了 002,003,005,011 這4個簇。
            簇號 + 31 = 邏輯扇區號 //// 31 = 保留扇區數 + 隱藏扇區數 + FAT數×每個FAT所占扇區數 + FDT所占扇區數 - 2 = 1 + 0 + 2*18 + 14 -2
            LBA = 邏輯扇區號 - 1
            扇區 = (LBA MOD 每道扇區數) + 1
            磁道 = (LBA / 每道扇區數) / 磁頭數
            磁頭 = (LBA / 每道扇區數) MOD 磁頭數

          根據上面的公式,得到以下計算值:
          002: S = ( 32 MOD 18 ) + 1 = 15
          002: C = ( 32 / 18 ) / 2 = 0
          002: H = ( 32 / 18 ) MOD 2 = 1
          -----------------
          011: S = ( ( 11+31-1) MOD 18) + 1 = 6
          011: C = ( ( 11+31-1) / 18) / 2 = 1
          011: H = ( ( 11+31-1) / 18) MOD 2 = 0

            就此,我們已經可心根據簇號得到物理CHS了,那怎樣才能得到一個文件的關系首簇號呢?前面我們提到了FDT。下面說說FDT的結構:
            每個FDT項占32字節,分配如下:
          =======================
          0 - 7 : 8字節,文件名
          8 - 10:  3字節,文件擴展名
          11 :1字節,文件的屬性
          12 - 15:4字節,保留
          16 - 21:6字節,保留
          22 - 23:2字節,文件最后修改時間(時分秒,5:6:5)
          24 - 25:2字節,文件最后修改日期(年月日,7:4:5,年取0-119對應 1980 - 2099)
          26 - 27:2字節,文件首簇號,我們可以根據這個值在FAT中找到文件的存儲位置
          28 - 31:4字節,文件的長度,以字節為單位
          ===========================
          0 - 7 文件名含義:0 - 目錄項為空,可用;E5 - 此文件已經被刪除
          7 - 10 :文件名和擴展名為8.3格式,如果不夠,必需用空格填充,即文件名如果只有6個字節,那剩下的2個字節必須以空格填充。文件名和擴展名都是大寫。
          11屬性字節含義:00 - 普通文件;01 - 只讀;02 - 隱藏;04 - 系統文件;10(1x) - 該文件是目錄。

            就此,本文已經基本介紹完了軟盤的結構,下面介紹如何讀一個文件:

          1. 給出一個文件名,比如“KERNEL.SYS”
          2. 將文件名擴展為“KERNEL  SYS”,即去掉點并為文件名和擴展名補充空格
          3. 讀FDT到內存中(用BIOS INT 13)
          4. 在FDT中查找到符合的文件名
          5. 可選,判斷在FDT中找到的是否是目錄
          6. 在符合的FDT中取出文件首簇號
          7. 讀入FAT,可以選擇讀入兩個FAT表,以檢查是否有效
          8. 將簇號轉換為CHS,將扇區讀入內存
          9. 根據簇號在FAT中查找下一簇,并判斷是否是文件最后一簇
          10. 如果是文件最后一簇,則文件讀取完畢;如果不是,則轉第8步

            如果在引導程序中讀指定的內核文件,則可以省略1、2步,直接給出內核文件名即可。

            如果給出的文件是帶目錄的,那這里還有必要介紹一下:實際上,目錄也是一個文件,只不過這個文件是一個FDT,FDT指出該目錄下其它文件或目錄。因此,給出如下路徑:/EXOS/KERNEL.BIN ,則先是在根目錄中,將“EXOS    ”這個“文件”讀出來,然后在讀出的FDT中找“KERNEL  BIN”。

            好了,本文至此告一段落,但愿能給大家一定的幫助。近期正在寫一個ERP,時間倉促,本文寫得也有不盡如人意的地方,更沒有代碼實例。還請大家見諒。

          X.
          2005-08-26


          閱讀全文(73) | 回復(3) | 引用(0)
           


          回復:FAT 12 文件系統簡介
          future0906(游客)發表評論于2005-8-29 11:08:27
          以下引用xemean在2005-8-28 16:20:19的評論:

          表頭的三個字節的值是 0xFFFFF0,即第1個字節是0xF0,第二個字節是0xFF,第三個字節也是 0xFF。按照小拉丁寫法,高位在前(左),低位在后(右),所以寫成 FF0我認為并沒有錯。


          恩,我明白你的意思了~~,謝

          個人主頁 | 引用 | 返回
           


          回復:FAT 12 文件系統簡介
          xemean發表評論于2005-8-28 16:20:19

          表頭的三個字節的值是 0xFFFFF0,即第1個字節是0xF0,第二個字節是0xFF,第三個字節也是 0xFF。按照小拉丁寫法,高位在前(左),低位在后(右),所以寫成 FF0我認為并沒有錯。


          個人主頁 | 引用 | 返回
           

          posted on 2005-09-14 16:21 春雷的博客 閱讀(1149) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 齐河县| 松原市| 册亨县| 隆德县| 和平区| 桐庐县| 门头沟区| 淮南市| 青浦区| 青州市| 茂名市| 米易县| 五莲县| 江陵县| 福贡县| 弥渡县| 栾川县| 南丹县| 沛县| 时尚| 重庆市| 保靖县| 兴山县| 通化县| 卢龙县| 松潘县| 社会| 旌德县| 剑川县| 峨边| 平南县| 安国市| 建阳市| 道孚县| 留坝县| 闵行区| 宝山区| 新干县| 嘉荫县| 荔浦县| 丹江口市|