我們知道了LILO怎麼安裝,包含什麼東西,有什麼功能,但LILO到底是怎麼啟動並執行呢?下面是程式碼分析層次的LILO運行過程,通過介紹這個過程,希望你能對整個Boot Loader這部分內容有一個深入的認識。 1.從磁碟片啟動 Linux核心可以存入一張1.44MB的磁碟片中,這樣做的前提是對“Linux核心映像”進行壓縮,壓縮是在編譯核心時進行的,而解壓是由裝入程式在引導時進行的。 當從磁碟片引導Linux時,Boot Loader比較簡單,其代碼在arch/i386/boot/bootsect.S組合語言檔案中。當編譯Linux核心源碼時,就獲得一個新的核心映像,這個組合語言檔案所產生的可執行代碼就放在核心映像檔案的開始處。因此,製作一個包含Linux核心的軟磁碟並不是一件困難的事。 把核心映像的開始處拷貝到磁碟片的第一個扇區就建立了一張啟動磁碟片。當BIOS裝入磁碟片的第一個扇區時,實際上就是拷貝Boot Loader的代碼。BIOS將Boot Loader讀入至記憶體中物理地址0x07c00處,控制權轉給Boot Loader,Boot Loader執行如下操作: · 把自己從地址0x07c00 移到 0x90000。 · 利用地址0x03ff,建立“實模式”棧。 · 建立磁碟參數表,這個表由BIOS用來處理磁碟片裝置驅動程式。 · 通過調用BIOS的一個過程顯示“Loading”資訊。 · 然後,調用BIOS的一個過程從磁碟片裝入核心映像的setup( )代碼,並把這段代碼放入從地址0x90200開始的地方。 · 最後再調用BIOS的一個過程。這個過程從磁碟片裝入核心映像的其餘部分,並把映像放在記憶體中從地址0x10000開始的地方,或者從地址0x100000開始的地方,前者叫做“低地址”的小核心映像(以“make zImage”進行的編譯),後者叫做“高地址”的大核心映像(以“make bzImage”)進行的編譯。 2.從硬碟啟動 一般情況下,Linux核心都是從硬碟裝入的。BIOS照樣將開機磁區讀入至記憶體中的0x00007c00處,控制權轉給Boot Loader,Boot Loader把自身移動至0x90000處,並在0x9B000處建立堆棧(從0x9B000處向0x9A200增長),將第二級的開機磁區讀入至記憶體的0x9B000處,把控制權交給它。在開機磁區移動之後,將顯示一個大寫的L字元,而在啟動第二級的開機磁區之前,將顯示一個大寫的I字元。如果讀入第二級的開機磁區的過程有錯誤的話,螢幕上的LI之後會顯示一個十六進位的錯誤號碼。 二級開機磁區內的代碼將把描述符表讀入至記憶體中的0x9D200處,把包含有命令列解釋程式的扇區讀入至記憶體的0x9D600處。接著,二級開機磁區將等待使用者的輸入,不管這時使用者輸入了一個選擇還是使用預設配置,都將把對應的扇區讀入至記憶體的0x9D600(覆蓋命令列解釋程式的空間),把產生的啟動參數儲存在0x9D800處。 如果使用者定義了用於啟動的RAM盤的話,這部分檔案將被讀入到實體記憶體的末尾。如果你的記憶體大於16MB的話,它會被讀入至16MB記憶體的結尾,這是因為BIOS程式不支援對16MB以上記憶體的訪問(它用於定址的指令中只有24位的地址描述位)。並且它開始於一個新的頁,以便於啟動後系統把它所佔的記憶體回收到記憶體池。 接下來,作業系統的初始化代碼將被讀入到記憶體的0x90200處。而系統的核心將被讀入到0x10000處。如果該核心是以make bzImage方式編譯的,它將被讀入到記憶體的0x100000處。在讀入的過程中,存放map檔案的扇區被讀入至記憶體的0x9D000處。 如果讀入的image是Linux的核心,控制權將交給處於0x90200的Setup.S。如果讀入的是另外的作業系統,過程要稍微麻煩一點:chain loader被讀入到記憶體的0x90200處。該系統用於啟動的扇區被讀入到0x90400。chain loader將把它所包含的分區表移到0x00600處,把開機磁區讀入到0x07c00。做完這一切,它把控制權交給開機磁區。 第二級開機磁區在得到控制權以後馬上顯示一個大寫的L字元。讀入命令列解釋程式後顯示一個大寫的O字元。 圖13.11是LILO運行完後,記憶體的分布情況。 圖13.11 LILO運行後的電腦記憶體分布情況
|