裝載著操作系統的磁碟是默認裝到內存0x8000位置,那ORG 0x7c00又是在做一個什麼事情呢?

最近在學習寫操作系統,在我想利用啟動區去啟動操作系統時,碰到了不理解的知識點。我們知道當磁碟開始運行時,是從啟動區開始執行,系統會默認把磁碟上的內容載入到內存0x8000的地址,但是啟動區又有一個規定,需要在程序前指定ORG 0x7c00,而這句指令的意思,是把程序載入到內存的制定位置,所以我不明白了?到底是讓程序放置到0x8000執行,還是0x7c00呢?


為嘛BIOS將MBR讀入0x7C00地址處(x86平台下)

對於很多人來講0x7C00這個地址是很神秘的,不知道這是幹什麼的。但是對於了解過x86平台下BIOS啟動過程的人,對這個地址再熟悉不過了。BIOS就是將MBR讀入0x7C00地址,然後進行後續的引導的。操作系統或是bootloader開發者必須假設 他們的彙編代碼被載入並從0x7C00處開始執行。

0x7C00的定義

對於這個地址,它不屬於Intel x86平台規範的,而是屬於BIOS規範中定義的內容。0x7C00第一次出現在IBM PC 5150的BIOS處理int 19(19號中斷)的時候,IBM PC 5150是x86(32位)IBM PC/AT系列的祖先,這款PC於1981年發布,使用了intel 8088(16位)的處理器和16KB的RAM內存,BIOS和微軟的基本指令均放在該內存中。

當打開電源,BIOS開始自檢,然後出發19號中斷,在處理19號中斷時,BIOS檢測電腦是否具有軟盤、硬碟或是固定磁碟,如果有任何可以使用的磁碟,BIOS酒吧磁碟的第一個扇區(512B)載入到內存的0x7C00地址處。

0x7C00的前身

0x7C00地址第一次出現在IBM PC 5150的ROM bios中,在此之前使用的地址是0x200。使用該地址的原因主要有:當時8086中斷向量使用地址為0x0-0x3FF;86-DOS從0x400處被載入;而它不使用0x200-0x3FF這段中斷向量地址。因此這段0x200-0x3FF地址不能被其他程序使用,Tim Paterson(86-DOS開發者)選擇0x200作為MBR載入地址。

0x7C00的意義

他們想留下32kb內更多的空間給操作系統來載入自己;8086/8088使用0x0-0x3FF作為中斷向量,然後BIOS數據緊隨之後;引導扇區是512位元組,但是用於引導程序的棧或數據區域需要多於512位元組;因此0x7C00,32kb中的最後1kb被選中。

一旦操作系統被引導並開始,引導扇區將一直不會被使用指導重啟,因此操作系統和應用程序可以自由的使用32KB的最後1kb空間。在操作系統被載入後,內存布局如下:

+——————— 0x0

| Interrupts vectors(中斷向量表)

+——————— 0x400

| BIOS data area(BIOS的數據區域)

+——————— 0x5??

| OS load area(操作系統載入區域)

+——————— 0x7C00

| Boot sector(引導區域)

+——————— 0x7E00

| Boot data/stack(引導數據/堆棧)

+——————— 0x7FFF

| (not used)

+——————— (…)

參考:

Why BIOS loads MBR into 0x7C00 in x86 ?


你弄錯了,BIOS就是把啟動扇區載入到0x7C00,不是0x8000.

說說為什麼會有0x8000這一說:是有些操作系統會把操作系統的代碼放到0x8000,這是因為BIOS讀完啟動扇區以後,會跳轉到0x7C00啟動,佔用0x7C00-0x7DFF這一段(512位元組),而一般bootloader還需要一個棧空間或者讀磁碟的交換空間,一般是放到0x7E00-0x7FFF這512位元組里,所以有些操作系統的鏡像起點是0x8000。

但是BIOS里讀取啟動扇區都是載入到0x7C00上的。


不到 0x8000 的位置呢,如果是 BIOS 的話,首先它要 Load 一部分內容到內存,包括 IVT 什麼的,然後進一步的要去載入 bootloader,bootloader 存在在 MBR 啟動扇區中,它需要被載入到 0x7C00。


不是, 0x7c00 裝載 bootloader,而 bootloader 讀入 os,但是並沒有特別的標準規定 os 應該放在哪裡,比如 xv6 放在 0x100000。


推薦閱讀:

linux內核啟動關於先有雞再有蛋的問題?
請問如何從下載的linux內核文件繼續編寫操作系統?
能敘述下面向對象思想在Linux內核編程中的應用嗎?
Linux操作系統關於C library的理解?
如何訪問linux內核,讀取所有進程的task_struct結構?/dev/mem?還是編寫驅動程序?

TAG:程序員 | 操作系統 | Linux內核 | 操作系統內核 | 操作系統開發 |