從扇區看USB-FDD和USB-HDD在引導時的區別
這個問題其實大家在平時是不會注意到的,我也是因為最近在PC機上寫系統載入程式的時候,才注意到的。
起因是這樣的,我在bochs虛擬機器裡寫了個載入程式,想移植到物理機上,大家都懂的,虛擬機器是支援軟碟機的,操作簡單方便,而且還可以建立虛擬軟盤,在系統啟動的時候,可以通過BIOS中斷呼叫,寫入映象也很方便。但是,問題來了!現在已經很難搞到軟碟機了和軟盤了,所以,最好的解決辦法就是用U盤代替軟盤,而且,大家現在也都這麼幹。於是乎,我就去網上找了找關於U盤啟動相關的資料。本來以為沒什麼,就沒把它當回事,可是,百度查出來的結果很不樂觀,第一頁一堆U盤引導助手什麼的,顯然不是我們們要的東西,不過倒是可以強讀MBR,把引導扇區的資料讀出來,然後反彙編,就能看出來了,但是,貌似比較耗時、費力,而且結果也不一定讓人滿意。那麼,下一步該怎麼辦呢?
還是從原點出發吧!因為在BIOS的配置選項裡面有啟動項的設定,這個大家都是知道的。等我進入到BIOS啟動項配置介面的時候,困惑就出來了,到底該用那麼模式?什麼是USB-FDD?什麼是USB-HDD?
經過一番簡單的調查以後,原來USB-FDD是模擬軟盤模式,一般的軟盤都可以用這個模式來啟動;USB-HDD是硬碟模式,像行動硬碟什麼的都可以用這種方式啟動;
知道了這些,下面就該為U盤選取轉化模式了。我用的磁碟管理軟體是DiskGenius,這個小巧易用,如果大家手頭有別的軟體也可以。然後找了一個16MB大小的U盤,這個淘寶都可以買到,也就幾塊錢。下面先把U盤裡扇區的資料全部清空。大家一定要注意,不要光格式化U盤,因為這樣的話U盤裡的檔案系統是清空的,但是扇區裡還是會殘留髒資料的,這個原因如果你看過檔案系統是如何操作的,那麼你就會理解其中的緣由了,所以,這就是為什麼誤刪除的檔案還可以找回來的原因。
清理完U盤裡的資料後,該選擇啟動模式了,先選USB-FDD模式吧,感覺軟盤模式會簡單一些。
要注意把更改驅動器號、掃描壞扇區、建立DOS系統幾個選項勾選掉,這樣才能保證扇區裡是一個乾淨的檔案系統。
至於為什麼要格式化成FAT12呢?是因為它的結構比較簡單,大致可以一目瞭然。點選轉換,完成對U盤的設定及檔案系統的格式化。
接下來我們看看U盤MBR(引導扇區)裡的資料:
如果你瞭解引導扇區的結構,那麼只要仔細觀察可以看出,這個引導扇區記錄和軟盤的沒有什麼區別。如果不瞭解的話,那麼也沒關係,其實裡面並不複雜,它由兩部分構成:主開機記錄、55AA結束標誌符。讀者可以很清楚的看到在0x36地址處的字串“FAT12”和附近的一些亂碼是這個檔案系統的結構,如果有興趣的讀者可以到網上查一查FAT12檔案系統的各項欄位。值得注意的是:FAT12檔案系統的開始位置一般不是從MBR 的0x36或者0x00處開始的,而是從0x03開始的,這點在讀者自己學習的時候要注意,不然得到的結果就會和你已經格式化了的檔案系統不一致。
對於瞭解磁碟結構的同學們,大家都知道軟盤和硬碟都是有扇區、磁頭、磁軌的,但是在U盤裡沒有這個概念,不過呢,我在DiskGenius軟體裡還是獲得了相關的資訊,詳見下圖所示:
大家可以清楚的看到,這個U盤容量16MB,2個柱面,255個磁頭,每磁軌63個扇區,總扇區數:32768。但是大家千萬要注意,這裡的資料應該是DiskGenius這個軟體自己模擬的,我在寫載入程式的時候,用int13 AH=2 以CHS(cylinders-heads-sectors,磁柱-磁頭-扇區)定址模式讀取U盤扇區的資料是無效的,或者讀出來的資料和扇區對應不上;對於出現這種問題,將在本文的後面介紹,請大家稍安勿躁。
再來看看USB-HDD模式,這個是硬碟的啟動模式。同樣,為了看清扇區內容,我們還是要先清空扇區裡的資料。然後選擇製作USB-HDD啟動盤,並且建立可引導分割槽。使用預設的配置就可以了,作者這裡的預設配置如下:
我們還是使用的FAT12檔案系統。在完成格式化以後,讓我們還是來看看MBR(引導扇區)裡面的資料吧,詳見下圖所示:
如果瞭解引導扇區結構的朋友肯定能明白,其實硬碟的引導扇區和軟盤的引導扇區還是有一定區別的;如前面提到的,軟盤的引導扇區包括:引導程式碼和55AA結束符兩部分,加在一起是512B位元組;而硬碟的引導扇區包括:引導程式碼、硬碟分割槽表、55AA結束符三部分組成;把引導扇區分成三段:0~0x1BD是引導程式碼,0x1BE~0x1FD是硬碟分割槽表,一共四項每項16個位元組,最後兩個位元組是55AA結束符。
在這裡是80h,01h,01h,00h,01h,feh,3fh,01h,3fh,00h,00h,00h,43h,7dh,00h,00h看來只有一個硬碟分割槽,其他的硬碟分割槽表內容全部都是0x00,正好我們剛才只建立了一個硬碟分割槽,那麼這16個位元組都是代表什麼意思呢?請參見下表:
位元組位移 | 欄位長度 | 值 | 欄位名和定義 |
---|---|---|---|
0 | 1Byte | 80h | 引導指示符,制定該分割槽是否是活動分割槽 |
1 | 1Byte | 01h | 開始磁頭 |
2 | 2Byte | 0001h | 開始扇區和柱面 |
4 | 1Byte | 01h | 系統ID,定義了分割槽的型別 |
5 | 1Byte | FEh | 結束磁頭 |
6 | 2Byte | 013Fh | 結束扇區和柱面 |
8 | 4Byte | 0000,003Fh | 相對扇區數,從該磁碟的開始到該分割槽的開始的位移量,以扇區來計算 |
12 | 4Byte | 0000,7D43h | 總扇區數,該分割槽中的扇區總數 |
可以與下圖U盤的引數做一下簡單的對照,
0000,003Fh的十進位制表示就是63,0000,7D43h的十進位制表示就是32067,與起始扇區號63、總扇區數32067是一致的,至於系統ID嘛,這個算是固定的,01代表的是FAT12,05代表的是擴充套件分割槽表,linux的檔案系統是83等等,這裡就不多介紹了。
再讓我們跳轉到3fh扇區去看看,哪裡的內容是什麼吧!
我想聰明的你已經發現了,在0x7E36處也是FAT12檔案系統標示符,看來我們格式化的檔案系統在這裡,而不是在MBR裡,這就是硬碟分割槽表的功能,如果我們把一塊硬碟只給一個系統或者分割槽使用,對於今天的我們,未免容量有些大,使用硬碟分割槽表可以把硬碟分解成4個主邏輯分割槽。在主邏輯分割槽內可以在定義擴充套件分割槽表,主分割槽再細分為若干個邏輯擴充套件分割槽(就是系統ID:05),這回看來跟硬碟上的結構沒有什麼區別了。
介紹了這麼多,下面該解決前文留下的那個問題了,對於那些假的扇區、磁頭、磁軌引數我們該怎麼辦呢?
其實BIOS早就為我們解決了這個問題,對於正常的讀扇區操作,使用BIOS的INT 13h AH = 02h中斷即可,其中AL=要讀扇區數,CH=柱面(磁軌)號,CL=起始扇區號,DH=磁頭號,DL=驅動器號(軟碟機從0開始,0:軟碟機A,1:軟碟機B;硬碟從80h開始,80h:硬碟C,81h:硬碟D)。這裡在多講一句,BIOS通過設定實現軟碟機引導,當我們的載入程式被執行的時候,那麼我們的程式碼所在的軟碟機就是軟碟機A,所以程式碼的DL暫存器賦值0就可以,不必糾結那個軟碟機是A,那個軟碟機是B。硬碟也是一樣,設定成80h即可,等到系統核心執行起來以後,磁碟的驅動程式會重新為磁碟分配磁碟裝置序列號。這種模式就是傳統的CHS(cylinders-heads-sectors,磁柱-磁頭-扇區)定址模式,根據相應的設定定位到具體的讀取扇區上。對於傳統的分扇區、磁頭、磁軌的磁碟裝置這種操作方式沒有問題,但是像U盤或者固態硬碟等沒有扇區、磁頭、磁軌的裝置我們該如何讀取扇區呢?
對於這些不分扇區、磁頭、磁軌的裝置,BIOS使用了一種新型的讀寫方式——LBA(Logical Block Address) ,中文名稱:邏輯區塊地址。這種方式可以直接使用順序的扇區號,而不用再進行磁頭,磁軌,扇區的轉換了。因此BIOS的INT 13h AH = 42h中斷實現了讀扇區的擴充套件,其中DL=驅動器號,這個和INT 13h AH = 02h中斷的DL暫存器一樣,而DS:SI指向的是一個叫做disk address packet(硬碟地址包)的結構,它的格式如下表:
Offset | Size | Description |
---|---|---|
00h | Byte | Size of packet(10h or 18h) |
01h | Byte | Reserved(0) |
02h | Word | Number of blocks to transfor(max 007fh for phoenix EDD) |
04h | DWord | Transfer buffer |
08h | QWord | Starting absolute block number |
10h | QWord | 64-bit flat address of transfer buffer(used if DWord at 04h is FFFF:FFFFh) |
這個結構有16位元組和24位元組兩種,根據使用者需要讀取的地址長度而決定,作者目前使用的是在真實模式下定址4GB空間並且使用16位元組的LBA定址結構,通過BIOS的INT 13h AH = 42h中斷讀取扇區內容,可以使程式正常執行,並且獲得正確的結果。
希望這篇文章能給你在編寫載入程式方面提供一些幫助。
相關文章
- FreeFlyOS【一】:boot部分(引導扇區)詳解boot
- 寫作業系統之開發引導扇區作業系統
- 從賦值看基本型別和引用型別的區別賦值型別
- RGB風扇和ARGB風扇有哪些不同?電腦RGB風扇和ARGB風扇的區別介紹
- 從原始碼看String,StringBuffer,StringBuilder的區別原始碼UI
- [面試專題]從for迴圈看let和var的區別面試
- 從2張執行流程圖看vue和react區別流程圖VueReact
- Oracle中單引號和雙引號的區別Oracle
- viewflow在html和body的區別ViewHTML
- 散熱風扇介面針數的區別:2針、3針、4針介面的散熱風扇有區別?
- CST和GMT時間的區別
- mysql主從和主備的區別MySql
- 堆和棧在物理上的區別
- 在xpath中text()和string(.)的區別
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- http和https的區別/get和post的區別HTTP
- ../和./和/的區別
- ||和??的區別
- /*和/**的區別
- 物件導向和麵向過程的區別物件
- 在 JavaScript 中,exec() 和 match() 區別JavaScript
- 介面和列舉在方法中的區別
- NULL在oracle和mysql索引上的區別NullOracleMySql索引
- 串列埠SRAM和並口SRAM的引腳區別串列埠
- subprocess中命令為引數序列和字串的區別字串
- 引數為*&與*的區別以及二維陣列傳遞時列數不對等的區別陣列
- jquery $(this) 和this的區別jQuery
- JQuery this和$(this)的區別jQuery
- T和?的區別
- makefile =和:=的區別
- ++a和a++的區別
- ./ 和sh 的區別
- 和區別
- 在Pandas中 SQL操作:SQLAlchemy和PyMySQL的區別MySql
- Tomcat部署時war和war exploded區別Tomcat
- Tomcat 部署時 war 和 war exploded 區別Tomcat
- 遊戲分類學:從真三國無雙系列看RPG和ACT的核心區別遊戲
- 心得 : 物件導向和麵向過程的區別【分享】物件
- java中程序導向和麵向物件區別?Java物件