linux 啓動過程分析

Linux系統啓動過程分析

  主要內容:

    1. 啓動過程幾個主要文件簡介 

    2. 開機過程詳細說明

    3. 開機過程詳圖

 

啓動過程中的幾個主要文件及其作用:

文件名稱

(按照加載次序列出)

 

作用

/etc/inittab

定義在進入或切換各個級別時系統需要執行的動作

init在初始化系統時需要讀取其中配置




/etc/rc.d/rc.sysinit

init進程調用執行

完成下面的初始化工作:

1. 獲取網絡環境及主機類型

2. 測試與載入內存設備/procUSB設備/sys

3. 決定是否啓動SELinux

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

5. 用戶自定義模塊的加載

6. 加載核心的相關設置

7. 設置系統時間

8. 設置中斷控制檯(console)的字形

9. 設置RAIDLVM等硬盤功能

10. fsak檢驗磁盤文件系統

11. 進行磁盤配額quota的轉換(非必要)

12. 重新以可讀取模式載入系統磁盤

13. 啓動quota的功能

14. 啓動隨機數設備

15. 清除啓動過程中生成的臨時文件

16. 將啓動相關信息加載到/var/log/message文件中

/ettc/rc.d/rc

init進程調用執行

根據制定的運行級別,加載或終止相應的系統服務

/etc/rc.local

rc腳本調用執行

保存用戶定義的徐開機後自動執行的命令

 

inittab文件說明:
    格式:  id:runlevels:action :process

id

用於在inittab文件中唯一標識一條記錄,沒有特別的意義

runlevels

用於指定記錄能在哪些級別下運行(可以有多個,表示在相應的運行級均需要運行;也可以爲空,爲空時表示0~6都要運行)

action

用於指定記錄將執行的動作類型

process

用於設置啓動進程所執行的動作命令

(字段中進程可以是任意的守候進程、可執行腳本或程序)


  inittab文件中每一記錄都從新的一行開始,所以每個記錄項最多可有512個字符;
  運行級(runlevels)就是操作系統當前正在運行的功能級別。這個級別從1到6;
  當運行級別改變,並且正在運行的程序並沒有在新的運行級別中指定需要運行,那麼init會先發送一個SIGTERM 信號終止,然後是SIGKILL. 運行級別發生變化時,init就會從/etc/inittab運行相應的命令
 

文件中有效的action值:

 


 

有效的action

 

respawn如果process字段指定的進程不存在,則啓動該進程,init不等待處理結束,而是繼續掃描inittab文件中的後續進程,當這樣的進程終止時,init會重新啓動它,如果這樣的進程已存在,則什麼也不做。

wait啓動process字段指定的進程,必須等到執行結束纔去處理inittab中的下一記錄項。

once: 啓動process字段指定的進程,不等待處理結束就去處理下一記錄項。當這樣的進程終止時,也不再重新啓動它,在進入新的運行級別時,如果這樣的進程仍在運行,init也不重新啓動它。

boot只有在系統啓動時,init才處理這樣的記錄項,啓動相應進程,並不等待處理結束就去處理下一個記錄項。當這樣的進程終止時,系統也不重啓它。

bootwait:系統啓動後,當第一次從單用戶模式進入多用戶模式時處理這樣的記錄項,init啓動這樣的進程,並且等待它的處理結束,然後再進行下一個記錄項的處理,當這樣的進程終止時,系統也不重啓它

off如果指定的進程正在運行,init就給它發SIGTERM警告信號,在向它發出信號SIGKILL強制其結束之前等待5秒,如果這樣的進程不存在,則忽略這一項。

powerfailinit接到斷電的信號(SIGPWR)時,處理指定的進程。當然前提是有U P S和監視UPS並通知init電源已被切斷的軟件。RHlinux默認沒有列出該選項

powerwait init接到斷電的信號(SIGPWR)時,處理指定的進程,init不會等待正在運行的進程結束,並且等到處理結束纔去檢查其他的記錄項。

sysinit: 指定的進程在訪問控制檯之前執行,這樣的記錄項僅用於對某些設備的初始化,目的是爲了使init在這樣的設備上向用戶提問有關運行級別的問題,init需要等待進程運行結束後才繼續。

