linux中/etc/inittab文件分析

一、什麼是init

  init是Linux系統操作中不可缺少的程序之一。 是一個由內核啓動的用戶級進程。

  內核啓動(已經被載入內存,開始運行,並已初始化所有的設備驅動程序和數據結構等)之後,就通過啓動一個用戶級程序init的方式來啓動其他用戶級的進程或服務。所以,init始終是第一個進程(其PID始終爲1)。
   
    init進程是系統所有進程的起點,Linux在完成核內引導以後,就開始運行init程序。
      
      init程序需要讀取配置文件/etc/inittab。inittab是一個不可執行的文本文件,它有若干行指令所組成。

  內核會在過去曾使用過init的幾個地方查找它,它的正確位置(對Linux系統來說)是/sbin/init.如果內核找不到init,它就會試着運行/bin/sh,如果運行失敗,系統的啓動也會失敗。

二、運行級別

   Runlevel 0是讓init關閉所有進程並終止系統。

    Runlevel 1是用來將系統轉到單用戶模式,單用戶模式只能有系統管理員進入,在該模式下處理那些在有登錄用戶的情況下不能進行更改的文件,改runlevel的編號1也可以用S代替。
    Runlevel 2是允許系統進入多用戶的模式,但並不支持文件共享,這種模式很少應用。
    Runlevel 3是最常用的運行模式,主要用來提供真正的多用戶模式,也是多數服務器的缺省模式。
    Runlevel 4一般不被系統使用,用戶可以設計自己的系統狀態並將其應用到runlevel 4階段,儘管很少使用,但使用該系統可以實現一些特定的登錄請求。
    Runlevel 5是將系統初始化爲專用的X Window終端。對功能強大的Linux系統來說,這並不是好的選擇,但用戶如果需要這樣,也可以通過在runlevel啓動來實現該方案。
    Runlevel 6是關閉所有運行的進程並重新啓動系統。

The following runlevels are defined:
   N       System bootup (NONE).
   S       Single user mode (not to be switched to directly)
   0       halt
   1       single user mode
   2 .. 5  multi user mode
   6       reboot

這些級別在/etc/inittab 文件裏指定。這個文件是init 程序尋找的主要文件,最先運行的服務是放在/etc/rc.d 目錄下的文件。在大多數的Linux 發行版本中,啓動腳本都是位於 /etc/rc.d/init.d中的。這些腳本被用ln 命令連接到 /etc/rc.d/rcn.d 目錄。(這裏的n 就是運行級0-6)

三、運行級別的配置

        在inittab文件中以#開頭的所有行都是註釋行。註釋行有助於用戶理解inittab文件,inittab文件中的值都是如下格式:

        label:runlevel:action:process


        1, label是1~4個字符的標籤,用來標示輸入的值。一些系統只支持2個字符的標籤。鑑於此原因,多數人都將標籤字符的個數限制在2個以內。該標籤可以是任意字符構成的字符串,但實際上,某些特定的標籤是常用的,在Red Hat Linux中使用的標籤是:
id 用來定義缺省的init運行的級別
si 是系統初始化的進程
ln 其中的n從1~6,指明該進程可以使用的runlevel的級別
ud 是升級進程
ca 指明當按下Ctrl+Alt+Del時運行的進程
pf 指當UPS表明斷電時運行的進程
pr 是在系統真正關閉之前,UPS發出電源恢復的信號時需要運行的進程

x 是將系統轉入X終端時需要運行的進程


2,runlevel字段指定runlevel的級別。可以指定多個runlevel級別,也可以不爲runlevel字段指定特定的值。(另外sysinit、boot、bootwait這三個進程會忽略這個設置值。)


