0x00:x86 架構 BIOS 引導加載程序中的"0x7C00"之謎
你知道 x86 操作系統中的"0x7C00"這個神奇數字嗎 ?
"0x7C00" 是BIOS加載MBR(主引導記錄,磁盤中的第一個扇區)的內存地址。操作系統或引導加載程序開發人員必須假設他們的匯編代碼已加載并從 0x7C00 開始。
但是...
第一,你可能很疑惑: "我讀了所有的Intel x86 手冊,但沒有找到神奇的數字0x7C00。"是的。0x7C00 與 x86 CPU 無關。很自然你在 intel 的cpu規格中查不到它。然后,你很想知道 "是誰確定這個數字的?"
第二,你可能很疑惑:"0x7C00 十進制數為 32KiB - 1024B。這個數字意味著什么?難道這只是巧合嗎?"
是誰決定了這個地址?并且,他為什么選擇這樣一個不著邊際的地址呢?現在,讓我們一起深入了解現代 x86 PC 的祖先"IBM PC 5150"的 BIOS 秘密!
0x01:"0x7C00"首先出現在IBM PC 5150中
縱觀x86 IBM兼容個人電腦的歷史,IBM PC 5150 是現代x86 IBM PC/AT 電腦的始祖。該電腦于 1981 年 8 月發布,配備 Intel 8088(16 位)和 16KiB RAM(最低內存型號), BIOS 和 Microsoft BASIC 存儲在 ROM 中。
當機器上電時,BIOS 執行 "POST"(開機自檢)程序,然后執行中斷調用 INT 19h。在中斷 INT 19h 處理程序中,BIOS 檢查 PC 是否有軟盤/硬盤/固定軟盤。如果有任何可用的磁盤,BIOS 將磁盤的第一個扇區(512B)加載到 0x7C00 中,并從這里開始啟動操作系統。
現在,你明白為什么在 x86 文檔中找不到這個神奇數字了吧。這個幻數屬于 BIOS 規范。
0x02:0x7C00的由來
圍繞 IBM DOS、微軟和SCP 86-DOS 這些科技公司,都是很有趣的故事。請參閱:MS-DOS 簡史(http://www.patersontech.com/dos/Byte/History.html)。
IBM?DOS 1.0 操作系統是參考的?SCP 的"86-DOS"(1980?年)。86-DOS(早期稱為QDOS)是8086/8088 cpu 的 CP/M 兼容操作系統。SCP出售兩塊 S-100總線板,一塊是8086 CPU板,另外一塊是"CPU Monitor" rom板。"CPU Monitor"程序提供了引導加載程序和調試器,這個"CPU Monitor"引導加載程序將 MBR 加載到"0x200",而不是"0x7C00"。?
1981 年,IBM DOS 是適用于 8086/8088 的下一代 CP/M 操作系統,"0x7C00 首次出現在 IBM PC 5150 ROM BIOS 中"。在這之前,SCP 的 CPU Monitor 引導加載程序加載到 0x200,而不是 0x7C00。
0x03:為什么早期的 CPU Monitor 的引導加載程序將 MBR 寫入"0x200"?
關于"0x200"有三個原因:
-
(1) 8086 中斷向量使用 0x0 - 0x3FF
-
(2) 86-DOS 是從0x400加載的
-
(3) 86-DOS 不使用 0x200 - 0x3FF 之間的中斷向量
這些原因意味著 0x200 - 0x3FF 保留空閑,并且86-DOS 或用戶應用程序想要加載到位置,不能妨礙操作系統,因此 Tim Paterson(86-DOS 開發人員)選擇 0x200 作為 MBR 加載地址。
0x04:"0x7C00" 又是誰決定的?
答案是:IBM PC 5150 BIOS 開發團隊。
"0x7C00 "是由 IBM PC 5150 BIOS 開發團隊(David Bradley 博士)決定的。如上所述,這個神奇的數字誕生于 1981 年,"IBM PC/AT Compat" PC/BIOS 供應商為了 BIOS 和操作系統的向后兼容性,從沒改變過這個值。
不是英特爾(8086/8088 供應商)或微軟(操作系統供應商)決定的。
0x05:"0x7C00 = 32KiB - 1024B"是什么意思?難道只是巧合嗎?
答案是:受操作系統要求和 CPU 內存布局影響。
IBM PC 5150 最小內存型號只有 16KB 內存。因此,你可能會有這樣的疑問:最小內存型號(16KiB)可以從軟盤加載操作系統嗎?BIOS 將 MBR 加載到 32KiB - 1024B 地址處,但物理內存顯然不夠。
不,這種情況不在考慮范圍之內。IBM PC 5150 ROM BIOS 開發團隊成員之一 David Bradley 博士說:"DOS1.0至少需要32KB,所以我們并不考慮在16KB內啟動。"
(注:DOS 1.0 最低要求 16KB 還是 32KB ?我找不到正確的答案。但至少在 1981 年的早期 BIOS 開發中,他們認為 32KB 是 DOS 的最低要求)。
BIOS 開發團隊決定使用 0x7C00 是因為:
-
(1) 他們希望在 32KiB 內為操作系統留下盡可能多的空間來加載自身。
-
(2) 8086/8088使用0x0 - 0x3FF作為中斷向量,BIOS數據區在其之后。
-
(3) 引導扇區為 512 字節,引導程序的堆棧/數據區域需要更多 512 字節。
-
(4) 因此,選擇了 0x7C00,即 32KiB 的最后 1024B。
一旦操作系統加載并啟動,引導扇區在電源重置之前不會被使用。因此,操作系統和應用程序可以自由使用 32KiB 的最后 1024B。
其內存布局如下所示:
+--------------------- 0x0
| Interrupts vectors
+--------------------- 0x400
| BIOS data area
+--------------------- 0x5??
| OS load area
+--------------------- 0x7C00
| Boot sector
+--------------------- 0x7E00
| Boot data/stack
+--------------------- 0x7FFF
| (not used)
+--------------------- (...)
參考:
https://www.glamenv-septzen.net/en/view/6