Linux的啟動過程及init程式

酸蘿蔔別吃發表於2021-02-25

Linux下有三個特殊程式:

  • idle程式(pid=0)
    idle程式其前身是系統建立的第一個程式,0號程式,也唯一一個沒有通過fork()或者kernel_thread產生的程式,由系統自動建立,執行在核心態。0號程式在建立了init程式後,演變成為idle程式。主處理器上的idle程式是由原始程式(0號程式)演變而來,從處理器上的idle程式是由init程式fork得到的,pid也為0。idle程式的優先順序最低,不參與排程,只有在執行佇列為空時才排程。
  • init程式(pid=1)
    init程式由0號程式建立,完成系統的初始化,是第一個使用者程式,是其他所有使用者程式的父程式。
  • kthreadd程式(pid=2)
    kthreadd程式由idle通過kernel_thread建立,始終執行在核心空間,負責核心程式的排程和管理。

init程式一開始是核心態,然後在執行了一個使用者態的init程式之後,轉成使用者態,之後只能在使用者態工作。使用者想要進入核心態只能通過呼叫API。
init程式要把自己轉換成使用者態,就需要執行一個使用者態的應用程式(init程式),需要執行這個程式就需要找到這個程式,需要找到這個程式就需要掛載根檔案系統,因為所有的應用程式都在檔案系統中。
所以,需要先掛載根檔案系統,並找到使用者態下的init程式。

Linux中的所有程式都是由init程式建立並執行的。首先Linux核心啟動,然後在使用者空間中啟動init程式,再啟動其他程式。在系統啟動完成後,init程式將變成守護程式監視系統的其他程式。
init啟動了login程式(使用者登入程式),命令列程式(提供命令列環境),shell程式(提供命令解釋和執行)
其中,shell程式是使用者登入後執行的第一個程式。

執行級別:

0  關機
1  單使用者
2  多使用者,會啟動網路功能,但不會啟動NFS,是維護模式
3  多使用者
4  不使用,預留
5  圖形化介面
6  重啟
emergency  急救模式

直接使用init+執行級別

在centos7中,init程式是systemed程式;在centos6中是upstart程式;在centos5中是init程式,在unbuntu中是init程式。

Centos7啟動過程:
init.png
1.開啟電源
2.POST加電自檢。初始化硬體裝置,檢查系統主要外圍裝置。啟動固化在主機板上的ROM晶片上的BIOS程式,BIOS程式會檢測記憶體,CPU,IO裝置等是否能正常執行。只要一通電,CPU就會自動載入BIOS程式,檢測完成之後進行硬體的初始化。
3.根據BIOS啟動的順序依次掃描各個引導裝置,讀取MBR(主引導扇區,是硬碟的第一個扇區)中的主載入程式bootloader並載入到記憶體執行。
啟動.png
4.執行MBR中的BootLoader(centos7是GRUB2),載入其配置檔案,提供一個選單給使用者,選擇要啟動的系統或者核心版本。
5.載入核心,核心得到系統控制權後,進行初始化。探測可識別的硬體裝置,載入硬體驅動程式,以只讀方式掛載檔案系統,執行使用者空間的第一個程式systemed。
6.載入systemed的配置檔案,根據配置檔案設定預設執行級別。
7.執行系統初始化指令碼/etc/rc.d/rc.sysinit,完成系統初始化。
8.啟動終端,列印登入提示符。

unit檔案:
systemed可以管理所有的系統資源,不同的資源統稱為unit檔案。
unit檔案一共有12種檔案型別:

    • .service:系統服務
    • .target:多個unit組成的一組,引導其他unit,代替了以前的執行級別
    • .device:硬體裝置
    • .mount:檔案系統的掛載點
    • .automount:自動掛載點
    • .path:用於監控指定的目錄變化,並觸發其他unit執行,用於定義檔案系統的一個檔案或目錄
    • .scope:描述一些系統服務的分組資訊,不是使用者建立的,系統自己產生的
    • .slice:程式組
    • .snapshot:systemed快照
    • .socket:程式間通訊的socket
    • .swap:用於做虛擬記憶體的交換分割槽,標識swap裝置
    • .timer:定時器

相關文章