13號中斷 int 13(轉)

第一部分      簡      介   
   1,1   
   一.    硬盤結構簡介   
    
       1.    硬盤參數釋疑   
           到目前爲止,    人們常說的硬盤參數仍是古老的    CHS    (Cylinder/Head/Sector)   
   參數.    那麼爲何要使用這些參數,    它們的意義是什麼?它們的取值範圍是什麼?   
           好久之前,    硬盤的容量還很是小的時候,    人們採用與軟盤相似的結構生產硬   
   盤.    也就是硬盤盤片的每一條磁道都具備相同的扇區數.    由此產生了所謂的3D參   
   數    (Disk    Geometry).    既磁頭數(Heads),    柱面數(Cylinders),    扇區數(Sectors),   
   以及相應的尋址方式.   
    
           其中:   
    
           磁頭數(Heads)    表示硬盤總共有幾個磁頭,也就是有幾面盤片,    最大   
   爲    255    (用    8    個二進制位存儲);   
           柱面數(Cylinders)    表示硬盤每一面盤片上有幾條磁道,    最大爲    1023   
   (用    10    個二進制位存儲);   
           扇區數(Sectors)    表示每一條磁道上有幾個扇區,    最大爲    63    (用    6   
   個二進制位存儲).   
           每一個扇區通常是    512個字節,    理論上講這不是必須的,    但好象沒有取   
   別的值的.   
    
           因此磁盤最大容量爲:   
    
           255    *    1023    *    63    *    512    /    1048576    =    8024    GB    (    1M    =    1048576    Bytes    )   
   或硬盤廠商經常使用的單位:   
           255    *    1023    *    63    *    512    /    1000000    =    8414    GB    (    1M    =    1000000    Bytes    )   
    
           在    CHS    尋址方式中,    磁頭,    柱面,    扇區的取值範圍分別爲    0    到    Heads    -    1,   
     0    到    Cylinders    -    1,    1    到    Sectors    (注意是從    1    開始).   
    
       2.    基本    Int    13H    調用簡介   
    
           BIOS    Int    13H    調用是    BIOS    提供的磁盤基本輸入輸出中斷調用,    它能夠   
   完成磁盤(包括硬盤和軟盤)的復位,    讀寫,    校驗,    定位,    診斷,    格式化等功能.   
   它使用的就是    CHS    尋址方式,    所以最大識能訪問    8    GB    左右的硬盤    (    本文中   
   如不做特殊說明,    均以    1M    =    1048576    字節爲單位).   
    
       3.    現代硬盤結構簡介   
    
           在老式硬盤中,    因爲每一個磁道的扇區數相等,    因此外道的記錄密度要遠低   
   於內道,    所以會浪費不少磁盤空間    (與軟盤同樣).    爲了解決這一問題,    進一   
   步提升硬盤容量,    人們改用等密度結構生產硬盤.    也就是說,    外圈磁道的扇區   
   比內圈磁道多.    採用這種結構後,    硬盤再也不具備實際的3D參數,    尋址方式也改   
   爲線性尋址,    即以扇區爲單位進行尋址.   
           爲了與使用3D尋址的老軟件兼容    (如使用BIOS    Int13H接口的軟件),    在硬   
   盤控制器內部安裝了一個地址翻譯器,    由它負責將老式3D參數翻譯成新的線性   
   參數.    這也是爲何如今硬盤的3D參數能夠有多種選擇的緣由    (不一樣的工做模   
   式,    對應不一樣的3D參數,    如    LBA,    LARGE,    NORMAL).   
    
       4.    擴展    Int    13H    簡介   
    
           雖然現代硬盤都已經採用了線性尋址,    可是因爲基本    Int    13H    的制約,    使   
   用    BIOS    Int    13H    接口的程序,    如    DOS    等還只能訪問    8    G    之內的硬盤空間.   
   爲了打破這一限制,    Microsoft    等幾家公司制定了擴展    Int    13H    標準   
   (Extended    Int13H),    採用線性尋址方式存取硬盤,    因此突破了    8    G    的限制,   
   並且還加入了對可拆卸介質    (如活動硬盤)    的支持.   
    
