「大數據」(九十八)Linux之啟動流程

【導讀:數據是二十一世紀的石油,蘊含巨大價值,這是·情報通·大數據技術系列第[98]篇文章,歡迎閱讀和收藏】

1 基本概念

按下電源按鍵後計算機硬件會主動的讀取 BIOS 來加載硬件信息及進行硬件系統的自我測試,之後系統會主動的去讀取第一個可開機的裝置 ( 由 BIOS 設定的 ) ,此時就可以讀入開機管理程序了。 開機管理程序可以指定使用哪個核心檔案來開機,並實際加載核心到內存當中解壓縮與執行, 此時核心就能夠開始在內存內活動,並偵測所有硬件信息並加載適當的驅動程序來使整部主機開始運作,等到核心偵測硬件並加載驅動程序完畢後,操作系統就開始在你的 PC 上面跑了。主機系統開始運作後,此時 Linux 才會呼叫外部程序開始準備軟件執行的環境, 並且實際的加載所有系統運作所需要的軟件程序!最後系統就會開始等待你的登錄與操作。

2 術語解釋

開機過程:指的是從打開計算機電源直到 LINUX 顯示用戶登錄畫面的全過程。

BIOS :全名是 (Basic Input / Output System) ,稱基本輸入輸出系統,可以視為是一個永久地記錄在 ROM 中的一個軟件,是操作系統輸入輸出管理系統的一部分。

MBR :全名是( Main Boot Record 主引導記錄區),整個硬盤的 0 磁道 0 柱面 1 扇區。

Boot Loader :在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統的軟硬件環境帶到一個合適的狀態,以便為最終調用操作系統內核做好一切準備。

3 詳細說明

通常情況下,諸如 lilo 、 grub 這些常見的引導程序都直接安裝在 MBR 中。我們以 grub 為例來分析這個引導過程。

「大數據」(九十八)Linux之啟動流程

grub 引導也分為兩個階段 stage1 階段和 stage2 階段 ( 有些較新的 grub 又定義了 stage1.5 階段 ) 。

1) 、 stage1 : stage1 是直接被寫入到 MBR 中去的,這樣機器一啟動檢測完硬件後,就將控制權交給了 GRUB 的代碼。也就是上圖所看到的前 446 個字節空間中存放的是 stage1 的代碼。 BIOS 將 stage1 載入內存中 0x7c00 處並跳轉執行。 stage1 ( /stage1/start.S )的任務非常單純,僅僅是將硬盤 0 頭 0 道 2 扇區讀入內存。而 0 頭 0 道 2 扇區內容是源代碼中的 /stage2/start.S ,編譯後 512 字節,它是 stage2 或者 stage1_5 的入口。

2) 、 stage2 :嚴格來說這裡還應該再區分個 stage1.5 的,就一併把 stage1.5 放在這裡一起介紹了。我們繼續說 0 頭 0 到 2 扇區的 /stage2/start.S 文件,當它的內容被讀入到內存之後,它的主要作用就是負責將 stage2 或 stage1.5 從硬盤讀到內存中。如果是 stage2 ,它將被載入到 0x820 處;如果是 stage1.5 ,它將被載入到 0x2200 處。這裡的 stage2 或者 stage1_5 不是 /boot 分區 /boot/grub 目錄下的文件,因為這個時候 grub 還沒有能力識別任何文件系統。

如果 start.S 加載 stage1.5 : stage1.5 它存放在硬盤 0 頭 0 道 3 扇區向後的位置, stage1_5 作為 stage1 和 stage2 中間的橋樑, stage1_5 有識別文件系統的能力,此後 grub 才有能力去訪問 /boot 分區 /boot/grub 目錄下的 stage2 文件,將 stage2 載入內存並執行。

如果 start.S 加載 stage2 :同樣,這個 stage2 也不是 /boot 分區 /boot/grub 目錄下的 stage2 ,這個時候 start.S 讀取的是存放在 /boot 分區 Boot Sector 的 stage2 。這種情況下就有一個限制:因為 start.S 通過 BIOS 中斷方式直接對硬盤尋址(而非通過訪問具體的文件系統),其尋址範圍有限,限制在 8GB 以內。因此這種情況需要將 /boot 分區分在硬盤 8GB 尋址空間之前。

