首页
/
每日頭條
/
生活
/
計算機物理引擎在哪開啟
計算機物理引擎在哪開啟
更新时间:2024-11-15 20:57:58

本講隻為講明白下面一個問題:

我們按下開機鍵後究竟發生了什麼?

我想當你探尋這個問題的答案時,搜到的大多數是這樣的描述:

BIOS 按照“啟動順序”,把控制權轉交給排在第一位的存儲設備:硬盤。然後在硬盤裡尋找主引導記錄的分區,這個分區告訴電腦操作系統在哪裡,并把操作系統被加載到内存中,然後你就能看到經典的啟動界面了,這個開機過程也就完成了。

這種描述簡直太魔幻了,為什麼是 BIOS 主導這一切?怎麼叫按照啟動順序?這個分區咋就被加載到内存了,又咋告訴電腦操作系統在哪裡了?我無法忍受這樣的魔幻描述,我非要把它說得清清楚楚。

首先學一個東西,一定要有一個前置的知識,我們把它當做已知的,我不可能從原子組成分子開始講原理。那學習計算機啟動過程的前置知識是什麼呢?我要求你已知以下幾點:

  1. 内存是存儲數據的地方,給出一個地址信号,内存可以返回該地址所對應的數據。
  2. CPU 的工作方式就是不斷從内存中取出指令,并執行。
  3. CPU 從内存的哪個地址取出指令,是由一個寄存器中的值決定的,這個值會不斷進行 1 操作,或者由某條跳轉指令指定其值是多少。

好了,隻需要知道這三點前置知識,你就能專業地解釋計算機的啟動過程了。

一、為什麼是 BIOS 主導?

都說開機後,BIOS 就開始運行自己的程序了,又硬件自檢,又加載啟動區的。我就不服了,為什麼開機後是執行 BIOS 裡的程序?為啥不是内存裡的?為啥不是硬盤裡的?

好的,不要懷疑前置知識,CPU 的工作方式,就是不斷從内存中取指令并執行,那為什麼會說是執行 BIOS 裡的程序呢?這就不得不說說内存映射了。

二、内存映射

CPU 地址總線的寬度決定了可訪問的内存空間的大小。比如 16 位的 CPU 地址總線寬度為 20 位,地址範圍是 1M。32 位的 CPU 地址總線寬度為 32 位,地址範圍是 4G。你可以算算我們現在的 64 位機的地址範圍。

可是,可訪問的内存空間這麼大,并不等于說全都給内存使用,也就是說尋址的對象不隻有内存,還有一些外設也要通過地址總線的方式去訪問,那怎麼去訪問這些外設呢?就是在地址範圍中劃出一片片的區域,這塊給顯存使用,那塊給硬盤控制器使用,等等 。

這樣說,其實就不符合我們的前置知識了,所以可以有一種不太正确的理解方式,那就是内存中的這塊位置就是顯存,那塊位置就是硬盤控制器。我們在相應的位置上讀取或者寫入,就相當于在顯存等外設的相應位置上讀取或者寫入,就好像這些外設的存儲區域,被映射到了内存中的某一片區域一樣。這樣我們就不用管那些外設啦,關注點仍然是一個簡簡單單的内存。這就是所謂的内存映射

太好了,現在又用簡單的前置知識就能解釋得通了,我們繼續往下推。

三、實模式下的内存分布

剛剛說到内存中劃分出了一片一片區域給各種外設,那麼問題自然就來了,哪塊區域,分給了哪塊外設了呢?如果是規定,那應該有一張表比較好吧。嗯沒錯,還真有,它就是實模式下的内存分布,筆者給它畫了一張圖:

計算機物理引擎在哪開啟(計算機啟動流程硬核科普)1

哎喲我真是個小天使,把比例都表現出來了,網上能再找出比我這個更直觀的請給我留言。實模式之後再解釋,現在簡單理解就是計算機剛開機的時候隻有 1M 的内存可用。

