本文來(lái)自微信公眾號(hào):編程技術(shù)宇宙 (ID:xuanyuancoding),作者:軒轅之風(fēng) O
來(lái)電了
“來(lái)電了,來(lái)電了,起來(lái)干活了”,一大早,我還在睡夢(mèng)中就被吵醒了。
我是 CPU 一號(hào)車(chē)間的阿 Q,好久不見(jiàn),不知道大家有沒(méi)有想我呢?
“今天不是星期六嗎?怎么還要工作”,我有些不開(kāi)心,本以為能睡一個(gè)懶覺(jué),誰(shuí)知道大周末的程序員還開(kāi)機(jī),這是來(lái)加班了嗎。
一邊抱怨,一邊還得趕緊起來(lái)干活。
來(lái)到我所在的工作車(chē)間,提取指令的小 A、分析指令的小胖和負(fù)責(zé)結(jié)果回寫(xiě)的老 K 都已經(jīng)到了,就差執(zhí)行指令的我了。
我們幾個(gè)各就各位,做起了準(zhǔn)備工作。
“小 A,報(bào)告一下各個(gè)寄存器的值”,我囑咐小 A,這是我們每天開(kāi)始工作前必做的檢查項(xiàng)。
每次一通電,咱們的電路就會(huì)啟動(dòng)自檢工作,把所有的寄存器全部重置,如果哪里有異常的話(huà),就會(huì)把錯(cuò)誤記錄到 EAX 寄存器中,如果發(fā)現(xiàn) EAX 的值不是 0,那可就大事不好了。
“報(bào)告,寄存器已確認(rèn):”
EAX,EBX, ECX, ESI, EDI, EBP, ESP: 0x00000000
EFLAGS: 0x00000002
CS: 0xF000
EIP: 0xFFF0
······
看起來(lái)沒(méi)什么問(wèn)題,尤其是 CS 和 IP 這兩個(gè)寄存器,決定著一會(huì)兒該從哪里開(kāi)始執(zhí)行代碼呢。
我們是一個(gè) 64 位的 CPU,平時(shí)都是工作在保護(hù)模式下,使用虛擬地址來(lái)訪(fǎng)問(wèn)內(nèi)存,由廠里的內(nèi)存管理單元 MMU 負(fù)責(zé)給轉(zhuǎn)換成真實(shí)的物理地址。
不過(guò)在剛剛開(kāi)機(jī)的這會(huì)兒功夫,虛擬地址翻譯所需要的頁(yè)目錄、頁(yè)表這些信息都還沒(méi)準(zhǔn)備好,MMU 還沒(méi)法工作,這時(shí)候我們只能使用 16 位的寄存器,工作在實(shí)地址模式下,使用段 + 基址的方式來(lái)跟內(nèi)存打交道,最多只能使用 1MB 的內(nèi)存空間,實(shí)在是有點(diǎn)局促。
開(kāi)始執(zhí)行
“大家都準(zhǔn)備好了嗎,打起精神來(lái),要準(zhǔn)備開(kāi)始今天的工作了哦!”
“Q 哥,這剛剛通電,內(nèi)存條那家伙應(yīng)該還是一片空白吧,咱們要去執(zhí)行哪里的指令???”,小 A 問(wèn)到。
“這你不用擔(dān)心,在主板上,咱們 CPU 隔壁不遠(yuǎn)處有個(gè)叫 BIOS 的伙計(jì),是一個(gè) ROM 芯片,咱們已經(jīng)跟他約定好了,一通電他就映射到地址空間中,你盡管按照 CS:IP(0xF000:0xFFF0)指向的地方開(kāi)始取指令就對(duì)了,他會(huì)安排好的”
“原來(lái)是這樣”,小 A 點(diǎn)了點(diǎn)頭,似懂非懂的樣子。
正式開(kāi)始干活了,小 A 熟練的從 F000:FFF0 處,也就是 0xFFFF0 處取到了第一條指令:jmp xxxx
好家伙,上來(lái)就是一個(gè)大跳轉(zhuǎn),我們一下來(lái)到了 BIOS 那家伙地盤(pán)的中央,開(kāi)始執(zhí)行他準(zhǔn)備的程序了。
接下來(lái)執(zhí)行的這一堆指令我已經(jīng)做過(guò)無(wú)數(shù)次了,對(duì)主板上各單位進(jìn)行檢測(cè),看看有沒(méi)有異常情況,還有初始化我們工作需要的中斷向量表等等,我早已經(jīng)輕車(chē)熟路了。
“哥幾個(gè)忙著吶”,我們正忙的熱火朝天,發(fā)現(xiàn)有人在門(mén)口圍觀,回頭看去,原來(lái)是隔壁二號(hào)車(chē)間、五號(hào)車(chē)間、八號(hào)車(chē)間的幾個(gè)家伙。
“你們幾個(gè)這么閑,要不來(lái)幫我們干會(huì)兒活?”
“哎,你想得美,你們一號(hào)核是引導(dǎo)處理器(BSP),待遇比我們好,這開(kāi)機(jī)啟動(dòng)的活兒我們?cè)趺茨軗屇??”,二?hào)車(chē)間的虎子陰陽(yáng)怪氣的說(shuō)到。
真是羨慕他們,比我們 1 號(hào)車(chē)間上班時(shí)間晚,每次都可以多睡會(huì)兒。
MBR
我繼續(xù)執(zhí)行 BIOS 中的代碼,一切檢查完畢,沒(méi)什么異常,要準(zhǔn)備啟動(dòng)操作系統(tǒng)大佬了。
接下來(lái),我檢查了 BIOS 中配置的啟動(dòng)順序,排在第一位的是硬盤(pán)兄弟。
于是我把硬盤(pán)老哥第 0 盤(pán)第 0 道第 1 扇區(qū)的內(nèi)容讀取到了內(nèi)存中的 0x7C00 位置,他們把這玩意叫做主引導(dǎo)記錄 MBR,一共 512 個(gè)字節(jié)。
聽(tīng)硬盤(pán)那哥們說(shuō),這是操作系統(tǒng)老大在安裝的時(shí)候,寫(xiě)到他那里的。
他還告訴我,這個(gè)位置很重要,曾經(jīng)就有病毒占據(jù)了這個(gè)位置,最后沒(méi)辦法只好重裝系統(tǒng)。
MBR
讀取到了 MBR 后,還得檢查最后兩個(gè)字節(jié)必須是 0x55 和 0xAA,看起來(lái)沒(méi)什么問(wèn)題,是一個(gè)合法的 MBR,我們又跳到了 0x7C00 的位置開(kāi)始執(zhí)行。
操作系統(tǒng)
終于來(lái)到操作系統(tǒng)的地盤(pán)兒了,在操作系統(tǒng)的指示下,我們切換了工作模式,開(kāi)始在保護(hù)模式下工作了!
剛剛切換到保護(hù)模式下,MMU 仍然沒(méi)法做地址翻譯工作,我們還是只有直接使用物理地址跟內(nèi)存聯(lián)系,所以得趕緊把頁(yè)目錄和頁(yè)表準(zhǔn)備妥當(dāng)才行。
忙活了一陣子之后,總算把需要的東西都弄好了,我激動(dòng)的打開(kāi)了內(nèi)存分頁(yè)的開(kāi)關(guān),通知 MMU 部門(mén)開(kāi)始工作,現(xiàn)在我們可以使用虛擬地址訪(fǎng)問(wèn)內(nèi)存了,這感覺(jué)棒多了!
這時(shí),一旁圍觀的二號(hào)車(chē)間、五號(hào)車(chē)間、八號(hào)車(chē)間那幾個(gè)家伙見(jiàn)狀趕緊遛了回去,因?yàn)樗麄冎?,馬上就該他們工作了。
我們繼續(xù)執(zhí)行操作系統(tǒng)的代碼,給咱們 CPU 其他所有核都準(zhǔn)備好了數(shù)據(jù)和指令,創(chuàng)建了多個(gè)線(xiàn)程出來(lái),把他們也叫起來(lái)一起工作,咱們這個(gè)八核 CPU 終于全面開(kāi)動(dòng)起來(lái),一下子熱鬧了不少。
再后來(lái),不知執(zhí)行了多少指令,創(chuàng)建了多少線(xiàn)程,才把操作系統(tǒng)老大完整的運(yùn)行了起來(lái),成功完成了這一次的啟動(dòng)。
這就是通電后,我們 CPU 開(kāi)始工作的日常,我已經(jīng)記不清這是第多少次啟動(dòng)了,也不知道,我們還能啟動(dòng)多少次???
廣告聲明:文內(nèi)含有的對(duì)外跳轉(zhuǎn)鏈接(包括不限于超鏈接、二維碼、口令等形式),用于傳遞更多信息,節(jié)省甄選時(shí)間,結(jié)果僅供參考,IT之家所有文章均包含本聲明。