假如是情形 2 ,我們將 /boot/grub 目錄下的內容清空,依然能成功啟動 grub ;假如是情形 1 ,將 /boot/grub 目錄下 stage2 刪除後,則系統啟動過程中 grub 會啟動失敗。

啟動內核:

當 stage2 被載入內存執行時,它首先會去解析 grub 的配置文件 /boot/grub/grub.conf ,然後加載內核鏡像到內存中,並將控制權轉交給內核。而內核會立即初始化系統中各設備並做相關的配置工作,其中包括 CPU 、 I/O 、存儲設備等。

關於 Linux 的設備驅動程序的加載,有一部分驅動程序直接被編譯進內核鏡像中,另一部分驅動程序則是以模塊的形式放在 initrd(ramdisk) 中。

Linux 內核需要適應多種不同的硬件架構,但是將所有的硬件驅動編入內核又是不實際的,而且內核也不可能每新出一種硬件結構,就將該硬件的設備驅動寫入內核。實際上 Linux 的內核鏡像僅是包含了基本的硬件驅動,在系統安裝過程中會檢測系統硬件信息,根據安裝信息和系統硬件信息將一部分設備驅動寫入 initrd 。這樣在以後啟動系統時,一部分設備驅動就放在 initrd 中來加載。這裡有必要給大家再多介紹一下 initrd 這個東東:

initrd 的英文含義是 bootloader initialized RAM disk ,就是由 boot loader 初始化的內存盤。在 linu2.6 內核啟動前, boot loader 會將存儲介質中的 initrd 文件加載到內存,內核啟動時會在訪問真正的根文件系統前先訪問該內存中的 initrd 文件系統。在 boot loader 配置了 initrd 的情況下,內核啟動被分成了兩個階段,第一階段先執行 initrd 文件系統中的 init ,完成加載驅動模塊等任務,第二階段才會執行真正的根文件系統中的 /sbin/init 進程。

另外一個概念: initramfs

initramfs 是在 kernel 2.5 中引入的技術,實際上它的含義就是:在內核鏡像中附加一個 cpio 包,這個 cpio 包中包含了一個小型的文件系統,當內核啟動時,內核將這個 cpio 包解開,並且將其中包含的文件系統釋放到 rootfs 中,內核中的一部分初始化代碼會放到這個文件系統中,作為用戶層進程來執行。這樣帶來的明顯的好處是精簡了內核的初始化代碼,而且使得內核的初始化過程更容易定製。

初始化系統:

/sbin/init 進程是系統其他所有進程的父進程,當它接管了系統的控制權先之後,它首先會去讀取 /etc/inittab 文件來執行相應的腳本進行系統初始化,如設置鍵盤、字體,裝載模塊,設置網絡等。主要包括以下工作:

1) 、執行系統初始化腳本 (/etc/rc.d/rc.sysinit) ,對系統進行基本的配置,以讀寫方式掛載根文件系統及其它文件系統,到此係統算是基本運行起來了,後面需要進行運行級別的確定及相應服務的啟動。 rc.sysinit 所做的事情 ( 不同的 Linux 發行版,該文件可能有些差異 ) 如下:

( 1 )獲取網絡環境與主機類型。首先會讀取網絡環境設置文件 "/etc/sysconfig/network" ,獲取主機名稱與默認網關等網絡環境。

( 2 )測試與載入內存設備 /proc 及 usb 設備 /sys 。除了 /proc 外,系統會主動檢測是否有 usb 設備,並主動加載 usb 驅動,嘗試載入 usb 文件系統。

( 3 )決定是否啟動 SELinux 。

( 4 )接口設備的檢測與即插即用( pnp )參數的測試。

( 5 )用戶自定義模塊的加載。用戶可以再 "/etc/sysconfig/modules/*.modules" 加入自定義的模塊,此時會加載到系統中。