initdefault: 指定一個默認的運行級別,只有當init一開始被調用時才掃描這一項,如果runlevel字段指定了多個運行級別,其中最大的數字 是默認的運行級別,如果runlevel字段是空的,init認爲字段是0123456,於是進入級別6,這樣便陷入了一個循環,如果inittab文件中沒 有包含initdefault的記錄項,則在系統啓動時請求用戶爲它指定一個初始運行級別

ctrlaltdel允許init在用戶於控制檯鍵盤上按下Ctrl+Alt+Del組合鍵時,重新啓動系統。注意,如果該系統放在一個公共場所,系統管理員可將Ctrl+Alt+Del組合鍵配置爲別的行爲,比如忽略等。我是設置成打印一句警告的話了(防止其他人惡意重啓系統):監視到特定的鍵盤組合鍵被按下時採取的動作,現在還不完善。

 

開機過程詳細說明:

  示意圖:

過程說明:
    1.  BIOS:系統首先由POST(PowerOnSelfTest,上電自檢)程序來對內部各個設備進行檢查;自檢後,就首先按照系統CMOS設置中保存的啓動順序搜尋軟硬盤驅動器及CD—ROM、網絡服務器等有效地啓動驅動器,讀入操作系統引導記錄,然後將系統控制權交給引導記錄,並由引導記錄來完成系統的順利啓動。

  注:
    硬盤主引導記錄MBR(Master Boot Record):位於硬盤0磁道0柱面1扇區,該扇區共512bytes,其中MBR佔446bytes ;MBR所做的唯一的事情就是裝載第二引導裝載程序。
    分區表DPT(Disk Partition Table)佔64bytes;
    硬盤有效標誌(Magic Number)佔2bytes;

    2.  引導扇區的前446字節,其中定義如何啓動本硬盤上的系統(根據分區表找到對應分區上的內核);而對於Linux,一般多用Grub引導,由於grub相對較大,所以分爲兩段式的進行引導,第一段存儲於硬盤MBR中,第二段放置於操作系統內核所在的分區上。Grub根據MBR中第一段找到第二段,繼續引導,第二段中放置的有GRUB菜單等信息,可以讓用戶選擇需要繼續引導啓動的系統;並且菜單中指定的有內核及RamDisk信息;
    3.  根據用戶選擇將對應的內核讀到內存,解壓展開;然後內核開始初始化;初始化完成後需要讀取根分區(根是一切的起點),這時候如果系統不是普通磁盤,是scsi或是raid形式時,就需要先加載相關的文件系統驅動來驅動該磁盤設備,從而讀取根分區(雞和蛋問題);這時候給內核提供了一個minilinux,即initrd,其中含有內核所需的一些基本模塊驅動,該linux只在內存中運行。內核啓動時展開該initrd來加載相應的驅動,在該驅動的補充之下從而掛載上根分區;
    4.  然後運行根分區腳本/sbin/init 來初始化系統;這個客戶自行程序運行會讀取初始化配置文件inittab:在其中順序定義並運行的有1.默認的運行級別 2.默認的系統服務初始化腳本sysinit位置 3.各種運行級別;系統會根據默認的運行級別,來對應執行相應級別下的腳本,該處腳本是鏈接文件,鏈接到init.d中相對應的文件,真正運行的是init.d裏的腳本)。

    注:
     rc N;表示用rc腳本去運行rc N.d目錄下的腳本;rc腳本就是去執行所需級別腳本的功能腳本;
    目錄下的文件均爲腳本鏈接文件,指向/etc/rc.d/rcN.d/目錄,並且命名時以S或K開頭,後面跟上0-99的數字;S代表啓動時執行;K代表關閉時執行;01-99代表啓動或關閉的級別(數字越小越優先)
    5.  初始化結束前執行最後一個文件:/etc/rc.d/rc.local,系統會讀取該腳本中的所有命令並執行一遍;但是該腳本只在啓動時執行一次,系統關閉時不能執行,所以不要爲了實現開機啓動而將某些服務寫入這個腳本,那樣會造成服務關機時的非正常關閉;

   注:
  內核:模塊化設計,大部分設備模塊是在需要時加載驅動,並且大部分模塊的驅動放置於根分區上。

 

 開機詳細流程圖:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章