Linux系統啟動過程詳解

2021-12-30 02:15:19 字數 3986 閱讀 3364

linux系統啟動

linux系統啟動是乙個非常複雜的過程,主要包括以下幾個部分:

載入bios的硬體資訊並進行自檢,並依據設定取得第乙個可開機的裝置;讀取第乙個開機裝置內的mbr的boot loader依據boot loader的設定載入kernel,kernel會開始偵測並載入驅動程式;在硬體驅動成功之後會執行init指令碼,也就是第乙個使用者程序。

bios

在按下電源按鈕後,系統首先會執行bios,bios會檢測硬體的資訊(硬體的啟動順序等),然後去讀取mbr的內容。但是系統在執行之前是如何執行bios的呢?

在電源啟動之後,cpu中的暫存器都已經有乙個預設的初始值,其中eip(32位的系統的指令暫存器)和基址暫存器的位址相加之後)的值是0xfffffff0h,儘管cpu啟動時處於實模式(實模式最多只能訪問1m的記憶體空間,該模式下任何程式可以向記憶體中的任何位址中讀取或者寫入內容,該模式下沒有保護和特權的概念,例如dos)中,最多只能訪問1m的記憶體空間,但是通過hack技術,cpu還是能執行處於0xfffffff0h的指令。

當cpu reset(開機或者重新啟動)後,根據x86架構的特性,(386以後)cpu會從4g位址的最頂端fffffff0處獲得第一條指令來執行,而這一位址被定位在bios裡。由於fffffff0到ffffffff只有短短的16位元組,根本不可能放下一段程式,所以這裡會放一條跳轉(jump)指令讓bios跳到更低的位址去執行。(cpu開始執行的程式時bios程式)。

(復位向量 reset vector)

復位向量存放的是內部處理在cpu充值之後執行的第一條指令的預設位置,復位向量可以是乙個指標或者是位址。

8086處理器的復位向量是在實體地址ffff0h處(16 bytes below 1 mb),cs 暫存器在重置時的值是ffffh,ip暫存器的值是0000h,形成的段位址是ffffh:0000h,對映到ffff0h。80286處理器的復位向量是在實體地址00ffff0h處(16 bytes below 1 mb),cs 暫存器在重置時的值是f000h,ip暫存器的值是fff0h,形成的段位址是f000h:fff0h,對映到00ffff0h。80386和之後的x86處理器的復位向量是在實體地址fffffff0h處,cs 暫存器在重置時的值是f000h,cs暫存器的基址是ffff0000h,ip暫存器的值是fff0h,形成的段位址是fffff000h:fff0h(fffff000h*4+fff0h),對映到fffffff0h。((ffff0000h+f000h)*4:fff0h)

下圖是系統的記憶體布局圖:

注:bios的大小一般是64kb

mbrbios執行完自檢操作之後,將mbr的內容複製到記憶體位址0x7c00h處,然後執行一條跳轉指令,執行mbr的操作。那個bios何時將mbr載入到記憶體中的呢?

其實bios是通過硬體的int 13中斷指令來讀取mbr的,也就是說只要bios能檢測到你的磁碟,它就會通過int 13中斷指令去讀取第乙個磁碟區內的mbr。

mbr包括兩個重要的部分:

1.微型的和作業系統相關的啟動程式

2.分割槽表

mbr將系統啟動程式載入記憶體繼續執行。

boot loader

mbr載入之後就會開始執行mbr中的boot loader。boot loader的最主要功能就是要認識作業系統的檔案格式並載入核心到記憶體中去執行。但是不同的系統具有不同的boot loader,同時只有乙個mbr,那我們如何決定該載入多系統中那個boot loader呢?

其實每個檔案系統或者分割槽都會保留一塊開機磁區(boot sector)提供作為作業系統存放boot loader,通常作業系統都會預裝乙份loader到它根目錄所在的檔案系統(檔案系統的掛載)的boot sector上。如果我們在乙個電腦上同時安裝了linux和windows,該boot sector,boot loader於mbr的關係有點像下圖:

其中藍色方塊表示boot loader,紅色方塊表示核心檔案。

boot loader的功能如下:

