2007-3-11 19:11:00 cpu執(zhí)行第一條指令時(shí)情形
系統(tǒng)
1822 0
cpu執(zhí)行的第一條指令不在內(nèi)存中,眾所周知,內(nèi)存是由ram組成的 ,而ram不斷電,可以保存信息,一旦斷電,ram中的信息將會(huì)丟失,所以cpu要執(zhí)行的第一條指令被固化在rom中
以前8086年代,由于內(nèi)存是1M的,所以rom被編址在1M的最后的64K中,所以它的段地址是0xFFFF0,這樣就不至于不ram分成兩個(gè)部分,就是將cs設(shè)置成0XF000,cpu執(zhí)行的BIOS第一條指令的地址是:0XF000:FFF0H,這樣使得固件的地址在尋址空間靠后的位置16個(gè)字節(jié)處,這是一條跳轉(zhuǎn)指令,向前調(diào)轉(zhuǎn)到一個(gè)地方,然后開始執(zhí)行,
啟動(dòng)代碼由
jmp F000 : XXXX
中的偏移
XXXX
來把握,如果使用得多,
XXXX
就小,使用得少,
XXXX
就大,這樣使啟動(dòng)代碼盡量靠后,而不浪費(fèi)多余的地址空間,由于地址空間安排在最后,也不會(huì)把整個(gè)地址空間隔離成兩段。
而出現(xiàn)80386以后,內(nèi)存已經(jīng)大于1M,所以
如果把冷啟動(dòng)固件編址在
F000h
段內(nèi),就會(huì)把整個(gè)地址空間隔離成不連續(xù)的兩段,一段是
F000h
以前的地址,一段是
1M
以后的地址,這很不方便。
intel
采用的辦法是,還是默認(rèn)將執(zhí)行啟動(dòng)代碼的
BIOS ROM
編址在系統(tǒng)可尋址空間的最后(如
32
位
x86
機(jī)的話,這段地址就位于
4GB
的最后一個(gè)
64K
內(nèi)),在系統(tǒng)復(fù)位時(shí),
CPU
進(jìn)入實(shí)模式,并將
CS
寄存器設(shè)置成
F000h
,而將它的
shadow register
的
Base
設(shè)置成
FFFF0000h
(理論上正常情況下
CS
為
F000h
的話,其
shadow register
的
Base
應(yīng)該設(shè)置成
000F
0000h
,但
intel
有意識(shí)的將高
12
位觸發(fā)成
1
了,除了這樣他也沒有什么好辦法讓機(jī)器一啟動(dòng)就跑道
4GB
那么高的地址上去執(zhí)行),而偏移量
EIP
置成
0000FFF0h
,所以機(jī)器執(zhí)行的第一條指令的固件安排的物理地址顯然就變成了
FFFFFFF0h
。
BIOS
代碼和以前還是要兼容的,也就是說此時(shí)從
FFFFFFF0h
處取出的還是一條遠(yuǎn)跳轉(zhuǎn)指令
jmp F000 : XXXX
(我跟蹤調(diào)試過好幾款
BIOS
,這里的
XXXX
似乎都是
E05B
),問題隨之而來。這個(gè)遠(yuǎn)跳轉(zhuǎn)指令是要更新
CS
寄存器和它的
shadow register
的,也就是說執(zhí)行這條
jmp F000 : E05B
之后(也就是
CPU
執(zhí)行第一條指令之后),
CS
將被更新成
F000
,其實(shí)
CS
原來就是這個(gè)值,這里說不上是更新,但
CS
的
shadow register
就不一樣了,它被真正的更新了,它的
Base
域被更新成
000F
0000h
了(高
12
不再具有觸發(fā)成
1
的功能,那個(gè)功能只在機(jī)器啟動(dòng)到第一次更新
CS
的內(nèi)容期間有效)。這個(gè)
Base
再加上虛擬地址中的偏移量
E05B
,得到物理地址
000FE05Bh
,這就是
CPU
執(zhí)行的第二條指令的地址,但是這條指令的地址已經(jīng)是
1M
以內(nèi)了。但我們不要忘記,這時(shí)的
F000h
段內(nèi)可不再是
BIOS ROM
了,這一段此時(shí)安排的事實(shí)上是我們的
RAM
空間,這一段
RAM
需不需要初始化才能使用那還另說,關(guān)鍵是此時(shí)此刻這個(gè)地方不應(yīng)該有可以執(zhí)行的代碼才對(duì)啊?
CPU
第二條指令就跳到這里不是自尋死路嗎
?
似乎走進(jìn)了死胡同,但我翻閱了很多資料,找到了一點(diǎn)線索。在很久以前出現(xiàn)過一個(gè)叫著
Chips & Technoloqies
的公司,他設(shè)計(jì)出一組被稱著
neat
的芯片組,
可以將內(nèi)存高端的
BIOS ROM
映射到
1M
以內(nèi)的
RAM
空間里
,
并且可以使這一段被映射的
RAM
空間具有與
ROM
類似的只讀屬性。
這個(gè)公司后來被
intel
收購(gòu)。但后來這種映射似乎就成為了一種標(biāo)準(zhǔn)。由于這種映射關(guān)系我們有理由相信,機(jī)器啟動(dòng)的時(shí)候,
4G
的最后一個(gè)
64K
里與
1M
的最后一個(gè)
64K
里應(yīng)該具有相同的東西,
所以即使從
FFFFFFF0h
用一條
jmp
跳到
000FE05Bh
,也仍然能夠找到正確的代碼去執(zhí)行。
那么
BIOS
接下來要干一些什么事呢?它有很多事情要做,我只舉幾件有代表性的,其中有兩件事是
DRAM
的初始化和
memory sizing
。按理說這個(gè)時(shí)候
CPU
還處在實(shí)模式下,
BIOS
還沒有辦法去確定超過
1M
的內(nèi)存量。另外還有一件事就是代碼和數(shù)據(jù)拷貝,因?yàn)橛成涞?
1M
以內(nèi)來的
BIOS ROM
容量有限,事實(shí)上還有很大一部分沒有映射過來,以壓縮的形式存放在高端的
ROM
中了,
BIOS
在
1M
以內(nèi)執(zhí)行初始化時(shí)難免需要將高端的那些內(nèi)容拷過來使用,這也是不容易做到的。但不要忘了,我們可以使用前面說的將段
break
成
4G
的方法來做成這幾件事。當(dāng)然,似乎還存在著這樣一種可能性,那就是
切換到保護(hù)模式
,這些事情就都可以做了,并且好像沒有必要再切換回實(shí)模式。情況沒有想象中那么簡(jiǎn)單,從我前面的那個(gè)實(shí)驗(yàn)看,我切換到保護(hù)模式之后只執(zhí)行了幾行非常必要的將段
break
成
4G
的代碼,其他的事情一律不做,因?yàn)楸Wo(hù)模式下有非常嚴(yán)格的特權(quán)檢查,并且需要設(shè)置
GDT
,
IDT
,
LDT
等一系列的表格,一般的代碼是不容易在保護(hù)模式下跑起來的,所以想在保護(hù)模式下完成整個(gè)
BIOS
的初始化,工程過于浩大,幾乎等于寫一套小型的保護(hù)模式操作系統(tǒng)了(
FreeBios
可能就是這么干的)。
當(dāng)然我也有足夠多的證據(jù)證明我們常用的
BIOS
都使用了這種
break limit
的技術(shù),并且它們完成
break
后都是迅速切換回實(shí)模式
。
---------------------------------------------
參考了
X86 CPU在段式管理下的地址形成機(jī)制以及BIOS初始化過程對(duì)這種機(jī)制的利用
陳英豪
?
中科院計(jì)算所
2007-3-11 19:11:00 cpu執(zhí)行第一條指令時(shí)情形
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元