硬盤結構與分區初識詳解

轉至 http://www.linuxdiyf.com/bbs/thread-197157-1-1.html

 

首先說明硬盤的物理組成。整個硬盤的物理組成主要有:

                  1|    圓形的盤片(記錄數據的部分)
                  2|    機械手臂與在其上的磁頭(讀寫盤片上的數據)
                  3|    主軸馬達(轉動盤片讓磁頭讀寫)

   下面以幾何數學抽象分析一個硬盤。硬盤是一個圓柱體。它被切成250個圓片,對應每個圓片有一個磁頭,從上至下編號[0-254]。再看編號爲0的第一個圓片,按固定大小將它分成一個個圓環,叫磁道,由外至內編號[0-n]。所有圓片以此規則給磁道編號。再看編號爲0的磁道,它以每512bytes一份分成了63等分,規定一起始位置,依次編號爲[1-63]。所有磁道以此規則給扇區編號。這每512bytes的區域叫扇區。再看整個圓柱體,所有編號爲0的磁道作爲一組磁道柱,叫柱面(竊以爲翻譯爲“柱面”並不好。)。從上往下看,這個圓柱體就是由編號[0-n]的柱面組成的。一磁道的大小爲:63*512bytes。一個柱面的大小爲:255*63*512bytes=7.8M。這就是著明的C/H/S模型(cylinder/Header/Sector)。這樣,每一組C/H/S數據與每一扇區一一對應。這種模型並不好,所以Linux不用,DOS使用它的。
    還有另一種數學模型,就是LBA(Logical Block Addressing)模型。 它對應於C/H/S模型,以0/0/1所對應的扇區開始,將所有扇區依次以自然數序列編號爲[0-n ]。

    實際的硬盤一到二個盤片就夠了,不過卻是通過上面講的數學模型來進行存取的。下面是關於硬盤分區的內容。

   硬盤的第一個扇區,叫MBR,全稱爲Master BootRecord,即硬盤的主引導記錄。這一扇區也叫主引導扇區。在總共512bytes的主引導扇區裏,主引導程序(bootloader)佔446bytes,第二部分是Partitiontable區(分區表),即DPT,佔64個bytes,記錄硬盤的分區情況。第三部分是magicnumber,佔2個字節,固定爲55AA,起標記分區表的作用。
   通常情況,至少在Linux下的文件系統格式,以MBR所在磁道的下一磁道,也就是0柱面/1磁頭/1扇區(LBA的63號扇區,就是第64格)作爲各個分區的開始,這樣既保護MBR所在磁道,又可以讓各分區的起始/末尾都在柱面的邊緣(除了第一個分區),不過ms粗暴的從0/0/2作爲第一個分區的開始。一般情況硬盤內部的邏輯結構可以描述爲:

                [硬盤]=[[第一磁道][分區組]]
                [第一磁道]=[[MBR ][剩餘62扇區]]

   由於分區表總量是64bytes。需要以每16bytes記錄一個分區的信息。所以它最多隻能記錄四筆分區記錄,與我們想建立多於四個分區的現實不符,於是出現了擴展分區的概念。0號扇區裏存放着4或少於4個分區的記錄,其中一個可以是擴展分區,並且不能多於一個。
   擴展分區的裏的分區叫邏輯分區。擴展分區的第一個扇區同樣用來存放分區表,只是這的分區表更像是一單鏈鏈表。每個擴展分區的分區表只記錄兩筆記錄:一條隸屬於自己的邏輯分區記錄,另一條指向下一個邏輯分區的記錄,我認爲可以形象比喻爲拿一串一次性水杯環環半套着,以杯底爲擴展分區之首,杯口爲末,這樣整條杯子鏈就是一擴展分區。每個杯子的杯底半部分就是自己的邏輯分區,同時是前一杯子的擴展分區;杯口半部分就是自己的擴展分區。其邏輯形式爲:

                [擴展分區一]=[[第一磁道][邏輯分區一][擴展分區組]]
                [擴展分區k]=[[第一磁道][邏輯分區k ]](當k>1)
                [第一磁道]=[[分區表 ][剩餘62扇區]]
   我希望我已經講明白擴展分區的概念了,並希我並沒有理解錯。原本14點多的時候,這篇文章快完工了,正準備去上課呢,剛好這時候分析數據的時候發現擴展分區並不是原來理解的那樣,回這修改的時候,又不那麼好說明白。一開始我以爲擴展分區裏是子擴展分區的概念,每個子擴展分區包含接下來的所有分區。後來認爲每個子擴展分區包含連續的兩個分區。最後得出現在的這個結論。
    下面通過工具dd與losetup模擬出一個硬盤,然後用cfdisk分區,並分析它的分區表,來深刻理解硬盤的分區。
# touch /tmp/mydisk
# cd /tmp/
# dd if=/dev/null of=mydisk count=1 seek=4000000
# modprobe loop
# losetup /dev/loop0 mydisk 