我們看到,内存被各種外設瓜分了,即映射在了内存中。BIOS 更狠,不但其空間被映射到了内存 0xC0000 - 0xFFFFF 位置,其裡面的程序還占用了開頭的一些區域,比如把中斷向量表寫在了内存開始的位置,真所謂先到先得啊。

四、怎麼就從 BIOS 裡的程序開始執行了

好了,現在我們知道 BIOS 裡的信息被映射到了内存 0xC0000 - 0xFFFFF 位置,其中最為關鍵的系統 BIOS 被映射到了 0xF0000 - 0xFFFFF 位置。假如我現在說,CPU 開機就是執行了這塊區域的代碼,然後巴拉巴拉一頓操作就開機了,你肯定要噴我了,為什麼就執行到這了呢,那咋不從頭開始執行?

這就自然有了一種猜想,我們要用到另一個前置知識了,就是 CPU 從内存的哪個位置取出執行并執行呢?是 PC 寄存器中的地址值。BIOS 程序的入口地址也就是開始地址是 0xFFFF0(人家就那麼寫的),也就是開機鍵一按下,一定有一個神奇的力量,将 pc 寄存器中的值變成 0xFFFF0,然後 CPU 就開始馬不停蹄地跑了起來。沒錯,接下來這句話,可能就是你找了很久的答案,請做好準備:

在你開機的一瞬間,CPU 的 PC 寄存器被強制初始化為 0xFFFF0。如果再說具體些,CPU 将段基址寄存器 cs 初始化為 0xF000,将偏移地址寄存器 IP 初始化為 0xFFF0,根據實模式下的最終地址計算規則,将段基址左移 4 位,加上偏移地址,得到最終的物理地址也就是抽象出來的 PC 寄存器地址為 0xFFFF0。

當我在學習這段知識時,看到這句話才讓将我心裡積壓了很久的疑惑解開,多麼簡單粗暴的道理啊。寫到這裡我也是長舒了一口氣,因為剩下的過程,就幾乎隻是流水賬一樣的正推了。

至于怎麼強制初始化的,我覺得就越過了前置知識的邊界了,況且各個廠商的硬件實現也不一定相同,有很多辦法,也很簡單。讨論起來意義就不大了。

五、BIOS 裡到底寫了什麼程序

好了,我們現在知道了 BIOS 被映射到了内存的某個位置,并且開機一瞬間 CPU 強制将自己的 pc 寄存器初始化為 BIOS 程序的入口地址,從這裡開始 CPU 馬不停蹄地向前跑了起來。那接下來的問題似乎也非常自然地就問出來了,那就是 BIOS 程序裡到底寫了啥?

把 BIOS 程序裡的二進制信息全貼出來也不合适,我們分析一些主要的。我們首先還是來猜測,你看入口地址是 0xFFFF0,說明程序是從這執行的。實模式下内存的下邊界就是 0xFFFFF,也就是隻剩下 16 個字節的空間可以寫代碼了,這夠幹啥的呢?如果你有心的話應該能猜出,入口地址處可能是個跳轉指令,跳到一個更大範圍的空間去執行自己的任務。沒錯就是這樣,0xFFFF0 處存儲的機器指令,翻譯成彙編語言是:

JMPfarf000:e05b

意思是跳轉到物理地址 0xfe05b 處開始執行(回憶下前面說的實模式下的地址計算方式)。

地址 0xfe05b 處開始,便是 BIOS 真正發揮作用的代碼了,這塊代碼會檢測一些外設信息,并初始化好硬件,建立中斷向量表并填寫中斷例程。這裡的部分不要展開,這隻是一段寫死的程序而已,而且對理解開機啟動過程無幫助,我們看後面精彩的部分,也就是 BIOS 的最後一項工作:加載啟動區

六、0x7c00 是啥

該較真的地方就是要較真,我絕對不會讓加載這種魔幻的詞出現在這裡,我們現在就來把它拆解成人話。

其實這個詞也并不魔幻,加載在計算機領域就是指,把某設備上(比如硬盤)的程序複制到内存中的過程。那加載啟動區這個過程,翻譯過來就是,BIOS 程序把啟動區的内容複制到了内存中的某個區域。好了,問題又自然出來了,啟動區是哪裡?被複制到了内存的哪個位置?然後呢?我們一個個來回答。