提供選項列表:使用者可以選擇不同的開機專案,這個是多重開機系統的重要功能轉入核心檔案:直接將核心檔案載入記憶體執行核心轉交個其他loader:將開機管理功能交給其他的loader負責 由於具有選項列表的功能,我們可以選擇不同的核心載入,由於具有轉交功能,我們能夠將loader許可權交給其他的loader,所以實現了多重啟動。但是windows的loader不具有轉交功能,所以在裝雙系統的時候必須先裝windows然後再裝linux,因為windows的loader缺省會寫入mbr和自身檔案系統的boot sector。下圖是多系統的啟動方式:

核心的執行 當我們使用boot loader將核心載入到記憶體後,此時核心開始接管bios的工作了。核心一般會進行硬體的檢測,不會使用bios的檢測資訊。 那麼核心檔案在**呢?一般核心檔案會在/boot下,並且取名為/boot/vmlinuz。如下圖所示:

該核心檔案被boot loader動態的載入記憶體,核心也是作為模組module動態載入的,模組檔案存在於/lib/modules目錄下。如下圖所示:

由於模組組是存放在根目錄所在的檔案系統下的(根目錄/與/lib不能存放在不同的檔案系統中),所以在開機過程中核心必須掛載根目錄才能在動驅動程式的功能。 一般來說非必要的同時可以編譯成模組的功能都會編譯成模組動態載入,例如usb,sata,scsi等磁碟驅動程式也是以模組的方式存在的。

一般情況下,bios通過int 13中斷去的boot loader與kernel文件來啟動系統,然後核心會開始接管系統並且嘗試掛載根目錄來取得額外的驅動程式。但是問題出現了?在沒有取得磁碟的驅動程式之前,核心根本無法然是sata等磁碟,所以在掛載根目錄之前必須取得磁碟的驅動程式,但是磁碟的驅動程式在/lib/modules目錄下,你根本無法掛載根目錄又怎麼讀取/lib/modules下面的驅動程式模組檔案?linux使用虛擬檔案系統來處理這個問題。

虛擬檔案系統虛擬檔案系統一般的檔名為/boot/initrd,這個檔案能夠通過boot loader來載入到記憶體中,然後這個檔案會被解壓並且在記憶體中模擬生成乙個根目錄(檔案系統),initrd檔案包含必備的一小部分目錄和可執行檔案用來載入實際開機過程中所需要的核心模組,通常這些模組就是usb,raid,lvm,scsi等檔案和磁碟的驅動程式等。比如insmod工具可以將核心模組載入虛擬的核心。 等載入完成之後,會幫助核心重新呼叫/sbin/init來開始後續的正常開機程式。 下面是initrd的內部結構圖:

cpio是乙個文件管理器,用來將標準輸入寫入檔案或者目錄。

整個系統啟動的過程如下圖所示:

從上圖可以看出,boot loader可以載入kernel和initrd,然後在記憶體中解壓initrd為根目錄,kernel就能夠藉此載入適當的驅動程式,最終釋放虛擬的檔案系統並掛載事假的根目錄檔案系統就能夠開始正常的開機過程了。

Linux系統啟動過程詳解

1 bios自檢 2 啟動grub lilo 3 載入核心 4 執行init程序 5 通過 etc inittab檔案進行初始化 6 登陸linux 1 bios自檢 a post power on self test 對硬體進行檢測 計算機在通電後首先由bios進行自檢,即所謂的post powe...

Linux系統啟動過程詳解

1 bios自檢 2 啟動grub lilo 3 載入核心 4 執行init程序 5 通過 etc inittab檔案進行初始化 6 登陸linux 1 bios自檢 a post power on self test 對硬體進行檢測 計算機在通電後首先由bios進行自檢,即所謂的post powe...

Linux系統啟動過程詳解

本文是學習日記,學自菜鳥教程。linux啟動過程並不複雜,主要分為五部分 核心的引導 執行init 系統初始化 建立終端 使用者登入系統。過程如下 第一部分 核心引導 作業系統接管硬體以後,首先讀入 boot目錄下的核心檔案。第二部分 init程序 在linux作業系統當中,init程序是所有程序的...