3,action:表示進入對應的runlevels時,init應該運行process字段的命令的方式。有效的action值如下:
respawn:表示init應該監視這個進程,即使其結束後也應該被重新啓動。
  wait:init應該運行這個進程一次,並等待其結束後再進行下一步操作。
  once:init需要運行這個進程一次。
  boot:隨系統啓動運行,所以runlevel值對其無效。
  bootwait:隨系統啓動運行,並且init應該等待其結束。
  off:沒有任何意義。
  initdefault:系統啓動後的默認運行級別;由於進入相應的運行級別會激活對應級別的進程,所以對其指定process字段沒有任何意義。如果inittab文件內不存在這一條記錄,系統啓動時在控制檯上詢問進入的運行級。
  sysinit:系統啓動時準備運行的命令。比如說,這個命令將清除/tmp.可以查看/etc/rc.d/rc.sysinit腳本瞭解其運行了那些操作。
  powerwait:允許init在電源被切斷時,關閉系統。當然前提是有U P S和監視U P S並通知init電源已被切斷的軟件。RH linux默認沒有列出該選項。
  powerfail:同powerwait,但init不會等待正在運行的進程結束。RH linux默認沒有列出該選項。
  powerokwait:當電源監視軟件報告“電源恢復”時,init要執行的操作。
  powerfailnow:檢測到ups電源即將耗盡時,init要執行的操作,和powerwait/powerfail不同的喲。
  ctrlaltdel:允許init在用戶於控制檯鍵盤上按下Ctrl + Alt + Del組合鍵時,重新啓動系統。注意,如果該系統放在一個公共場所,系統管理員可將Ctrl + Alt + Del組合鍵配置爲別的行爲,比如忽略等。我是設置成打印一句罵人的話了^o^. kbrequest:監視到特定的鍵盤組合鍵被按下時採取的動作,現在還不完善。
  ondemand:A process marked with an ondemand runlevel will be executed whenever the specified ondemand runlevel is called. However, no runlevel change will occur (ondemand runlevels are ‘a’, ‘b’,and ‘c’),(英語太菜,那個however不知道該怎麼翻譯纔好。慚愧!)

 

4,process字段包含init執行的進程,該進程採用的格式與在命令行下運行該進程的格式一樣,因此process字段都以該進程的名字開頭,緊跟着是運行時,緊跟着是運行時要傳遞給該進程的參數。比如/sbin/shutdown -t3 -r now,該進程在按下Ctrl+Alt+Del時執行,在命令行下也可以直接輸入來重新啓動系統。

 

四、例子

仔細學習例子文件,學習應用其中關於inittab的語法格式。該文件的大多數內容都可以忽略,因爲超過一半的內容都是註釋,剩餘的一些文件內容主要是用來實現某些特殊的功能:

    id 的值表明缺省的runlevel是3。
    ud 的值可以喚醒/sbin/update進程,該進程爲保持磁盤的完整性,將在對磁盤進行I/O操作之前清空整個I/O緩衝區。
    pf、pr和ca的值只被特定的中斷所調用。
    如果系統是專用的X終端,則只需x的輸入值。
    getty進程來提供虛擬終端設備的服務,例如:
    3:2345:respawn:/sbin/mingetty tty3
    標籤字段的值是3,3是設備tty3的數字後綴,tty3與相應的進程相關聯,該getty進程可以啓動的runlevel是2、3、4和5,當該進程終止時,init馬上就重新啓動它。啓動進程的路徑名是/sbin/mingetty,該進程是實現虛擬終端支持的最小版本的getty,爲tty3提供啓動虛擬設備的進程。
    si::sysinit:/etc/rc.d/rc.sysinit

    該值告訴init程序運行/etc/rc.d/rc.sysinit腳本文件來初始化系統,該腳本文件與所有啓動的腳本類似,它只是一個包含Linux的 shell命令的可執行文件,注意輸入的字符串必須包括該腳本的完整路徑。不同版本的Linux存放該腳本的位置也不相同,但不用刻意去記憶這些位置,只需查看/etc/inittab文件即可,該文件中包含啓動腳本文件的確切位置。


另一篇文章介紹:

嵌入式系統下的linux啓動配置文件,不同與普通的PC linux啓動配置,啓動相關文件與文件的內容也要少得多。嵌入式系統下的linux啓動過程一般是:
    1 在bootloader中制定各種要求傳給linux內核的參數,製作ramdisk或ramfs文件系統,並在開機後首先mount上,該文件系統主要負責包含啓動運行的配置文件,嵌入式系統主要是/etc/inittab和/etc/rc文件;
    2 在init進程啓動後,進程首先執行/etc/inittab文件,該文件語法下面介紹,一般包括三項內容就可以啓動。其中主要的一項內容就是::sysinit:/etc/rc,目的是制定初始化要執行的腳本配置文件,在/etc/rc中則主要是配置系統;另一項內容是::respawn:-/usr/sbin/xxx,xxx一般爲shell,最後一個重要的項是::shutdown:/bin/umount -a -r

首先介紹點背景知識,關於inittab的:

init進程是系統中所有進程的父進程,init進程繁衍出完成通常操作所需的子進程,這些操作包括:設置機器名、檢查和安裝磁盤及文件系統、啓動系統日誌、配置網絡接口並啓動網絡和郵件服務,啓動打印服務等。Solaris中init進程的主要任務是按照inittab文件所提供的信息創建進程,由於進行系統初始化的那些進程都由init創建,所以init進程也稱爲系統初始化進程。
       下面具體說明inittab文件的格式。
  inittab文件中每一記錄都從新的一行開始,每個記錄項最多可有512個字符,每一項的格式通常如下:id:rstate:action:process,下面分別解釋。
  1.id字段是最多4個字符的字符串,用來唯一標誌表項。
  2.rstate(run state)字段定義該記錄項被調用時的運行級別,rstate可以由一個或多個運行級別構成,也可以是空,空則代表運行級別0~6。當請求init改變運行級別時,那些rstate字段中不包括新運行級別的進程將收到SIGTERM警告信號,並且最後被殺死;只有a、b、c啓動的命令外(a、b、c不是真正的運行級別)
  3.action字段告訴init執行的動作,即如何處理process字段指定的進程,action字段允許的值及對應的動作分別爲:
         1)respawn:如果process字段指定的進程不存在,則啓動該進程,init不等待處理結束,而是繼續掃描inittab文件中的後續進程,當這樣的進程終止時,init會重新啓動它,如果這樣的進程已存在,則什麼也不做。
         2)wait:啓動process字段指定的進程,並等到處理結束纔去處理inittab中的下一記錄項。
         3)once:啓動process字段指定的進程,不等待處理結束就去處理下一記錄項。當這樣的進程終止時,也不再重新啓動它,在進入新的運行級別時,如果這樣的進程仍在運行,init也不重新啓動它。
         4)boot:只有在系統啓動時,init才處理這樣的記錄項,啓動相應進程,並不等待處理結束就去處理下一個記錄項。當這樣的進程終止時,系統也不重啓它。
         5)bootwait:系統啓動後,當第一次從單用戶模式進入多用戶模式時處理這樣的記錄項,init啓動這樣的進程,並且等待它的處理結束,然後再進行下一個記錄項的處理,當這樣的進程終止時,系統也不重啓它。
         6)powerfail:當init接到斷電的信號(SIGPWR)時,處理指定的進程。
         7)powerwait:當init接到斷電的信號(SIGPWR)時,處理指定的進程,並且等到處理結束纔去檢查其他的記錄項。
         8)off:如果指定的進程正在運行,init就給它發SIGTERM警告信號,在向它發出信號SIGKILL強制其結束之前等待5秒,如果這樣的進程不存在,則忽略這一項。
         9)ondemand:功能通respawn,不同的是,與具體的運行級別無關,只用於rstate字段是a、b、c的那些記錄項。
            10)sysinit:指定的進程在訪問控制檯之前執行,這樣的記錄項僅用於對某些設備的初始化,目的是爲了使init在這樣的設備上向用戶提問有關運行級別的問題,init需要等待進程運行結束後才繼續。
         11)initdefault:指定一個默認的運行級別,只有當init一開始被調用時才掃描這一項,如果rstate字段指定了多個運行級別,其中最大的數字是默認的運行級別,如果rstate字段是空的,init認爲字段是0123456,於是進入級別6,這樣便陷入了一個循環,如果 inittab文件中沒有包含initdefault的記錄項,則在系統啓動時請求用戶爲它指定一個初始運行級別
  4.Process字段中進程可以是任意的守候進程、可執行腳本或程序。
  另外:在任何時候,可以在文件inittab中添加新的記錄項,級別Q/q不改變當前的運行級別,重新檢查inittab文件,可以通過命令init Q或init q使init進程立即重新讀取並處理文件inittab