什麼是啟動區呢?即使你不知道,你也應該能夠猜到,一定是符合某種特征的一塊區域,于是人們把它就叫做啟動區了,那要符合什麼特征呢?先不急,不知道你有沒有過設置 BIOS 啟動順序的經曆,通常有 U 盤啟動、硬盤啟動、軟盤啟動、光盤啟動等等,BIOS 會按照順序,讀取這些啟動盤中位于 0 盤 0 道 1 扇區的内容

至于磁盤格式的劃分,本篇就不做講解了,總之對于内存,我們給出一個數字地址就能獲取到該地址的數據,而對于磁盤,我們需要給出磁頭、柱面、扇區這三個信息才能定位某個位置的數據,都是描述位置的一種方式而已。

接着說, 這 0 盤 0 道 1 扇區的内容一共有 512 個字節,如果末尾的兩個字節分别是 0x55 和 0xaa,那麼 BIOS 就會認為它是個啟動區。如果不是,那麼按順序繼續向下個設備中尋找位于 0 盤 0 道 1 扇區的内容。如果最後發現都沒找到符合條件的,那直接報出一個無啟動區的錯誤。

BIOS 找到了這個啟動區之後幹嘛呢?哦,前面說過了是加載,就是把這 512 個字節的内容,一個比特都不少的全部複制到内存的 0x7c00 這個位置。怎麼複制的?當然是指令啦。哪些指令呢?這裡我隻能簡單說指令集中是有 in 和 out 的,用來将外設中的數據複制到内存,或者将内存中的數據複制到外設,用這兩個指令,以及外設給我們提供的讀取方式,就能做到這一點啦。

啟動區内容此時已經被 BIOS 程序複制到了内存的 0x7c00 這個位置,然後呢?這個其實也不難猜測,啟動區的内容就是我們自己寫的代碼了,複制到這裡之後,就開始執行呗,之後我們的程序就接管了接下來的流程,BIOS 的使命也就結束啦。所以複制完之後,接下來應該是一個跳轉指令吧!沒錯,正是這樣,PC 寄存器的值變為 0x7c00,指令開始從這裡執行。

咦?不知道你有沒有發現,我們似乎不知不覺又把之前的一句魔法語言翻譯成人話了,開頭我們說:

BIOS 把控制權轉交給排在第一位的存儲設備。

所以這句話是什麼意思呢?就是 BIOS 把啟動區的 512 字節複制到内存的 0x7c00 位置,并且用一條跳轉指令将 pc 寄存器的值指向 0x7c00。你看,這不是也沒多幾個字嘛,就把這個問題說得明明白白,簡簡單單。

哦,對了,現在似乎就剩下一個問題了,為什麼非要是 0x7c00 呢?好問題,當然答案也很簡單,那就是人家 BIOS 開發團隊就是這樣定的,之後也不好改了,不然不兼容。為什麼不好改?我們看一個簡單的啟動區 512 字節的代碼。(代碼摘抄自《30 天自制操作系統》)

;hello-os ;TAB=4 ORG0x7c00;程序加載到内存的0x7c00這個位置 ;程序主體 entry: MOVAX,0;初始化寄存器 MOVSS,AX MOVSP,0x7c00 MOVDS,AX;段寄存器初始化為0 MOVES,AX MOVSI,msg putloop: MOVAL,[SI] ADDSI,1 CMPAL,0;如果遇到0結尾的,就跳出循環不再打印新字符 JEfin MOVAH,0x0e;指定文字 MOVBX,15;指定顔色 INT0x10;調用BIOS顯示字符函數 JMPputloop fin: HLT JMPfin msg: DB0x0a,0x0a;換行、換行 DB"hello-os" DB0x0a;換行 DB0;0結尾 RESB0x7dfe-$;填充0到512字節 DB0x55,0xaa;可啟動設備标識

我們看第一行:

ORG0x7c00