( 6 )加載核心的相關設置。按 "/etc/sysctl.conf" 這個文件的設置值配置功能。

( 7 )設置系統時間( clock )。

( 8 )設置終端的控制檯的字形。

( 9 )設置 raid 及 LVM 等硬盤功能。

( 10 )以方式查看檢驗磁盤文件系統。

( 11 )進行磁盤配額 quota 的轉換。

( 12 )重新以讀取模式載入系統磁盤。

( 13 )啟動 quota 功能。

( 14 )啟動系統隨機數設備(產生隨機數功能)。

( 15 )清楚啟動過程中的臨時文件。

( 16 )將啟動信息加載到 "/var/log/dmesg" 文件中。

當 /etc/rc.d/rc.sysinit 執行完後,系統就可以順利工作了,只是還需要啟動系統所需要的各種服務,這樣主機才可以提供相關的網絡和主機功能,因此便會執行下面的腳本。

2) 、執行 /etc/rc.d/rc 腳本。該文件定義了服務啟動的順序是先 K 後 S ,而具體的每個運行級別的服務狀態是放在 /etc/rc.d/rc*.d ( *=0~6 )目錄下,所有的文件均是指向 /etc/init.d 下相應文件的符號鏈接。 rc.sysinit 通過分析 /etc/inittab 文件來確定系統的啟動級別,然後才去執行 /etc/rc.d/rc*.d 下的文件。

/etc/init.d-> /etc/rc.d/init.d

/etc/rc ->/etc/rc.d/rc

/etc/rc*.d ->/etc/rc.d/rc*.d

/etc/rc.local-> /etc/rc.d/rc.local

/etc/rc.sysinit-> /etc/rc.d/rc.sysinit

也就是說, /etc 目錄下的 init.d 、 rc 、 rc*.d 、 rc.local 和 rc.sysinit 均是指向 /etc/rc.d 目錄下相應文件和文件夾的符號鏈接。我們以啟動級別 3 為例來簡要說明一下。

/etc/rc.d/rc3.d 目錄,該目錄下的內容全部都是以 S 或 K 開頭的鏈接文件,都鏈接到 "/etc/rc.d/init.d" 目錄下的各種 shell 腳本。 S 表示的是啟動時需要 start 的服務內容, K 表示關機時需要關閉的服務內容。 /etc/rc.d/rc*.d 中的系統服務會在系統後臺啟動,如果要對某個運行級別中的服務進行更具體的定製,通過 chkconfig 命令來操作,或者通過 setup 、 ntsys 、 system-config-services 來進行定製。如果我們需要自己增加啟動的內容,可以在 init.d 目錄中增加相關的 shell 腳本,然後在 rc*.d 目錄中建立鏈接文件指向該 shell 腳本。這些 shell 腳本的啟動或結束順序是由 S 或 K 字母后面的數字決定,數字越小的腳本越先執行。例如, /etc/rc.d/rc3.d /S01sysstat 就比 /etc/rc.d/rc3.d /S99local 先執行。

3) 、執行用戶自定義引導程序 /etc/rc.d/rc.local 。其實當執行 /etc/rc.d/rc3.d/S99local 時,它就是在執行 /etc/rc.d/rc.local 。 S99local 是指向 rc.local 的符號鏈接。就是一般來說,自定義的程序不需要執行上面所說的繁瑣的建立 shell 增加鏈接文件的步驟,只需要將命令放在 rc.local 裡面就可以了,這個 shell 腳本就是保留給用戶自定義啟動內容的。

4) 、完成了系統所有的啟動任務後, linux 會啟動終端或 X-Window 來等待用戶登錄。 tty1,tty2,tty3... 這表示在運行等級 1 , 2 , 3 , 4 的時候,都會執行 "/sbin/mingetty" ,而且執行了 6 個,所以 linux 會有 6 個純文本終端, mingetty 就是啟動終端的命令。

除了這 6 個之外還會執行 "/etc/X11/prefdm-nodaemon" 這個主要啟動 X-Window

至此,系統就啟動完畢了


分享到:


相關文章: