1.簡介
Linux啓動過程指的是從加電到看到shell提示的這一段時間。
Linux啓動的過程能夠大概分爲幾個個階段,具體劃分爲幾個階段則依靠具體的系統實現。通常來講,基於X86架構的系統能夠分爲3個階段;一些嵌入式的系統有的分爲兩個階段,有的分爲3個階段。
不少介紹linux系統啓動的文章對細節部分都描述的不清楚,那就讓我來詳細的說一下吧,若是由錯誤,請多包含了:)
2. 啓動過程之上電與加載引導程序
不管是哪一種系統,linux啓動的第一階段老是CPU上電初始化的階段。
CPU在上電以後首先是自檢的過程,當這個過程完成以後,CPU就會跳轉到一個固定
的地址,從這個地址開始執行代碼。這個固定的地址根據CPU的不一樣而不一樣,好比PC中的這個地址是0XFFFF0。而這個固定的地址一般是一些只讀的或者
可讀寫的閃存,CPU經過總線和這些閃存鏈接,並可以經過尋址機制找到這些閃存的地址。
在普通PC中,BIOS系統是一個‘加載第一個引導程序’的系統,PC的CPU上
電後執行的第一行代碼老是BIOS中的閃存所保存的代碼,這段代碼能夠看做是一個啓動環境,它完成的工做有兩部分:基本硬件加電檢測與本地設備的枚舉與初
始化。當完成加電檢測後,這段BIOS代碼(完成加電檢測的代碼)會被從內存中清除,可是BIOS的系統運行時服務代碼開始運行,這段代碼檢測CMOS的
配置,其實也就是看看用戶配置的從哪一個設備啓動,當BIOS的運行時服務代碼找到用戶配置的啓動設備後,就今後設備中將第一個引導程序的代碼拷貝到RAM
中,至此,BIOS的任務順利完成。剩下的事情交給‘第一個引導程序’來繼續吧。須要注意的是這個所謂的‘第一個引導程序‘確定保存在用戶選擇的設備中,
而且BIOS的運行時服務代碼知道這個引導程序保存的地址,要不怎麼把它搞到RAM中去啊?
而在嵌入式系統中可能沒有BIOS這樣的系統,可是確定也有一塊相似的閃存
/ROM,CPU能夠從這個ROM的地址上開始執行代碼,而這段代碼確定是一個啓動環境,也就是一段特殊的程序了,好比U-BOOT什麼的。這段程序確定
保存在閃存的固定位置,要不您讓CPU怎麼找?這段程序幹什麼呢?它們提供了將Linux系統映象下載到閃存並繼續執行的方法,除了能夠存儲並引導
Linux映象以外,這些程序還可能執行必定級別的系統測試和硬件初始化過程。嵌入式系統的這段啓動環境代碼就相似與PC中的‘第一個引導程序’代碼,也
就是和硬盤MBR中包含的主引導程序相似。
在PC
Linux啓動中,當BIOS發現是由硬盤引導系統後,就找到此硬盤的MBR,將MBR中保存的引導程序加載到RAM中,而後將CPU的控制權交給MBR
中的這段代碼,BIOS的任務到此算是所有完成了。因此說,BIOS從上電到如今忙活了大半天,主要目的就是爲了找到引導設備,並將引導設備的引導程序加
載到RAM中來運行。BIOS好人啊!
3.第一階段引導程序
MBR中的代碼就是所謂的‘第一階段引導程序’。
它分爲三個部分,第一部分是真正的代碼,即BootLoader代碼部分,就是一段可執行的代碼;第二部分是一個64字節的分區表,包含四個分區記錄;第三部分是結束標識符(0XAA55),用來作MBR的有效性檢測。
‘第一階段引導程序’的做用是查找並加載‘第二階段引導程序’。它經過在分區表中查
找一個活動分區來實現此功能。在MBR的第二部分所標識的四個分區中,只有一個是活動分區,一般這個活動分區記錄包含了真正分區的信息,
Bootloader經過這個信息找到真正的分區,而後從這個分區將‘第二階段引導程序’加載進RAM中。
4.第二階段引導程序
第二階段引導程序能夠認爲是引導過程的最後一步了,它的核心任務就是加載Linux內核與可選的初始化RAM盤。
在PC環境中,如今一般使用grub來實現引導程序。Grub相對應lilo來講一
個最大的優勢就是grub能夠識別硬盤分區。其實在第一階段引導程序加載第二階段引導程序以前,第一階段引導程序會先引導一個第1。5階段引導程序進入
RAM執行,這段代碼能夠理解爲包含linux系統映象的特殊文件系統,當此引導程序運行後,就會加載第二階段引導程序了。第二階段引導程序主要是
grub的工做,就是使用咱們事先配置好的grub來加載相應的內核映象與初始化RAM盤到內存中。
當內核影響與初始化RAM盤加載成功後,第二階段引導程序的任務也就勝利完成了,剩下的活都交給內核映象吧。
5.內核啓動過程 當第二階段引導程序完成任務,內核映象取得CPU控制權後,內核的旅程就開始了,終於等到這一天了! 惋惜,此時的內核映象並非一個可執行的程序,而是一個壓縮過的程序,使用zlib 壓縮而成。其實此內核映象包括兩個部分,最前端的部分是一小段的可執行代碼,後面纔是真正的內核映象。前端部分的主要工做是初始化少許的硬件設置,而後解 壓縮內核映象並將解壓縮後的內核放入高端內存中。此時若是發現由初始化RAM盤,則將其移入內存中,暫時不用。而後,解壓縮後的內核取得了CPU的控制 權,內核開始行動了! 內核啓動後,首先對頁表進行初始化,並啓動內存分頁功能,而後檢測CPU類型,而後調用start_kernel()函數,進入與體系無關的初始化部分,包括內存配置,加載初始化RAM盤,最後啓動init函數,至此內核啓動階段就結束了。