以上這些都是介紹的標準的linux System V的標準,所以對嵌入式來講有些東西並不見得有用!這裏介紹點針對嵌入式的,也就是針對busybox init的:

busybox的init

   除了基本的命令之外,BusyBox還支持init功能,如同其它的init一樣,busybox的init也是完成系統的初始化工作,關機前的工作等等,我們知道在Linux的內核被載入之後,機器就把控制權轉交給內核,linux的內核啓動之後,做了一些工作,然後找到根文件系統裏面的init程序,並執行它,BusyBox的init進程會依次進行以下工作:(參考<<構建嵌入式LINUX系統>> p201)

1.       爲init設置信號處理過程

2.       初始化控制檯

3.       剖析/etc/inittab文件

4.       執行系統初始化命令行,缺省情況下會使用/etc/init.d/rcS

5.       執行所有導致init暫停的inittab命令(動作類型:wait)

6.       執行所有僅執行一次的inittab(動作類型:once)

一旦完成以上工作,init進程便會循環執行以下進程:

       1.  執行所有終止時必須重新啓動的inittab命令(動作類型:once)

       2.  執行所有終止時必須重新啓動但啓動前必須詢問用戶的inittab命令(動作類型:askfirst)

       初始化控制檯之後,BusyBox會檢查/etc/inittab文件是否存在,如果此文件不存在,BusyBox會使用缺省的inittab配置,它主要爲系統重引導,系統掛起以及init重啓動設置缺省的動作,此外它還會爲四個虛擬控制檯(tty1到tty4)設置啓動shell的動作。如果未建立這些設備文件,BusyBox會報錯。

       inittab文件中每一行的格式如下所示:(busybox的根目錄下的example文件夾下有詳盡的inittab文件範例)     

       id:runlevel:action:process

儘管此格式與傳統的Sytem V init類似,但是,id在BusyBox的init中具有不同的意義。對BusyBox而言,id用來指定啓動進程的控制tty。如果所啓動的進程並不是可以交互的shell,例如BusyBox的sh(ash),應該會有個控制tty,如果控制tty不存在,Busybox的sh會報錯。BusyBox將會完全忽略runlevel字段,所以空着它就行了,你也許會問既然沒用保留着它幹嗎,我想大概是爲了和傳統的Sytem V init保持一致的格式吧。process字段用來指定所執行程式的路徑,包括命令行選項。action字段用來指定下面表中8個可應用到process的動作之一。

動作
 結果
 
sysinit
 爲init提供初始化命令行的路徑
 
respawn
 每當相應的進程終止執行便會重新啓動
 
askfirst
 類似respawn,不過它的主要用途是減少系統上執行的終端應用程序的數量。它將會促使init在控制檯上顯示“Please press Enter to active this console”的信息,並在重新啓動之前等待用戶按下enter鍵
 
wait
 告訴init必須等到相應的進程完成之後才能繼續執行
 
once
 僅執行相應的進程一次,而且不會等待它完成
 
ctratldel
 當按下Ctrl+Alt+Delete組合鍵時,執行相應的進程
 
shutdown
 當系統關機時,執行相應的進程
 
restart
 當init重新啓動時,執行相應的進程,通常此處所執行的進程就是init本身
 

 

以下是我的usblinux的inittab文件

::sysinit:/etc/init.d/rcS

::respawn:/sbin/getty  115200  tty1

tty2::askfirst:-/bin/sh

tty3::askfirst:-/bin/sh

::restart:/sbin/init

::ctrlaltdel:/bin/umount -a -r

這個inittab執行下列動作

1.       將/etc/init.d/rcS設置成系統的初始化文件

2.       在115200 bps的虛擬終端tty1上啓動一個登陸會話 (注意getty的用法)

3.       在虛擬終端tty2和tty3上啓動askfirst動作的shell

4.       如果init重新啓動,將/sbin/init設置成它會執行的程序

5.       告訴init,在系統關機的時候執行umount命令卸載所有文件系統,並且在卸載失敗時用只讀模式衝新安裝以保護文件系統。

 

 

1、busybox的inittab與pc使用的inittab不同,第一ID並不是隨便取名字的,這個名字要與/dev/目錄下是否有對應的文件對應

對應錯誤

 

can't open /dev/0: No such file or directory

process '-/bin/sh' (pid 789) exited. Scheduling for restart.

can't open /dev/0: No such file or directory

process '-/bin/sh' (pid 793) exited. Scheduling for restart.

2、出現下面這種錯誤:

process '-/bin/sh' (pid 789) exited. Scheduling for restart.

process '-/bin/sh' (pid 794) exited. Scheduling for restart.

process '-/bin/sh' (pid 796) exited. Scheduling for restart.

process '-/bin/sh' (pid 798) exited. Scheduling for restart.

對應的inittab文件中有

ttyS0::askfirst:-/bin/sh

雖然在/dev/目錄下有ttyS0設備,但是這個設備顯然不可用,所以纔會出現上面的錯誤

3、當在inittab中同時定義的兩個在同一個串口終端登陸的語句時

::askfirst:-/bin/sh

s3c2410_serial0:23456:respawn:/sbin/getty -L s3c2410_serial0 115200 vt100

出現的情況就是被搶佔,不能接收任何串口輸入

4、bad inittab entry

多半時因爲非法字符造成的。

 

5、busybox中的字段runleve也沒有運行時的運行級別的概念

 

6、分析一下啓動的過程

1.       爲init設置信號處理過程

2.       初始化控制檯

3.       剖析/etc/inittab文件

4.       執行系統初始化命令行,缺省情況下會使用/etc/init.d/rcS

5.       執行所有導致init暫停的inittab命令(動作類型:wait)

6.       執行所有僅執行一次的inittab(動作類型:once)

一旦完成以上工作,init進程便會循環執行以下進程:

       1.  執行所有終止時必須重新啓動的inittab命令(動作類型:once)

       2.  執行所有終止時必須重新啓動但啓動前必須詢問用戶的inittab命令(動作類型:askfirst)

       初始化控制檯之後,BusyBox會檢查/etc/inittab文件是否存在,如果此文件不存在,BusyBox會使用缺省的inittab配置,它主要爲系統重引導,系統掛起以及init重啓動設置缺省的動作,此外它還會爲四個虛擬控制檯(tty1到tty4)設置啓動shell的動作。如果未建立這些設備文件,BusyBox會報錯。

 

7、網上有人問“-”的作用

我很納悶:
:: respawn:-/bin/sh
這個-是幹什麼的,爲什麼有的時候有有的時候沒有???
還有啊,我從網上看到一個例程,如下,節選:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清兩個的區別,這樣控制檯就啓動了,是第一句啓動的還是第二句,那我內核啓動參數裏面的console=ttyS0會自動來找這個控制檯???

原帖由 wavezone 於 2008-8-22 16:34 發表 
我很納悶:
:: respawn:-/bin/sh
這個-是幹什麼的,爲什麼有的時候有有的時候沒有???
還有啊,我從網上看到一個例程,如下,節選:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清兩個的區別 ...

 

測試的時候是這樣的,加上”-”的語句會在登陸終端之後調用/etc/目錄下的profile文件,而不加”-”的不會執行這個腳本。

其實登陸終端的命令有幾種方便,但是標準的還是使用getty來登陸,但是直接使用如上的語句也是可以的,並且兼容性強一點,因爲它不需要指定對應的串口設備。

::askfirst:-/bin/sh

s3c2410_serial0::askfirst:-/bin/sh

::askfirst:-/bin/sh

s3c2410_serial0:23456:respawn:/sbin/getty -L s3c2410_serial0 115200 vt100

都是可用的。

 
8./bin/sh: XXX not found
arm-linux-readelf -d xxx
查看你的以用程序依賴哪些庫
一般是因爲缺少libc.so.6造成的,實際還是根文件系統的問題,沒有將常用的庫文件拷貝到/lib目錄下
常用的庫:

[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/ld* .

[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libc-2.3.2.so .

[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libc.so.6 .

[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libm * .

[root@centos lib]cp /usr/local/arm/3.4.1/arm-linux/lib/libcrypt* .

9、錯誤insmod: chdir(2.6.26.6): No such file or directory

網上有人提出這種解決方法:

需要注意的是insmod等模塊加載命令需要從lib/modules/2.6.26.6

的目錄下加載模塊,所以必須先建立此目錄,然後將模塊放到此目錄下面,否則將出現以下兩種情況:

一是沒有建立lib/modules/2.6.26.6目錄,取決於內核版本號,將出現insmod: chdir(2.6.26.6): No such file or directory的錯誤

二是隻將模塊簡單地放在根目錄或其它文件夾,沒有將其拷貝到指定的lib/modules/2.6.26.6目錄,將出現

insmod: module 'gpio_driver' not found錯誤

不過這種方法不是很奏效

 

根本原因是insmod的問題,在busybox編譯的時候參考下面的選項,不要使用

Linux Module Utilities --->

  [ ] Simplified modutils

//該選項不要選擇

[*] Support version 2.6.x Linux kernels 

//此選項選上

參考如下:

 

 


 

 

10、不能執行”-h”命令

在執行xxx –h時沒有任何反應。是在lib目錄下缺少常見的庫文件

參考如下:

[root@vm-dev rootfs]# ls lib/

ld-2.3.6.so               libc-2.3.6.so      libgcc_s.so      libnsl.so.1             libnss_files.so.2        libnss_nis.so.2     librt-2.3.6.so       libthread_db.so.1

ld-linux.so.2             libcrypt-2.3.6.so  libgcc_s.so.1    libnss_compat-2.3.6.so  libnss_hesiod-2.3.6.so   libpcprofile.so     librt.so.1           libutil-2.3.6.so

libanl-2.3.6.so           libcrypt.so.1      libm-2.3.6.so    libnss_compat.so.2      libnss_hesiod.so.2       libpthread-0.10.so  libSegFault.so       libutil.so.1

libanl.so.1               libc.so.6          libmemusage.so   libnss_dns-2.3.6.so     libnss_nis-2.3.6.so      libpthread.so.0     libtermcap.so.2      modules

libBrokenLocale-2.3.6.so  libdl-2.3.6.so     libm.so.6  libnss_dns.so.2         libnss_nisplus-2.3.6.so  libresolv-2.3.6.so  libtermcap.so.2.0.8

libBrokenLocale.so.1      libdl.so.2         libnsl-2.3.6.so  libnss_files-2.3.6.so   libnss_nisplus.so.2      libresolv.so.2      libthread_db-1.0.so



 

一份完整的inittab文件

引用內容:
    #
    # inittab       This file describes how the INIT process should set up
    #               the system in a certain run-level.
    #
    # Author:       Miquel van Smoorenburg, 
    #               Modified for RHS Linux by Marc Ewing and Donnie Barnes
    #
                                                                                                                             
    # Default runlevel. The runlevels used by RHS are:
    #   0 - halt (Do NOT set initdefault 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章