計算機加電後作業系統啟動過程

2021-09-07 15:38:07 字數 2799 閱讀 5013

揭開鋼琴的蓋子:作業系統好比乙個架美麗的鋼琴,我們可以用上面的琴鍵彈出優美的旋律。但是我們不能滿足於只會彈奏,如果我們要更深入理解鋼琴,必須開啟鋼琴的蓋子,一**竟。所以學習作業系統,不能停留上系統api的呼叫,需要能更好更高效的呼叫api,知道api的侷限性與缺點,就必須開啟作業系統的蓋子,**作業系統api下的底層原理。

從我們按下電源鍵使得計算機通電,計算機的各個部件是怎麼執行起來的呢。我們現在使用的計算都遵循馮諾依曼結構,在我們**計算機的啟動前,先弄明白我們的計算機的結構。

x86 pc歲開機時,cpu處於實模式,這時候記憶體的計算方式是段基址 << 4 + 段內偏移cpu的第一條指令是通過cs:ip來取得,而此時cs=0xffff,ip=0x0000。這是硬體設定好的。

所以最開始執行的指令位址就是0xffff0,這個記憶體位址對映在主機板的bios rom(唯讀儲存區)中。

rom中的程式會檢測ram、鍵盤、顯示器、軟硬磁碟是否正確工作。同時會從位址0開始設定bios的中斷向量表。

rom中的程式繼續執行,將啟動裝置磁碟0磁軌0扇區,乙個512位元組的扇區讀到記憶體0x07c00處。0x07c00應試是乙個歷史遺留的問題,後續把system模組拷貝到位址開始處時,預留的空間將不夠,所以bootset需要把0x07c00這一塊作業系統引導與設定模組拷貝走。這算是乙個歷史包袱。

設定cs=0x07c0,ip=0x0000。

rom中的程式執行結束,轉到0x07c00處開始執行。

啟動裝置是可以通過bios程式來設定的,資訊寫在cmos中。cmos(64b-128b)中存的還有實時鐘,硬體配置資訊等。(開始時按住del鍵可以進入啟動設定的配置介面,可以設定光碟啟動或u盤啟動等)。

把0x7c00開始的512個位元組,拷貝到0x90000處。(0x90000 - 0x90020)

設定棧ss = 0x9000,sp = 0xff00,這裡把sp設定的夠大,防止棧的區域把下面的作業系統**覆蓋了。

呼叫bios ox13中斷,將第2-5個扇區拷貝到0x90020開始的記憶體處。如果出錯,就反覆讀取。

獲取磁碟的引數:磁軌數等

列印字串資訊:system is loading

讀入system部分(幾百個扇區),讀入到記憶體為0x10000處。(在0x90000的下面)

轉到位址為0x90020的位址處執行,也就是開始執行setup部分的**了。

主要工作是完成作業系統啟動前的設定工作。

讀取游標的位置資訊放在09000的頭2個位元組處。因為這時候bootsect模組的**已經沒有用了,可以覆蓋了。

讀出擴充套件記憶體的大小,放在接著的2個位元組處。

獲取顯示卡引數,硬碟引數等等。

將system模組的內容從0x10000處開始移到0x00000處,即記憶體的起始位置。之所以load進來的時候為什麼不一次性放在0x00000處,是因為0x00000處開始放的bios中斷。現在bios中斷已經不需要了,所以可以覆蓋了。

這時候開始,bios的中斷向量表已經被覆蓋了,後面就不再需要bios的中斷了。

設定中斷向量表與全域性描述符表的一部分內容。

把cr0的最後一位設定為1,也就是說從實模型進入保護模式。

jmpi 0, 8。 cs = 8,取到的段基址其實是0x0000,那麼這句話就是跳轉到位址為0x00000的地方開始執行,也就是system模組的開始部分。

cp:ip的翻譯過程是:從cs的前12位取出gdt的偏移量(這裡是1),從gtd的對應表項中取得基位址,再和ip合併為乙個完整的位址。

int n: n指明了idt表中的序號。從idt表中獲取中斷處理函式的入口位址。

system的第一部分就是head.s部分的**,這部分**實際處於絕對位址0處開始的地方。該部分的**是在保護模式下執行的,所使用的是at&t格式的彙編指令與之前使用的as86彙編指令不同。這部分的**主要完成了下面幾件事情。

初步始中斷描述符中的256項門描述符。

檢查a20位址線是否開啟。關於a20位址線的解釋

測試系統是否含有資料協處理器,並設定暫存器cr0對應的位。

初始化記憶體頁目錄表,為記憶體分頁管理作好準備工作。頁目錄表放在了絕對實體地址為0開始處,也就是head.s程式物理記憶體位置,程式會被覆蓋掉。80286當時24根位址線,定址16m,所以頁表要能定址16mb。如果記憶體頁大小為4k,那頁表就有4k個表項,乙個表項按4個位元組算,那頁表就需要16k個位元組(4頁)。這裡只用到了1級頁表,在後續的發展**現了二級頁表,3級頁表。

最後跳轉到system模組中的初始化程式init/main.c中繼續執行。

head.s程式執行結束後,已經正式完成了記憶體頁目錄頁表的設定,並重新設定了核心實際使用的中斷描述符表idt和全域性描述符表gtd。另外還為軟盤驅動開闢了1kb的緩衝區。此時system模組在記憶體中的詳細映像如下圖所示:

整體上可以分類6個階段,頭2個階段為boostset,中間3個階段為setup,最後乙個階段為system的head模組。

[1] 《linux核心完全剖析基於0.12核心》 趙炯著。

[2] 網易雲課堂,哈爾濱工業大學《作業系統之應用》 李治軍。

作業系統啟動過程

當我們按下開機鍵後,作業系統究竟是如何跑起來的?這個過程詳細說來很複雜。這裡只簡單描述一下。當機器剛從生產線上下線的時候,裡面沒有作業系統,稱之為裸機。裸機什麼事都幹不了,於是需要裝上作業系統。機器中固化了乙個用於讀取磁碟或者其他裝置的程式,於是當你在啟動時按下f2鍵,就會執行這個程式安裝作業系統。...

作業系統啟動過程

計算機的儲存器分為 大容量儲存器 通常為硬碟 和 主儲存器 即 記憶體 操作 系統 如 windows unix linux mac os 安裝在大容量儲存器上,而主儲存器又分為兩部分 能夠永久儲存資料的rom read only memory 和易失性儲存器部分 即在關機後資料全部丟失 bios ...

作業系統啟動過程

當我們按下開機鍵後,作業系統究竟是如何跑起來的?這個過程詳細說來很複雜。這裡只簡單描述一下。當機器剛從生產線上下線的時候,裡面沒有作業系統,稱之為裸機。裸機什麼事都幹不了,於是需要裝上作業系統。機器中固化了乙個用於讀取磁碟或者其他裝置的程式,於是當你在啟動時按下f2鍵,就會執行這個程式安裝作業系統。...