這樣,就可以把文件mydisk當作一個硬盤來使用了。下面對它進行分區。
# cfdisk -h 255 -s 63 /dev/loop0
一個主分區,一個擴展分區,擴展分區內分了三個邏輯分區。下面分析它們的分區表,用# cfdisk -P r /dev/loop0就可以看到它們的分區表,我們先看MBR裏的信息。
Sector 0:
0x000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01
0x1C0:01 00 17 FE 3F 1B 3F 00 00 00 DD DC 06 00 00 00
0x1D0: 01 1C 05 FE 3F F7 1C DD 06 00 DC ED 35 00 00 00
0x1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA

   我們已經知道MBR裏有446bytes的主引導程序,64bytes的分區表和2bytes的“55AA”分區表標誌。由於這個硬盤裏沒有主引導程序,所以[0x000-0x1BD ]的引導程序代碼爲零。[0x1BE-0x1FD]裏就是分區表。可以表示4項分區,每項分區爲16個字節。我們只要把16個字節的內容搞清楚了,分區表就不再神祕了。(用bc的ibase=16;obase=10來快速轉進制數)
    MBR是分區表的信息只有兩項內容:
80 0101 00 17 FE 3F 1B 3F 00 00 00 DD DC 06 00

00 0001 1C 05 FE 3F F7 1C DD 06 00 DC ED 35 00
    這意味着MBR的分區表中只定義了兩個分區,我們一個一個來分析,先分析第一個分區表項,80 0101 00 17 FE 3F 1B 3F 00 00 00 DD DC 06 00,我們先解釋一下這16個字節的含義。
   第一個字節的內容是分區的引導標誌,80表示是引導分區,00表示不是引導分區。接下來三字節表示分區的起始磁頭、扇區、柱面,本例中三個參數分別是01 01 00,這代表第一個分區從0柱面1磁頭1扇區開始。第五個字節表示分區類型,17表示某類型,常用的類型有0F(擴展分區),0B(FAT32),06(FAT16)。接下來三字節分別表示分區的結束磁頭,扇區,柱面。注意,這裏有些玄機,分區的起始扇區和結束扇區看起來用了一個完整字節,其實不是。由於C/H/S中扇區編號從1到63,因此用一個字節表示有些浪費,一個字節由八個二進制數組成,扇區編號只用了低六位,高2位給柱面用了。因此,表示柱面其實用了10個二進制數,其中高2位是從扇區參數中借來的。結合本例看看,這三參數分別是 FE3F1B,分析一下,FE表示分區的結束磁頭是254,3F拆爲二進制是00111111,低六位是111111,用來表示分區的結束扇區,也就是說結束扇區是63。FF拆開後高2位00給了柱面用,不過柱面還是1B,結束在27/254/63。
   C/H/S的柱面用了10個二進制數,最多隻能表示1024個柱面,也就是說最多隻能表示1024X7.8M=7.8G大小的硬盤,這之後的硬盤容量它就力不從心了。這也是當初設計分區表時目光短淺,如果能用兩個字節表示柱面,那現在就完全沒問題了。由於C/H/S對現在的海量硬盤根本無用武之地,因此表示分區大小的重任就只能落在LBA的肩上了。後八個字節就是用LBA方法來表示分區距起始的位置和分區大小,這個起始位置是相對於本分區表所在扇區來說的,起始位置+分區大小-1=結束位置。
    本例中這四個字節的內容是3F 00 00 00,首先我們要高低位互換,四個字節的內容是00 00 003F,轉爲10進制是63,這意味着第一個分區之前的扇區數是63,也意味着第一個分區從63扇區開始。因爲LBA表示扇區是從0開始編號而不是從1開始,分區之前有63個扇區意味着分區之前的扇區是從0到62,那分區起始自然應該從63開始。
    最後四位參數是DD DC 06 00,高低位轉換後得:06 DC DD,轉爲10進制是449757。知道了分區起始位置在63,大小爲449757,就可以算得結束位置爲63+449757-1=449819
    對分區表的第一個項內容總結一下,這16個參數告訴我們,第一個分區從0/1/1開始,到27/254/63結束,可以引導系統,分區類型爲某類型,分區起始的扇區數是63,分區大小是449757扇區。
    接下來的分析就不看C/H/S的起未了,因爲超8G的它表現不了,不過這上面的數據是通過LBA計算得來的。
    分析第二項00  0001 1C  05  FE 3F F7    1C DD 06 00    DC ED 35 00
   知道:不可引導;分區類型爲擴展分區(05);距起始扇區449820(06 DD 1C );分區大小3534300(35 EDDC)。得這個分區的末尾是3974119.接下來要分析的第二張分區表就是在擴展分區的第一個扇區449820扇區裏。截取分區表部分:

Sector 449820:
0x1B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 01
0x1C0: 01 1C 83 FE 3F 37 3F 00 00 00 DD DC 06 00 00 00
0x1D0: 01 38 05 FE 3F 53 1C DD 06 00 1C DD 06 00 00 00
0x1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
    這個分區表同樣只定義了兩個分區,通過前面的概念,知道一個是邏輯分區一,後一個擴展分區二(補充:實際也就是邏輯分區二加上其前的一磁道。),下面分析一下它的數據。
   分析第一項知道:不可引導;分區類型代碼83;距起始扇區63(00 00 00 3F);大小449757(06 DCDD)。這個起始扇區不是從整個硬盤開始算的,而是從本擴展分區的位置開始算的,所有這個數值基本都是63。於是這個起始扇區實際是449820+63=449883;結束扇區是449883+449757-1=899639。這一組起始/結束數據就是邏輯分區一的位置。
    分析第二項:不可引導;類型爲擴展分區(05).距起始扇區449820(06 DD 1C)大小449820(06 DD 1C).注意:以後向下定義後續擴展分區時,之前的扇區數指的都是被定義的擴展分區的起點到第一個擴展分區起點的距離。得起始在扇區449820+449820=899640;結束扇區在899640+449820-1=1349459。這一組數據其實就是邏輯分區二加其前面的一磁道所有的位置。下面分析在扇區899640裏邊的分區表。

Sector 899640:
0x1B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
0x1C0: 01 38 83 FE 3F 53 3F 00 00 00 DD DC 06 00 00 00
0x1D0: 01 54 05 FE 3F F7 38 BA 0D 00 A4 33 28 00 00 00
0x1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 0055 AA

分析第一項:不可引導;分區類型83;距起始扇區63(00 00 00 3F)分區大小449757(00 06 DCDD);得這個分區起始在扇區899640+63=899703;結束在899703+449757-1=1349459。正是上一個擴展分區的位置減去首磁道。
分析第二項:不可引導;分區類型擴展分區(05);距起始扇區899640(0D BA 38)分區大小2634660(0028 33A4);注意:前面提到過了,這個起始是相對於第一擴展分區起始的,而不是相對於前一個擴展分區的。得這個分區起始在扇區449820+899640=134960;結束在1799280+2634660-1=4433939。下面看最後一張分區表,因爲其後再沒有擴展分區,所以它就只有本邏輯分區的一條記錄。

Sector 1349460:
0x1B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
0x1C0: 01 54 83 FE 3F F7 3F 00 00 00 65 33 28 00 00 00
0x1D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
    
    分析得:不可引導;分區類型83;起始63;大小2634597;得起始扇區爲:1349460+63=135523;結束在135523+2634597-1=3984119
至此,分區表分析完畢。分析它只是爲了更好的理解硬盤的分區規律,而這些數據完全可以通過工具獲得。

# cfdisk -P t /dev/loop0
Partition Table for /dev/loop0
         ---Starting----      ----Ending-----    Start     Number of
# Flags Head Sect  Cyl   ID  Head Sect  Cyl     Sector    Sectors
-- ----- ---- ---- ----- ---- ---- ---- ----- ----------- -----------
1  0x80    1    1     0 0x17  254   63    27          63      449757
2  0x00    0    1    28 0x05  254   63   247      449820     3534300
3  0x00    0    0     0 0x00    0    0     0           0           0
4  0x00    0    0     0 0x00    0    0     0           0           0
5  0x00    1    1    28 0x83  254   63    55          63      449757
6  0x00    1    1    56 0x83  254   63    83          63      449757
7  0x00    1    1    84 0x83  254   63   247          63     2634597
# cfdisk -P s /dev/loop0
Partition Table for /dev/loop0
               First       Last
# Type       Sector      Sector   Offset    Length   Filesystem Type (ID) Flag
-- ------- ----------- ----------- ------ ----------- -------------------- ----
1 Primary           0      449819     63      449820 Hidden HPFS/NTF (17) Boot
2 Primary      449820     3984119      0     3534300 Extended (05)        None
5 Logical      449820      899639     63      449820 Linux (83)           None
6 Logical      899640     1349459     63      449820 Linux (83)           None
7 Logical     1349460     3984119     63     2634660 Linux (83)           None

   理解之後,如果分區表丟失,恢復數據只要將分區表複製到相應位置就可以了。即使所有的分區表都不見了,也是可以恢復的。每個分區在建立文件系統時,都會將本分區的類型,大小等信息放在這個分區的頭上。研究這個,我們還是可以確定當前這個分區在硬盤上的位置。有了這個位置信息,基本上還是可以大致的恢復出整個硬盤的分區表(有些信息不太能確定,比如說到底是主分區還是邏輯分區)。如果文件系統的信息也丟失了呢?那就只能碰運氣了。運氣好的話,你能找到一些系統在隱含扇區備份的分區表信息。你可以全盤查找55AA這個特徵值,然後看它像不像分區表。

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