二.    Boot    Sector    結構簡介   
    
       1.    Boot    Sector    的組成   
    
           Boot    Sector    也就是硬盤的第一個扇區,    它由    MBR    (Master    Boot    Record),   
   DPT    (Disk    Partition    Table)    和    Boot    Record    ID      三部分組成.   
    
           MBR    又稱做主引導記錄佔用    Boot    Sector    的前    446    個字節    (    0    to    0x1BD    ),   
   存放系統主引導程序    (它負責從活動分區中裝載並運行系統引導程序).   
           DPT    即主分區表佔用    64    個字節    (0x1BE    to    0x1FD),    記錄了磁盤的基本分區   
   信息.    主分區表分爲四個分區項,    每項    16    字節,    分別記錄了每一個主分區的信息   
   (所以最多能夠有四個主分區).   
           Boot    Record    ID    即引導區標記佔用兩個字節    (0x1FE    and    0x1FF),    對於合法   
   引導區,    它等於    0xAA55,    這是判別引導區是否合法的標誌.   
    
       2.    分區表結構簡介   
    
           分區表由四個分區項構成,    每一項的結構以下:   
    
           BYTE    State                :    分區狀態,    0    =    未激活,    0x80    =    激活    (注意此項)   
           BYTE    StartHead        :    分區起始磁頭號   
           WORD    StartSC            :    分區起始扇區和柱面號,    底字節的低6位爲扇區號,   
                                             高2位爲柱面號的第    9,10    位,    高字節爲柱面號的低    8    位   
           BYTE    Type                  :    分區類型,    如    0x0B    =    FAT32,    0x83    =    Linux    等,   
                                             00    表示此項未用   
           BYTE    EndHead            :    分區結束磁頭號   
           WORD    EndSC                :    分區結束扇區和柱面號,    定義同前   
           DWORD    Relative        :    在線性尋址方式下的分區相對扇區地址   
                                                 (對於基本分區即爲絕對地址)   
           DWORD    Sectors          :    分區大小    (總扇區數)   
    
           注意:    在    DOS    /    Windows    系統下,    基本分區必須以柱面爲單位劃分   
   (    Sectors    *    Heads    個扇區),    如對於    CHS    爲    764/255/63    的硬盤,    分區的   
   最小尺寸爲      255    *    63    *    512    /    1048576    =    7.844    MB.   
    
       3.    擴展分區簡介   
    
           因爲主分區表中只能分四個分區,    沒法知足需求,    所以設計了一種擴展   
   分區格式.    基本上說,    擴展分區的信息是以鏈表形式存放的,    但也有一些特   
   別的地方.   
           首先,    主分區表中要有一個基本擴展分區項,    全部擴展分區都隸屬於它,   
   也就是說其餘全部擴展分區的空間都必須包括在這個基本擴展分區中.    對於   
   DOS    /    Windows    來講,    擴展分區的類型爲    0x05.   
           除基本擴展分區之外的其餘全部擴展分區則以鏈表的形式級聯存放,    後   
   一個擴展分區的數據項記錄在前一個擴展分區的分區表中,    但兩個擴展分區   
   的空間並不重疊.   
           擴展分區相似於一個完整的硬盤,    必須進一步分區才能使用.    但每一個擴   
   展分區中只能存在一個其餘分區.    此分區在    DOS/Windows    環境中即爲邏輯盤.   
   所以每個擴展分區的分區表    (一樣存儲在擴展分區的第一個扇區中)中最多   
   只能有兩個分區數據項(包括下一個擴展分區的數據項).   
           擴展分區和邏輯盤的示意圖以下:   
     
   三.    系統啓動過程簡介   
    
           系統啓動過程主要由一下幾步組成(以硬盤啓動爲例):   
    
           1.    開機    :-)   
           2.    BIOS    加電自檢    (    Power    On    Self    Test    --    POST    )   
                 內存地址爲    0ffff:0000   
           3.    將硬盤第一個扇區    (0頭0道1扇區,    也就是Boot    Sector)   
                 讀入內存地址    0000:7c00    處.   
           4.    檢查    (WORD)    0000:7dfe    是否等於    0xaa55,    若不等於   
                 則轉去嘗試其餘啓動介質,    若是沒有其餘啓動介質則顯示   
                 "No    ROM    BASIC"    而後死機.   
           5.    跳轉到    0000:7c00    處執行    MBR    中的程序.   
           6.    MBR    首先將本身複製到    0000:0600    處,    而後繼續執行.   
           7.    在主分區表中搜索標誌爲活動的分區.    若是發現沒有活動   
                 分區或有不止一個活動分區,    則轉中止.   
           8.    將活動分區的第一個扇區讀入內存地址    0000:7c00    處.   
           9.    檢查    (WORD)    0000:7dfe    是否等於    0xaa55,    若不等於則   
                 顯示    "Missing    Operating    System"    而後中止,    或嘗試   
                 軟盤啓動.   
           10.    跳轉到    0000:7c00    處繼續執行特定系統的啓動程序.   
           11.    啓動系統    ...   
    
           以上步驟中    2,3,4,5    步是由    BIOS    的引導程序完成.    6,7,8,9,10   
   步由MBR中的引導程序完成.   
    
           通常多系統引導程序    (如    SmartFDISK,    BootStar,    PQBoot    等)   
   都是將標準主引導記錄替換成本身的引導程序,    在運行系統啓動程序   
   以前讓用戶選擇要啓動的分區.   
           而某些系統自帶的多系統引導程序    (如    lilo,    NT    Loader    等)   
   則能夠將本身的引導程序放在系統所處分區的第一個扇區中,    在    Linux   
   中即爲    SuperBlock    (其實    SuperBlock    是兩個扇區).   
    
     
           第二部分    技術資料   
   第一章    擴展    Int13H    技術資料   
    
   一.    簡介   
           設計擴展    Int13H    接口的目的是爲了擴展    BIOS    的功能,    使其支持   
   多於1024柱面的硬盤,    以及可移動介質的瑣定,    解鎖及彈出等功能.   
    
   二.    數據結構   
    
   1.    數據類型約定   
           BYTE          1    字節整型    (      8    位    )   
           WORD          2    字節整型    (    16    位    )   
           DWORD        4    字節整型    (    32    位    )   
           QWORD        8    字節整型    (    64    位    )   
    
   2.    磁盤地址數據包    Disk    Address    Packet    (DAP)   
           DAP    是基於絕對扇區地址的,    所以利用    DAP,    Int13H    能夠輕鬆地逾   
   越    1024    柱面的限制,    由於它根本就不須要    CHS    的概念.   
           DAP    的結構以下:   
    
           struct    DiskAddressPacket   
           {   
                   BYTE    PacketSize;            //    數據包尺寸(16字節)   
                   BYTE    Reserved;                //    ==0   
                   WORD    BlockCount;            //    要傳輸的數據塊個數(以扇區爲單位)   
                   DWORD    BufferAddr;          //    傳輸緩衝地址(segment:offset)   
                   QWORD    BlockNum;              //    磁盤起始絕對塊地址   
           };   
    
           PacketSize    保存了    DAP    結構的尺寸,    以便未來對其進行擴充.    在   
   目前使用的擴展    Int13H    版本中    PacketSize    恆等於    16.    若是它小於   
   16,    擴展    Int13H    將返回錯誤碼(    AH=01,    CF=1    ).   
           BlockCount    對於輸入來講是須要傳輸的數據塊總數,    對於輸出來講   
   是實際傳輸的數據塊個數.    BlockCount    =    0    表示不傳輸任何數據塊.   
           BufferAddr    是傳輸數據緩衝區的    32    位地址    (段地址:偏移量).    數據   
   緩衝區必須位於常規內存之內(1M).   
           BlockNum    表示的是從磁盤開始算起的絕對塊地址(以扇區爲單位),   
   與分區無關.    第一個塊地址爲    0.    通常來講,    BlockNum    與    CHS    地址的關係   
   是:   
           BlockNum    =    cylinder    *    NumberOfHeads    +   
                                 head    *    SectorsPerTrack    +   
                                 sector    -    1;   
    
           其中    cylinder,    head,    sector    是    CHS    地址,    NumberOfHeads    是磁盤   
   的磁頭數,    SectorsPerTrack    是磁盤每磁道的扇區數.   
           也就是說    BlockNum    是沿着    扇區->磁道->柱面    的順序記數的.    這一順   
   序是由磁盤控制器虛擬的,    磁盤表面數據塊的實際排列順序可能與此不一樣   
   (如爲了提升磁盤速度而設置的間隔因子將會打亂扇區的排列順序).   
    
   3.    驅動器參數數據包    Drive    Parameters    Packet   
         驅動器參數數據包是在擴展    Int13H    的取得驅動器參數子功能調用中   
   使用的數據包.    格式以下:   
           struct    DriveParametersPacket   
           {   
                   WORD    InfoSize;                      //    數據包尺寸    (26    字節)   
                   WORD    Flags;                            //    信息標誌   
                   DWORD    Cylinders;                  //    磁盤柱面數   
                   DWORD    Heads;                          //    磁盤磁頭數   
                   DWORD    SectorsPerTrack;      //    每磁道扇區數   
                   QWORD    Sectors;                      //    磁盤總扇區數   
                   WORD    SectorSize;                  //    扇區尺寸    (以字節爲單位)   
           };   
           信息標誌用於返回磁盤的附加信息,    每一位的定義以下:   
    
           0    位:   
                   0    =    可能發生    DMA    邊界錯誤   
                   1    =    DMA    邊界錯誤將被透明處理   
                   若是這位置    1,    表示    BIOS    將自動處理    DMA    邊界錯誤,    也就是說   
                   錯誤代碼    09H    永遠也不會出現.   
    
           1    位:   
                   0    =    未提供    CHS    信息   
                   1    =    CHS    信息合法   
                   若是塊設備的傳統    CHS    幾何信息不適當的話,    該位將置    0.   
    
           2    位:   
                   0    =    驅動器不可移動   
                   1    =    驅動器可移動   
    
           3    位:    表示該驅動器是否支持寫入時校驗.   
    
           4    位:   
                   0    =    驅動器不具有介質更換檢測線   
                   1    =    驅動器具有介質更換檢測線   
    
           5    位:   
                   0    =    驅動器不可鎖定   
                   1    =    驅動器能夠鎖定   
                   要存取驅動器號大於    0x80    的可移動驅動器,    該位必須置    1   
                   (某些驅動器號爲    0    到    0x7F    的設備也須要置位)   
           6    位:   
                   0    =    CHS    值是當前存儲介質的值    (僅對於可移動介質),    若是   
                   驅動器中有存儲介質,    CHS    值將被返回.   
                   1    =    CHS    值是驅動器支持的最大值    (此時驅動器中沒有介質).   
    
           7    -    15    位:    保留,    必須置    0.   數據結構

