歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux 引導啟動程序(boot)

Linux 引導啟動程序(boot)

日期:2017/2/28 16:21:06   编辑:Linux教程

主要描述 boot/目錄中的三個匯編代碼文件,見列表 3-1 所示。正如在前一章中提到的,這三個 文件雖然都是匯編程序,但卻使用了兩種語法格式。bootsect.s 和 setup.s 采用近似於 Intel 的匯編語言語法,需要使用 Intel 8086 匯編編譯器和連接器 as86 和ld86,而 head.s 則使用 GNU 的匯編程序格式,並且運行在保護模式下,需要用 GNU 的 as 進行編譯。這是一種 AT&T 語法的匯編語言程序。

使用兩種編譯器的主要原因是由於對於 Intel x86 處理器系列來講,GNU 的編譯器僅支持 i386 及以 後出的 CPU。不支持生成運行在實模式下的程序。

閱讀這些代碼除了你需要知道一些一般 8086 匯編語言的知識以外,還要對采用 Intel 80X86 微處理器的 PC 機的體系結構以及80386 32 位保護模式下的編程原理有些了解。所以在開始閱讀源代碼之前可以先大概浏覽一下附錄中有關 PC 機硬件接口控制編程和80386 32 位保護模式的編程方法,在閱讀代碼時再就事論事地針對具體問題參考附錄中的詳細說明。

這裡先總的說明一下 Linux 操作系統啟動部分的主要執行流程。當 PC 的電源打開後,80x86 結構的 CPU 將自動進入實模式,並從地址 0xFFFF0 開始自動執行程序代碼,這個地址通常是 ROM-BIOS 中的 地址。PC 機的 BIOS 將執行某些系統的檢測,並在物理地址 0 處開始初始化中斷向量。此後,它將可啟動設備的第一個扇區(磁盤引導扇區,512 字節)讀入內存絕對地址 0x7C00 處,並跳轉到這個地方。啟動設備通常是軟驅或是硬盤。這裡的敘述是非常簡單的,但這已經足夠理解內核初始化的工作過程了。

Linux 的最最前面部分是用 8086 匯編語言編寫的(boot/bootsect.s),它將由 BIOS 讀入到內存絕對地址 0x7C00(31KB)處,當它被執行時就會把自己移到絕對地址 0x90000(576KB)處,並把啟動設備中後 2kB字節代碼(boot/setup.s)讀入到內存 0x90200 處,而內核的其它部分(system 模塊)則被讀入到從地址0x10000 開始處,因為當時 system 模塊的長度不會超過 0x80000 字節大小(即 512KB),所以它不會覆 蓋在 0x90000 處開始的 bootsect 和 setup 模塊。後面 setup 程序將會把 system 模塊移動到內存起始處,這樣 system 模塊中代碼的地址也即等於實際的物理地址,便於對內核代碼和數據的操作。圖 3-1 清晰地顯示出 Linux 系統啟動時這幾個程序或模塊在內存中的動態位置。其中,每一豎條框代表某一時刻內存中各程序的映像位置圖。在系統加載期間將顯示信息"Loading..."。然後控制權將傳遞給 boot/setup.s 中的代碼,這是另一個實模式匯編語言程序。

啟動部分識別主機的某些特性以及 vga 卡的類型。如果需要,它會要求用戶為控制台選擇顯示模式。 然後將整個系統從地址0x10000 移至 0x0000 處,進入保護模式並跳轉至系統的余下部分(在 0x0000 處)。 此時所有 32 位運行方式的設置啟動被完成: IDT、GDT 以及 LDT 被加載,處理器和協處理器也已確認, 分頁工作也設置好了;最終調用 init/main.c 中的 main()程序。上述操作的源代碼是在 boot/head.S 中的, 這可能是整個內核中最有訣竅的代碼了。注意如果在前述任何一步中出了錯,計算機就會死鎖。在操作系統還沒有完全運轉之前是處理不了出錯的。

為什麼不把系統模塊直接加載到物理地址 0x0000 開始處而要在 setup 程序中再進行移動呢?這是因 為在 setup 程序代碼開始部分還需要利用 ROM BIOS 中的中斷調用來獲取機器的一些參數(例如顯示卡 模式、硬盤參數表等)。當 BIOS 初始化時會在物理內存開始處放置一個大小為 0x400 字節(1Kb)的中斷向量表,因此需要在使用完 BIOS 的中斷調用後才能將這個區域覆蓋掉。

Copyright © Linux教程網 All Rights Reserved