1. 程式人生 > >MBR、EBR與DBR詳解

MBR、EBR與DBR詳解

先看一張硬碟圖片(一個盤面):

MBR

主引導記錄(MBR,Main Boot Record)是位於磁碟最前邊的一段引導(Loader)程式碼。它負責磁碟作業系統(DOS)對磁碟進行讀寫時分割槽合法性的判別、分割槽引導資訊的定位,它由磁碟作業系統(DOS)在對硬碟進行初始化時產生的。              --摘自百度百科

MBR扇區位於物理硬碟的0柱面,0磁頭,1扇區,也就是整個硬碟的第一個扇區(偏移量為0),共佔512個位元組(即一個扇區),每個物理硬碟只有一個MBR扇區。

MBR扇區由三部分構成:第一部分是446位元組的引導程式碼,也就是上面提到的MBR;第二部分是DPT(Disk Partition Table,硬碟分割槽表),包含4個表項,每個表項16位元組,共佔用64位元組;第三部分是2個位元組的結束標誌,0x55AA。其結構如下圖:

 

DBR

分割槽引導扇區也稱DBR(DOS BOOT RECORD),是由FORMAT高階格式化命令寫到該扇區的內容,DBR是由硬碟的MBR裝載的程式段。DBR裝入記憶體後,即開始執行該載入程式段,其主要功能是完成作業系統的自舉並將控制權交給作業系統。每個分割槽都有引導扇區,但只有被設為活動分割槽才會被MBR裝的DBR入記憶體執行。                 --摘自百度百科

在對硬碟分割槽之後,每一個分割槽均有一個DBR與之對應。DBR位於每個分割槽的第一個扇區,大小為512位元組

DBR的結構與分割槽格式有關,NTFS與FAT32的DBR格式是不同的。

EBR

EBR(Extended Boot Record)是與MBR相對應的一個概念。前邊已經講過,MBR裡有一個DPT的區域,它一共是64位元組,按每16個位元組作為一個分割槽表項,它最多隻能容納4個分割槽。能夠在MBR的DPT裡進行說明的分割槽稱為主分割槽。如果我們想分割槽多於4個的時候,MBR的DPT裡就會容納不下來,於是微軟就想出了另一個解決方案,在MBR裡,只放不多於三個主分割槽,剩下的分割槽,則由與MBR結構很相像的另一種分割槽結構(EBR,也就是擴充套件分割槽引導記錄)進行說明。一個EBR不夠用時,可以增加另一個EBR,如此像一根鏈條一樣地接下去,直到夠用為止。                --又摘自百度百科

實際上,EBR中有用的部分僅為其DPT的前兩個表項,第一個表項記錄了本擴充套件分割槽的邏輯偏移地址和扇區個數,第二個表項記錄了下一個擴充套件分割槽的必要資訊,本質上是一個連結串列的結點。

例項分析

下面給出我的一個Windows7虛擬機器的分割槽結構圖(所有的分割槽檔案系統格式均為NTFS):


在Winhex下讀取到的硬碟資訊如下:

其中MBR、DBR和EBR的位置如下圖:


從上圖可以看到,整個物理硬碟被分成了6個分割槽,其中C、E和F是主分割槽,G、H和I是擴充套件分割槽。寫程式碼獲得各個分割槽的資訊如下:

 

MBR扇區資料分析

讀取MBR如下(在硬碟偏移量為0處讀取512個位元組),找到其中64個位元組的DPT資料:

提取出來如下:

80  20 21 00 07  FE FF FF  00 08 00 00 00 F0 3F 06

00  FE FF FF 07  FE FF FF  00 F8 3F 06 00 F8 7F 02

00  FE FF FF 07  FE FF FF  00 F0 BF 08 00 00 40 02

00  FE FF FF 0F  FE FF FF  00 F0 FF 0A 00 08 40 00

上面四個表項分別指向分割槽CEFG

剛剛已經提到,DPT中最多包含4個表項,每個表項16位元組,每個表項的結構如下:

//DPT表項

typedefstruct_PartTableEntry {
    BYTE bootSignature;//引導標誌
    BYTE startHead;//CHS定址方式,起始磁頭
    BYTE startSector;//起始扇區,本位元組低六位
    BYTE startCylinder;//起始磁軌(柱面),startSector高二位和本位元組
    BYTE systemSignature;//檔案系統型別標誌
    BYTE endHead;//終止磁頭
    BYTE endSector;//終止扇區
    BYTE endCylinder;//終止磁軌
    unsignedint startSectorNo;//LBA定址,起始扇區號
    unsignedint totalSectorsNum;//該分割槽扇區總數
}PartTableEntry,*pPartTableEntry;


先看第一個表項:

80  20 21 00 07  FE FF FF  00 08 00 00 00 F0 3F 06

第一個位元組為引導標誌,0x80表示活動分割槽,0x00表示非活動分割槽。接下來三個位元組用來表示CHS定址方式的起始地址,具體含義已經在上面結構體中給出。接下來一個位元組表示分割槽檔案系統的型別,0x07表示NTFS(參考最後的附表)。接下來的三個位元組表示CHS定址方式的終止地址(0xFEFFFF表示該欄位無效,因為3個位元組最大的定址能力為2^(3*8)個扇區,即8GB。當分割槽大小超過8GB時該欄位無效)。再後面的四個位元組表示LBA(Logical Block Address)定址方式的起始扇區(可以計算出最大支援2TB的硬碟),要注意小端位元組序(資料儲存時低位元組在前),也就是說C盤的起始扇區為00 00 08 00。最後四個位元組表示該分割槽的扇區數量,同樣是小端模式,即C盤共0x063FF000個扇區。

接下來讓我們跳轉到C盤的起始扇區(00 00 08 00),讀取該處512位元組的資料如下:

你會看到熟悉的結束標誌0x55AA,實際上這是C盤的DBR扇區。DBR扇區各個欄位的含義在後面展開。

EBR扇區分析

MBR扇區的硬碟分割槽表的第二和第三個表項與第一個類似,這裡不再展開,我們主要來看一下第四個表項:

00  FE FF FF 0F  FE FF FF  00 F0 FF 0A 00 08 40 00

第一個位元組表示非活動分割槽,CHS定址無效,第五個位元組分割槽型別為0x0F,表示擴充套件分割槽。LBA定址的起始扇區為0x0AFFF000,包含扇區個數為0x00400800。跳轉到該擴充套件分割槽的起始扇區0x0AFFF000處讀取512位元組資料:

最後兩個位元組是結束標誌0x55AA又看到了這512位元組實際上是一個EBR扇區,其結構與MBR扇區相同,但有用的部分僅為DPT的前兩個表項,資料如下:

00  FE FF FF 07  FE FF FF  00 08 00 00 00 90 21 00

00  FE FF FF 05  FE FF FF  00 98 21 00 00 70 1E 00

第一個表項表示本擴充套件分割槽(邏輯驅動器G)的起始地址和扇區數量,其中LBA定址的起始扇區為00 00 08 00,但是該地址為相對偏移,實際的起始扇區為本扇區的實際地址加上相對偏移量,即0x0AFFF000 + 0x00000800 = 0x0AFFF800。讀取0x0AFFF800扇區的資料如下:

這個扇區實際上是邏輯驅動器G的DBR扇區,記錄了G盤的基本資訊。

第二個表項記錄了下一個擴充套件分割槽(邏輯驅動器H)的EBR扇區的起始地址和扇區總數量。其中,EBR扇區的起始地址為00 21 98 00,同樣是一個相對地址,實際扇區為0x0AFFF000 + 0x00219800 = 0x0B218800,讀取0x0B218800扇區的資料如下:

這512位元組是邏輯驅動器H的EBR扇區,同樣提取DPT的前兩個表項:

00  FE FF FF 07  FE FF FF  00 08 00 00 00 B8 0B 00

00  FE FF FF 05  FE FF FF  00 58 2D 00 00 B0 12 00

與上一個EBR扇區類似,第一個表項的LBA定址的起始扇區(00 00 08 00)仍是一個相對偏移,指向本擴充套件分割槽的起始地址,其實際扇區為:0x0B218800 + 0x00000800 = 0x0B219000,實際位元組偏移為0x0B219000 *512位元組每扇區 = 0x1643200000,從該位元組處讀取512位元組資料可以得到分割槽H的DBR扇區,這裡就不再截圖。第二個表項的LBA定址起始扇區(00 2D 58 00)同樣是一個相對偏移,指向下一個擴充套件分割槽(I:)的EBR扇區,其實際扇區為MBR扇區DPT第四個表項的起始扇區加上該相對偏移,即0x0AFFF000 + 0x002D5800 = 0x0B2D4800。該扇區的資料為:

在該EBR扇區中,DPT的第一個表項仍使用相對偏移指出本擴充套件分割槽(I:)的起始扇區,這個扇區就是分割槽I:的DBR扇區。第二個表項全0,表示該擴充套件分割槽即是最後一個擴充套件分割槽。

總結一下,在Windows系統下如果採用MBR的引導方式,當分割槽個數大於等於4的時候,一般情況下系統會將前三個分割槽設為主分割槽,第四個及其之後的分割槽作為擴充套件分割槽。MBR扇區的DPT中前三個表項可以直接定位前三個主分割槽的DBR扇區,第四個表項指向第一個擴充套件分割槽的EBR扇區,根據EBR中的DPT前兩個表項分別可以定位本擴充套件分割槽的DBR扇區和下一個擴充套件分割槽的EBR扇區,由此擴充套件分割槽連結成一條鏈進行管理。

DBR扇區分析

下面給出NTFS和FAT32的DBR扇區格式,注意一點:NTFS下的備份DBR在分割槽的最後一個扇區,FAT32下的備份DBR一般在第六個扇區。

//NTFS DBR扇區

typedefstruct_NTFSDBR {
    BYTE JMP[3]; //跳轉指令
    BYTE FsID[8]; //檔案系統ID
    unsignedshortint bytePerSector;  //每扇區位元組數
    BYTE secPerCluster;       //每簇扇區數
    BYTE reservedBytes[2];    //2個保留位元組
    BYTE zeroBytes[3];    //三個0位元組
    BYTE unusedBytes1[2]; //2個未用位元組
    BYTE mediaType;//媒體型別
    BYTE unusedBytes2[2]; //2個未用位元組
    unsignedshortint secPerTrack;    //每磁軌扇區數
    unsignedshortint Heads; //磁頭數
    unsignedint hideSectors; //隱藏扇區數
    BYTE unusedBytes3[4]; //4個未用位元組
    BYTE usedBytes[4];    //4個固定位元組
    unsigned__int64 totalSectors; //總扇區數
    unsigned__int64 MFT; //MFT檔案起始簇號
    unsigned__int64 MFTMirror;    //MFTMirror檔案起始簇號
    char fileRecord;  //檔案記錄
    BYTE unusedBytes4[3]; //3個未用位元組
    char indexSize;   //索引緩衝區大小
    BYTE unusedBytes5[3]; //未用位元組
    BYTEvolumeSerialID64[8]; //卷序列號
    unsignedint checkSum;    //校驗和
    BYTE bootCode[426];   //引導程式碼
    BYTE endSignature[2]; //結束標誌
}NTFSDBR,*pNTFSDBR;

