x86
架構計算機是如何啓動的?
16-bit Processors and Segmentation (1978)
The IA-32 architecture family was preceded by
16-bit processors
, the 8086 and 8088. The 8086 has16-bit registers
and a16-bit external data bus
, with20-bit addressing giving a 1-MByte address space
. The 8088 is similar to the 8086 except it has an 8-bit external data bus.> The 8086/8088 introducedsegmentation
to the IA-32 architecture. With segmentation, a16-bit segment register
contains a pointer toa memory segment of up to 64 KBytes
. Usingfour
segment registers at a time, 8086/8088 processors are able to address up to 256 KByteswithout
switching between segments. The 20-bit addresses that can be formed using a segment register and an additional 16-bit pointer provide a total address range of 1 MByte.
8086 是整個 intel 系列處理器的老祖宗。所有後續的一系列處理器都兼容 8086。唉,這就是路徑依賴啊。這是一個 16-bit 的處理器。寄存器也是 16-bit 的。but 卻能尋址 20-bit 的地址空間,也就是 1M 的內存。怎樣在 16-bit 的處理器上實現呢?很簡單,將 1M 的空間分成多個 64K 的 segment。那怎樣用 16-bit 的寄存器表示 20-bit 的地址呢?也很簡單,用 2 個 16-bit 的寄存器組合得來的(register1,register2)。那怎樣組合的呢?address = register1 << 4 + register2
。將 register1 << 4 和 register2 用一個 20-bit 的加法器就能得到內存地址。這種方式就是所謂的 real address mode
。也即是拿到的是真正的內存地址。x86 架構的計算機啓動時會先進入 real address mode。
計算機啓動前置知識
- CPU 工作方式是: 從
內存
中取指、執行。 - 內存是存儲數據的地方,給出一個內存地址,可以得到該處的數據。
- CPU 從內存哪裏取指令,由
instruction pointer
這個寄存器的值決定。這個值不斷 +1,或者跳轉(jump) 到某處。real address mode 下由 CS:IP 組合決定。
BIOS
BIOS 是啥
BIOS
是啥呢?一個軟件而已。不像我們平時在 PC 上使用如 QQ
等軟件是安裝在硬盤上的。BIOS 安裝在 ROM 中。這個軟件幹啥的呢?幫助計算機啓動,開機時檢測整個機器的硬件。計算機啓動需要運行軟件,軟件運行需要計算機先啓動。咳咳,成了先有雞還是先有蛋了,這怎麼行?所以需要 BIOS 這個在硬件上的軟件來幫助,破除這種依賴。
BIOS 大小
通過 dmidecode
這個命令來查看。也就是讀取 BIOS 的信息。
root@aliyun:~# dmidecode -t bios -q # 方法一
BIOS Information
Vendor: SeaBIOS
Version: 8c24b4c
Release Date: 04/01/2014
Address: 0xE8000
Runtime Size: 96 kB
ROM Size: 64 kB --- ROM Size,在此可以看到,BIOS 大小爲 64K。
Characteristics:
BIOS characteristics not supported
Targeted content distribution is supported
BIOS Revision: 0.0
root@aliyun:~# cd /sys/class/dmi/id/ # 方法二
root@aliyun:id# ls
bios_date chassis_serial modalias product_serial sys_vendor
bios_vendor chassis_type power product_uuid uevent
bios_version chassis_vendor product_family product_version
chassis_asset_tag chassis_version product_name subsystem
x86 架構計算機啓動流程
- 如上圖所示,當按下
power on
之後,此時的 CPU 處於 real address mode。由硬件負責將BIOS 64K
的內容加載到0xF0000 到 0xFFFFF
(64K 內存)。並將CS(code segment) 置爲 0xF000
,IP(instruction pointer) 置爲 0xFFF0
。組合起來的內存地址PC
就是 0xFFFF0。 - 此時 CPU 從
PC = 0xFFFF0
處開始取指、執行。那麼從0xFFFF0 到 0xFFFFF
只有 16Bytes。空間太小了,能放啥呢?但是可以跳到其他地方去執行啊。不錯,這裏存放的有一條指令是jmp far f000:e05b
, 組合起來就是0xfe05b
。注意這個地址可是在0xF0000 到 0xFFFFF
範圍之內,也就是這條指令跳轉到BIOS 內部的代碼
去執行。從 0xFE05B 到 0xFFFF0 將近 8K 內存,代碼不少。 - 此時 CPU 從
PC = 0xfe05b
開始取值、執行。具體幹啥呢?就是執行所謂的開機自檢。檢查計算機硬件。同時去找啓動扇區,那什麼纔是啓動扇區呢?若 0 盤 0 道 1 扇區最後兩個字節分別是 0x55,0xaa,那就是啓動區。很像 java class 文件中的魔數,就是標記一下。同時將找到的啓動扇區(512Bytes) 複製到內存0x7C00 到 0x7DFF
(512Bytes) 處。最後會將CS 置爲 0x0000, IP 置爲 0x7C00
,組合起來就是0x7C00
。 - 此時 CPU 從
PC = 0x7C00
開始取值、執行。具體幹啥呢?這就是開發人員可以決定的了。在啓動扇區上可以是加載 OS Kernel 的代碼,硬盤分區,boot loader 等。
References
1.x86-ORG
2. how-to-see-rom-size
3. bios-info-dmidecode
4. system-management-bios
5. 計算機是如何啓動的?
6.多種 MBR 組織方式
7. 計算機是怎樣啓動的?