這個數字就是剛剛說的啟動區加載位置,這行彙編代碼簡單說就表示把下面的地址統統加上 0x7c00。正因為 BIOS 将啟動區的代碼加載到了這裡,因此有了一個偏移量,所以所有寫啟動區代碼的人就需要在開頭寫死一個這樣的代碼,不然全都串位了。

然後正因為所有寫操作系統的,啟動區的第一行彙編代碼都寫死了這個數字,那 BIOS 開發者最初定的這個數字就不好改了,否則它得挨個聯系各個操作系統的開發廠商,說唉我這個地址改一下哈,你們跟着改改。在公司推動另一個團隊改個代碼都得大費周折,想想看這樣的推動得耗費多大人力。況且即使改了,之前的代碼也都不兼容了,這不得被人們罵死啊。

再看最後一行:

DB0x55,0xaa

這也驗證了我們之前說的這 512 字節的最後兩個字節得是 0x55 0xaa,BIOS 才會認為它是一個啟動區,才會去加載它,僅此而已。

回過頭來說 0x7c00 這個值,它其實就是一個規定死的值,但還是會有人問,那必然有它的合理性吧。其實,我的解釋也隻能說是人家規定了這個值,後人們替他們解釋這個合理性,并不是說當初人家就一定是這樣想的,就好比我們做語文的閱讀理解題一樣。

第一個 BIOS 開發團隊是 IBM PC 5150 BIOS,當時被認為的第一個操作系統是 DOS 1.0 操作系統,BIOS 團隊就假設是為它服務的。但操作系統還沒出,BIOS 團隊假設其操作系統需要的最小内存為 32 KB。BIOS 希望自己所加載的啟動區代碼盡量靠後,這樣比較“安全”,不至于過早的被其他程序覆蓋掉。可是如果僅僅留 512 字節又感覺太懸了,還有一些棧空間需要預留,那擴大到 1 KB 吧。這樣 32 KB 的末尾是 0x8000,減去 1KB(0x400) ,剛好等于 0x7c00。哇塞,太精準了,這可以是一種解釋方式。

七、啟動區裡的代碼寫了啥

其實寫到這,我這篇文章就應該戛然而止了,因為最初的那個問題已經解決了,CPU 已經開始馬不停蹄地從我們預期的位置跑起來了,萬事開頭難,剩下的内容,就是操作系統想怎麼玩就怎麼玩了。

但我覺得還不夠味,似乎還有些問題萦繞在你腦海裡。比如說這個問題:

啟動區裡的代碼寫了啥?就 512 字節就是全部操作系統内容了?

這是一個好問題,512 個字節确實幹不了啥,現在的操作系統怎麼也得按 M 為單位算吧,512 個字節遠遠不夠呢,那是怎麼回事呢?

其實我們可以按照之前的思路猜測,BIOS 用很少的代碼就把 512 字節的啟動區内容加載到了内存,并跳轉過去開始執行。那按照這個套路,這 512 字節的啟動區代碼,是不是也可以把更多磁盤中存儲的操作系統程序,加載到内存的某個位置,然後跳轉過去呢?

沒錯,就是這個套路。所以 BIOS 負責加載了啟動區,而啟動區又負責加載真正的操作系統内核,這配合默契吧?

由于用于啟動盤的磁盤是人家寫操作系統的廠商制作的,俗稱制作啟動盤,所以他也肯定知道操作系統的核心代碼存儲在磁盤的哪個扇區,因此啟動區就把這個扇區,以及之後的好多好多扇區(具體取決于操作系統有多大)都讀到内存中,然後跳轉到開始的程序開始的位置。跳轉到哪裡呢?這個就不像 0x7c00 這個數那麼經典了,不同的操作系統肯定也不一樣,也不用事先規定好,反正寫操作系統的人給自己定一個就好了,别覆蓋其他關鍵設備用到的區域就好。

八、操作系統内核寫了啥

好了現在經過好幾輪跳跳跳,終于跳到内核代碼啦,我們來一起回顧一下:

  1. 按下開機鍵,CPU 将 PC 寄存器的值強制初始化為 0xffff0,這個位置是 BIOS 程序的入口地址(一跳)
  2. 該入口地址處是一個跳轉指令,跳轉到 0xfe05b 位置,開始執行(二跳)
  3. 執行了一些硬件檢測工作後,最後一步将啟動區内容加載到内存 0x7c00,并跳轉到這裡(三跳)
  4. 啟動區代碼主要是加載操作系統内核,并跳轉到加載處(四跳)

經過這連續的四次跳躍,終于來到了操作系統的世界了,剩下的内容,可以說是整個操作系統課程所講述的原理,分段、分頁、建立中斷、設備驅動、内存管理、進程管理、文件系統、用戶态接口等等。

這些名詞在操作系統的課程中你可能都或多或少聽過,如果你好好學了的話也一定知道大概的原理,不過像筆者這樣從頭到尾研讀過 linux 内核源碼的硬核狗來說,這些概念不隻是書本上枯燥無味的概念,而是活靈活現在操作系統的每一行代碼上,有的展現了作者無比的智慧,有的讓我看到了作者由于硬件設定不得已做出的屈服。

如果這篇文章提起了你對操作系統的好奇心,建議你也找時間讀一讀,和我一起入坑,你會發現一個新世界的大門向你打開了

九、參考資料

好了,這回我真的要結束了,相信如果你真的看完了全文,計算機的啟動過程,可以說有了比較具象的了解。如果你想深入細節,也就是了解整個過程的每一點,那可要下功夫了。

初學者推薦兩本書籍,可以順序閱讀,祝你入坑:

  • 《30 天自制操作系統》
  • 《操作系統真象還原》
,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
上海海關包裹查詢系統
上海海關包裹查詢系統
複雜的海關政策如何搞懂?遇到通關問題又該找誰去處理?這些問題,隻需簡單撥打一個熱線電話就能得到解決。小布了解到,上海海關12360業務自開通以來,業務不斷完善,功能不斷增強,解決問題也越來越高效,充分發揮了海關服務“總客服”的作用。熱線業務...
2024-11-15
論語中的儒家思維
論語中的儒家思維
《論語》,儒家傳統中最受尊崇的聖典,可能是由孔子第二代弟子彙編成冊的。《論語》的基本内容是孔子的語錄,保存了口傳的和筆錄的孔子教訓。《論語》把握住孔子精神的方式和内容,與柏拉圖的對話集強調蘇格拉底的教學法如出一轍。許多具有批評意識的現代讀者...
2024-11-15
女尊文1v1軟萌可愛男主
女尊文1v1軟萌可愛男主
1、《妻主不要》作者:月照花林文案:他琴棋書畫樣樣精通。他上得廳堂下得廚房。他謹守閨訓又貌美如花。最初的時候,他縱有千般好,她就是不要。後來的時候,他沒了千般好,她一生不離。她自幼家道中落來賣包子。她隻想平平淡淡找個樸實的夫郎過日子。這個看...
2024-11-15
近代最牛的盜墓祖師爺
近代最牛的盜墓祖師爺
大家好,我是管哥。盜墓行業一直在民間充滿傳奇色彩,盜墓高人也數不勝數,他們各有手段尋找墓穴,然而就有這麼一個人被稱之為盜墓祖師爺!他就是姚玉忠,被抓之後姚玉忠依舊口出狂言,說後悔沒有挖秦始皇陵!那麼這位盜墓祖師爺究竟盜了多少墓,從墓中他又得...
2024-11-15
怎樣辨别甲床是否受損
怎樣辨别甲床是否受損
怎樣辨别甲床是否受損?看外觀甲床的受損是十分容易辨别的,一般都是能夠從外觀上就能觀察到甲床的受損,現在小編就來說說關于怎樣辨别甲床是否受損?下面内容希望能幫助到你,我們來一起看看吧!怎樣辨别甲床是否受損看外觀。甲床的受損是十分容易辨别的,一...
2024-11-15
Copyright 2023-2024 - www.tftnews.com All Rights Reserved