轉自:http://hi.baidu.com/xlrzxzl/item/6202c73fe141f7637d034befspa

 

三.    接口規範   
    
   1.    寄存器約定   
           在擴展    Int13H    調用中通常使用以下寄存器約定:   
    
           ds:di    ==>    磁盤地址數據包(    disk    address    packet    )   
           dl          ==>    驅動器號   
           ah          ==>    功能代碼    /    返回碼   
    
           在基本    Int13H    調用中,    0    -    0x7F    之間的驅動器號表明可移動驅動器   
   0x80    -    0xFF    之間的驅動器號表明固定驅動器.    但在擴展    Int13H    調用中   
   0x80    -    0xFF    之間還包括一些新出現的可移動驅動器,    好比活動硬盤等.   
   這些驅動器支持先進的鎖定,解鎖等功能.   
           ah    返回的錯誤碼除了標準    Int13H    調用規定的基本錯誤碼之外,又增長   
   瞭如下錯誤碼:   
    
         B0h        驅動器中的介質未被鎖定   
    
         B1h        驅動器中的介質已經鎖定   
    
         B2h        介質是可移動的   
    
         B3h        介質正在被使用   
    
         B4h        鎖定記數溢出   
    
         B5h        合法的彈出請求失敗   
    
   2.    API    子集介紹   
         1.x    版的擴展    Int13H    調用中規定了兩個主要的    API    子集.   
    
         第一個子集提供了訪問大硬盤所必須的功能,    包括    檢查擴展    In13H   
   是否存在(    41h    ),    擴展讀(    42h    ),    擴展寫(    43h    ),    校驗扇區(    44h    ),   
   擴展定位(    47h    )    和    取得驅動器參數(    48h    ).   
         第二個子集提供了對軟件控制驅動器鎖定和彈出的支持,    包括    檢查擴展   
   Int13H    是否存在(    41h    ),    鎖定/解鎖驅動器(    45h    ),    彈出驅動器(    46h    ),   
   取得驅動器參數(    48h    ),    取得擴展驅動器改變狀態(    49h    ),    int    15h.   
         若是使用了調用規範中不支持的功能,    BIOS    將返回錯誤碼    ah    =    01h,   
   CF    =    1.   
    
   3.    API    詳解   
    
   1)    檢驗擴展功能是否存在   
   入口:   
           AH    =    41h   
           BX    =    55AAh   
           DL    =    驅動器號   
    
   返回:   
           CF    =    0   
                 AH    =    擴展功能的主版本號   
                 AL    =    內部使用   
                 BX    =    AA55h   
                 CX    =    API    子集支持位圖   
           CF    =    1   
                 AH    =    錯誤碼    01h,    無效命令   
    
           這個調用檢驗對特定的驅動器是否存在擴展功能.    若是進位標誌置    1   
   則此驅動器不支持擴展功能.    若是進位標誌爲    0,    同時    BX    =    AA55h,    則   
   存在擴展功能.    此時    CX    的    0    位表示是否支持第一個子集,    1位表示是否   
   支持第二個子集.   
           對於    1.x    版的擴展    Int13H    來講,    主版本號    AH    =    1.    AL    是副版本號,   
   但這僅限於    BIOS    內部使用,    任何軟件不得檢查    AL    的值.   
    
   2)    擴展讀   
   入口:   
           AH    =    42h   
           DL    =    驅動器號   
           DS:DI    =    磁盤地址數據包(Disk    Address    Packet)   
    
   返回:   
           CF    =    0,    AH    =    0    成功   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用將磁盤上的數據讀入內存.    若是出現錯誤,    DAP    的    BlockCount   
   項中則記錄了出錯前實際讀取的數據塊個數.   
    
   3)    擴展寫   
   入口:   
           AH    =    43h   
           AL   
                 0    位    =    0    關閉寫校驗   
                               1    打開寫校驗   
                 1    -    7    位保留,    置    0   
           DL    =    驅動器號   
           DS:DI    =    磁盤地址數據包(DAP)   
   返回:   
           CF    =    0,    AH    =    0    成功   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用將內存中的數據寫入磁盤.    若是打開了寫校驗選項,    但    BIOS   
   不支持,    則會返回錯誤碼    AH    =    01h,    CF    =    1.    功能    48h    能夠檢測BIOS是否   
   支持寫校驗.   
           若是出現錯誤,    DAP    的    BlockCount    項中則記錄了出錯前實際寫入的數   
   據塊個數.   
    
   4)    校驗扇區   
   入口:   
           AH    =    44h   
           DL    =    驅動器號   
           DS:DI    =    磁盤地址數據包(Disk    Address    Packet)   
    
   返回:   
           CF    =    0,    AH    =    0    成功   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用校驗磁盤數據,    但並不將數據讀入內存.若是出現錯誤,    DAP    的   
   BlockCount    項中則記錄了出錯前實際校驗的數據塊個數.  

    
   5)    鎖定/解鎖驅動器   
   入口:   
           AH    =    45h   
           AL   
                   =    0    鎖定驅動器   
                   =    1    驅動器解鎖   
                   =    02    返回鎖定/解鎖狀態   
                   =    03h-FFh    -    保留   
           DL    =    驅動器號   
    
   返回:   
           CF    =    0,    AH    =    0    成功   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用用來縮定指定驅動器中的介質.   
           全部標號大於等於    0x80    的可移動驅動器必須支持這個功能.    若是   
   在支持可移動驅動器控制功能子集的固定驅動器上使用這個功能調用,    將   
   會成功返回.   
           驅動器必須支持最大255次鎖定,    在全部鎖定被解鎖以前,    不能在物理上   
   將驅動器解鎖.    解鎖一個未鎖定的驅動器,將返回錯誤碼    AH=    B0h.    若是鎖定一   
   個已鎖定了255次的驅動器,    將返回錯誤碼    AH    =    B4h.   
           鎖定一個沒有介質的驅動器是合法的.   
    
   6)    彈出可移動驅動器中的介質   
   入口:   
           AH    =    46h   
           AL    =    0    保留   
           DL    =    驅動器號   
    
   返回:   
           CF    =    0,    AH    =    0    成功   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用用來彈出指定的可移動驅動器中的介質.   
           全部標號大於等於    0x80    的可移動驅動器必須支持這個功能.    若是   
   在支持可移動驅動器控制功能子集的固定驅動器上使用這個功能調用,    將   
   會返回錯誤碼    AH    =    B2h    (介質不可移動).    若是試圖彈出一個被鎖定的介質   
   將返回錯誤碼    AH    =    B1h    (介質被鎖定).   
           若是試圖彈出一個沒有介質的驅動器,    則返回錯誤碼    Ah    =    31h    (驅動器   
   中沒有介質).   
           若是試圖彈出一個未鎖定的可移動驅動器中的介質,    Int13h會調用    Int15h   
   (AH    =    52h)    來檢查彈出請求可否執行.    若是彈出請求被拒絕則返回錯誤碼(同   
   Int15h).    若是彈出請求被接受,但出現了其餘錯誤,    則返回錯誤碼    AH    =    B5h.   
    
   7)    擴展定位   
   入口:   
           AH    =    47h   
           DL    =    驅動器號   
           DS:DI    =    磁盤地址數據包(Disk    Address    Packet)   
    
   返回:   
           CF    =    0,    AH    =    0    成功   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用將磁頭定位到指定扇區.   
    
   8)    取得驅動器參數   
   入口:   
           AH    =    48h   
           DL    =    驅動器號   
           DS:DI    =    返回數據緩衝區地址   
    
   返回:   
           CF    =    0,    AH    =    0    成功   
                   DS:DI    驅動器參數數據包地址,    (參見前面的文章)   
           CF    =    1,    AH    =    錯誤碼   
    
           這個調用返回指定驅動器的參數.   
    
   9)    取得擴展驅動器介質更換檢測線狀態   
   入口:   
           AH    =    49h   
           DL    =    驅動器號   
    
   返回:   
           CF    =    0,    AH    =    0      介質未更換   
           CF    =    1,    AH    =    06h    介質可能已更換   
    
           這個調用返回指定驅動器的介質更換狀態.   
           這個調用與    Int13h    AH    =    16h    子功能調用相同,    只是容許任何驅動器   
   標號.    若是對一臺支持可移動介質功能子集的固定驅動器使用此功能,則永遠   
   返回    CF    =    0,    AH    =    0.   
           簡單地將可移動介質鎖定再解鎖就能夠激活檢測線,    而無須真正更換介質.   
    
   10)    Int    15h    可移動介質彈出支持   
   入口:   
           AH    =    52h   
           DL    =    驅動器號   
   返回:   
           CF    =    0,    AH    =    0    彈出請求可能能夠執行   
           CF    =    1,    AH    =    錯誤碼    B1h    或    B3h      彈出請求不能執行   
    
           這個調用是由    Int13h    AH=46h    彈出介質功能調用內部使用的.  翻譯

相關文章
相關標籤/搜索