typedefstruct_FAT32_Sector{
    unsignedint   Sectors_per_FAT_FAT32;    //FAT32每個FAT表佔用扇區數
    unsignedshortint Extend_Flag;    //0-3位表示活動FAT數,7位:0表示在執行時FAT對映到所有FAT 1表示只有一個FAT是活動的,其他位保留
    unsignedshortint FS_Version;  //檔案系統版本,高位元組表示主要修訂號,低直接表示次要修訂號
    unsignedint   Root_Cluster_Number;                              //根目錄簇號,一般取值為2
    unsignedshortint FS_Info_Sector;                                //檔案系統扇區號,一般取1
    unsignedshortint Backup_Sector;                                 //備份引導扇區,一般取值為6
    BYTE   Reserved_Sector[12];        //保留扇區  
}FAT32_Sector, *pFAT32_Sector;
typedefstruct_Basic_BPB{
    unsignedshortint    Bytes_per_Sector;                  //每個扇區位元組數,可取512,1024,2048,4096,通常取512
    BYTE     Sectors_per_Cluster;   //每簇扇區數,可取1,2,4,8,16,32,64,128,FAT32最多跟蹤268,435,445個簇
    unsignedshortint    Reserved_Sector;                   //保留扇區,表示第一個FAT前的扇區數,通常取32
    BYTE     FATs;                                   //FAT表個數,通常取2
    unsignedshortint    RootEntry;                             //根目錄項數,對FAT32,取值必為0
    unsignedshortint    SmallSector;                       //小扇區數,對FAT32,取值必為0
    BYTE     Media;                                 //儲存介質描述,F8表示硬碟,F0表示3.5軟盤
    unsignedshortint    Sector_per_FAT_FAT16;              //針對FAT12/16的每個FAT扇區數,對FAT32,取值為0
    unsignedshortint    Sector_per_Track;                  //每道扇區數,描述磁碟物理結構
    unsignedshortint    Heads;                                 //磁頭數
    unsignedint      Hidden_Sector;                         //該塊硬碟前用於存放引導程式碼及分割槽表的扇區數
    unsignedint      Large_Sector;      //總扇區數,若SmallSector為0,此處表示分割槽上扇區總數
                                     //可用扇區數 = 總扇區數-保留扇區-FAT表佔用扇區
    _FAT32_Sector     Fat32_Sector;                      //FAT32檔案系統扇區資訊                
}Basic_BPB, *pBasic_BPB;
typedef  struct_FAT32_Extend_BPB{
    BYTE Physical_Drive;                            //物理驅動器號,0x80表示物理硬碟,0x00表示軟盤驅動器
    BYTE Reserved;                                       //保留
    BYTE Extend_Singure;                            //0x28或0x29以供Windows NT識別
    unsignedint  Vol_Serial;                                //卷序列號,由格式化時隨機獲得
    BYTE Vol_Label[11];            //卷標示
    BYTE System_ID[8];                 //系統ID,根據格式化的格式為FAT32,FAT16等
}FAT32_Extend_BPB, *pFAT32_Extend_BPB;

//FAT32 DBR扇區
typedefstruct_FAT32_DBR{
    BYTE     JumpInstrction[3]; //0x00,跳轉指令,通常為EB5890,其中58指示了,跳轉位置,在X86中,58+2就代表跳轉到5A處
    BYTE     OEMID[8];                 //0x03,廠商標示和OS版本資訊
    _Basic_BPB            BPB;                               //0x0B
    _FAT32_Extend_BPB Extend_BPB;                            //0x40
    BYTE Boot_Strap[420];              //檔案系統引導程式碼                              //0x5A,引導區程式碼
    BYTE endSignature[2];                  //0x01FE,結束標示
}FAT32_DBR, *pFAT32_DBR;


下面是一個FAT32分割槽的DBR扇區資料,具體含義在上述結構體中已做宣告,這裡就不再展開:

下面是一張以前的FAT32分割槽DBR扇區的資料,部分欄位含義做了解釋:


附-磁碟分割槽型別標誌表: