制作嵌入式根文件系統常見(jiàn)問(wèn)題詳解
首先介紹點(diǎn)背景知識,關(guān)于inittab的:
本文引用地址:http://dyxdggzs.com/article/241288.htminit進(jìn)程是系統中所有進(jìn)程的父進(jìn)程,init進(jìn)程繁衍出完成通常操作所需的子進(jìn)程,這些操作包括:設置機器名、檢查和安裝磁盤(pán)及文件系統、啟動(dòng)系統日志、配置網(wǎng)絡(luò )接口并啟動(dòng)網(wǎng)絡(luò )和郵件服務(wù),啟動(dòng)打印服務(wù)等。Solaris中init進(jìn)程的主要任務(wù)是按照inittab文件所提供的信息創(chuàng )建進(jìn)程,由于進(jìn)行系統初始化的那些進(jìn)程都由init創(chuàng )建,所以init進(jìn)程也稱(chēng)為系統初始化進(jìn)程。
下面具體說(shuō)明inittab文件的格式。
inittab文件中每一記錄都從新的一行開(kāi)始,每個(gè)記錄項最多可有512個(gè)字符,每一項的格式通常如下:id:rstate:action:process,下面分別解釋。
1.id字段是最多4個(gè)字符的字符串,用來(lái)唯一標志表項。
2.rstate(run state)字段定義該記錄項被調用時(shí)的運行級別,rstate可以由一個(gè)或多個(gè)運行級別構成,也可以是空,空則代表運行級別0~6。當請求init改變運行級別時(shí),那些rstate字段中不包括新運行級別的進(jìn)程將收到SIGTERM警告信號,并且最后被殺死;只有a、b、c啟動(dòng)的命令外(a、b、c不是真正的運行級別)
3.action字段告訴init執行的動(dòng)作,即如何處理process字段指定的進(jìn)程,action字段允許的值及對應的動(dòng)作分別為:
1)respawn:如果process字段指定的進(jìn)程不存在,則啟動(dòng)該進(jìn)程,init不等待處理結束,而是繼續掃描inittab文件中的后續進(jìn)程,當這樣的進(jìn)程終止時(shí),init會(huì )重新啟動(dòng)它,如果這樣的進(jìn)程已存在,則什么也不做。
2)wait:啟動(dòng)process字段指定的進(jìn)程,并等到處理結束才去處理inittab中的下一記錄項。
3)once:啟動(dòng)process字段指定的進(jìn)程,不等待處理結束就去處理下一記錄項。當這樣的進(jìn)程終止時(shí),也不再重新啟動(dòng)它,在進(jìn)入新的運行級別時(shí),如果這樣的進(jìn)程仍在運行,init也不重新啟動(dòng)它。
4)boot:只有在系統啟動(dòng)時(shí),init才處理這樣的記錄項,啟動(dòng)相應進(jìn)程,并不等待處理結束就去處理下一個(gè)記錄項。當這樣的進(jìn)程終止時(shí),系統也不重啟它。
5)bootwait:系統啟動(dòng)后,當第一次從單用戶(hù)模式進(jìn)入多用戶(hù)模式時(shí)處理這樣的記錄項,init啟動(dòng)這樣的進(jìn)程,并且等待它的處理結束,然后再進(jìn)行下一個(gè)記錄項的處理,當這樣的進(jìn)程終止時(shí),系統也不重啟它。
6)powerfail:當init接到斷電的信號(SIGPWR)時(shí),處理指定的進(jìn)程。
7)powerwait:當init接到斷電的信號(SIGPWR)時(shí),處理指定的進(jìn)程,并且等到處理結束才去檢查其他的記錄項。
8)off:如果指定的進(jìn)程正在運行,init就給它發(fā)SIGTERM警告信號,在向它發(fā)出信號SIGKILL強制其結束之前等待5秒,如果這樣的進(jìn)程不存在,則忽略這一項。
9)ondemand:功能通respawn,不同的是,與具體的運行級別無(wú)關(guān),只用于rstate字段是a、b、c的那些記錄項。
10)sysinit:指定的進(jìn)程在訪(fǎng)問(wèn)控制臺之前執行,這樣的記錄項僅用于對某些設備的初始化,目的是為了使init在這樣的設備上向用戶(hù)提問(wèn)有關(guān)運行級別的問(wèn)題,init需要等待進(jìn)程運行結束后才繼續。
11)initdefault:指定一個(gè)默認的運行級別,只有當init一開(kāi)始被調用時(shí)才掃描這一項,如果rstate字段指定了多個(gè)運行級別,其中最大的數字是默認的運行級別,如果rstate字段是空的,init認為字段是0123456,于是進(jìn)入級別6,這樣便陷入了一個(gè)循環(huán),如果 inittab文件中沒(méi)有包含initdefault的記錄項,則在系統啟動(dòng)時(shí)請求用戶(hù)為它指定一個(gè)初始運行級別
4.Process字段中進(jìn)程可以是任意的守候進(jìn)程、可執行腳本或程序。
另外:在任何時(shí)候,可以在文件inittab中添加新的記錄項,級別Q/q不改變當前的運行級別,重新檢查inittab文件,可以通過(guò)命令init Q或init q使init進(jìn)程立即重新讀取并處理文件inittab
以上這些都是介紹的標準的linux System V的標準,所以對嵌入式來(lái)講有些東西并不見(jiàn)得有用!這里介紹點(diǎn)針對嵌入式的,也就是針對busybox init的:
busybox的init
除了基本的命令之外,BusyBox還支持init功能,如同其它的init一樣,busybox的init也是完成系統的初始化工作,關(guān)機前的工作等等,我們知道在Linux的內核被載入之后,機器就把控制權轉交給內核,linux的內核啟動(dòng)之后,做了一些工作,然后找到根文件系統里面的init程序,并執行它,BusyBox的init進(jìn)程會(huì )依次進(jìn)行以下工作:(參考構建嵌入式LINUX系統>> p201)
1. 為init設置信號處理過(guò)程
2. 初始化控制臺
3. 剖析/etc/inittab文件
4. 執行系統初始化命令行,缺省情況下會(huì )使用/etc/init.d/rcS
5. 執行所有導致init暫停的inittab命令(動(dòng)作類(lèi)型:wait)
6. 執行所有僅執行一次的inittab(動(dòng)作類(lèi)型:once)
一旦完成以上工作,init進(jìn)程便會(huì )循環(huán)執行以下進(jìn)程:
1. 執行所有終止時(shí)必須重新啟動(dòng)的inittab命令(動(dòng)作類(lèi)型:once)
2. 執行所有終止時(shí)必須重新啟動(dòng)但啟動(dòng)前必須詢(xún)問(wèn)用戶(hù)的inittab命令(動(dòng)作類(lèi)型:askfirst)
初始化控制臺之后,BusyBox會(huì )檢查/etc/inittab文件是否存在,如果此文件不存在,BusyBox會(huì )使用缺省的inittab配置,它主要為系統重引導,系統掛起以及init重啟動(dòng)設置缺省的動(dòng)作,此外它還會(huì )為四個(gè)虛擬控制臺(tty1到tty4)設置啟動(dòng)shell的動(dòng)作。如果未建立這些設備文件,BusyBox會(huì )報錯。
inittab文件中每一行的格式如下所示:(busybox的根目錄下的example文件夾下有詳盡的inittab文件范例)
id:runlevel:action:process
盡管此格式與傳統的Sytem V init類(lèi)似,但是,id在BusyBox的init中具有不同的意義。對BusyBox而言,id用來(lái)指定啟動(dòng)進(jìn)程的控制tty。如果所啟動(dòng)的進(jìn)程并不是可以交互的shell,例如BusyBox的sh(ash),應該會(huì )有個(gè)控制tty,如果控制tty不存在,Busybox的sh會(huì )報錯。BusyBox將會(huì )完全忽略runlevel字段,所以空著(zhù)它就行了,你也許會(huì )問(wèn)既然沒(méi)用保留著(zhù)它干嗎,我想大概是為了和傳統的Sytem V init保持一致的格式吧。process字段用來(lái)指定所執行程式的路徑,包括命令行選項。action字段用來(lái)指定下面表中8個(gè)可應用到process的動(dòng)作之一。
sysinit: 為init提供初始化命令行的路徑
respawn: 每當相應的進(jìn)程終止執行便會(huì )重新啟動(dòng)
askfirst: 類(lèi)似respawn,不過(guò)它的主要用途是減少系統上執行的終端應用程序的數量。它將會(huì )促使init在控制臺上顯示“Please press Enter to active this console”的信息,并在重新啟動(dòng)之前等待用戶(hù)按下enter鍵
wait: 告訴init必須等到相應的進(jìn)程完成之后才能繼續執行
once:僅執行相應的進(jìn)程一次,而且不會(huì )等待它完成
ctratldel: 當按下Ctrl+Alt+Delete組合鍵時(shí),執行相應的進(jìn)程
shutdown: 當系統關(guān)機時(shí),執行相應的進(jìn)程
restart: 當init重新啟動(dòng)時(shí),執行相應的進(jìn)程,通常此處所執行的進(jìn)程就是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
這個(gè)inittab執行下列動(dòng)作
1. 將/etc/init.d/rcS設置成系統的初始化文件
2. 在115200 bps的虛擬終端tty1上啟動(dòng)一個(gè)登陸會(huì )話(huà) (注意getty的用法)
3. 在虛擬終端tty2和tty3上啟動(dòng)askfirst動(dòng)作的shell
4. 如果init重新啟動(dòng),將/sbin/init設置成它會(huì )執行的程序
5. 告訴init,在系統關(guān)機的時(shí)候執行umount命令卸載所有文件系統,并且在卸載失敗時(shí)用只讀模式?jīng)_新安裝以保護文件系統。
1、busybox的inittab與pc使用的inittab不同,第一ID并不是隨便取名字的,這個(gè)名字要與/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設備,但是這個(gè)設備顯然不可用,所以才會(huì )出現上面的錯誤
3、當在inittab中同時(shí)定義的兩個(gè)在同一個(gè)串口終端登陸的語(yǔ)句時(shí)
::askfirst:-/bin/sh
s3c2410_serial0:23456:respawn:/sbin/getty -L s3c2410_serial0 115200 vt100
出現的情況就是被搶占,不能接收任何串口輸入
4、bad inittab entry
多半時(shí)因為非法字符造成的。
[next]
5、busybox中的字段runleve也沒(méi)有運行時(shí)的運行級別的概念
6、分析一下啟動(dòng)的過(guò)程
1. 為init設置信號處理過(guò)程
2. 初始化控制臺
3. 剖析/etc/inittab文件
4. 執行系統初始化命令行,缺省情況下會(huì )使用/etc/init.d/rcS
5. 執行所有導致init暫停的inittab命令(動(dòng)作類(lèi)型:wait)
6. 執行所有僅執行一次的inittab(動(dòng)作類(lèi)型:once)
一旦完成以上工作,init進(jìn)程便會(huì )循環(huán)執行以下進(jìn)程:
1. 執行所有終止時(shí)必須重新啟動(dòng)的inittab命令(動(dòng)作類(lèi)型:once)
2. 執行所有終止時(shí)必須重新啟動(dòng)但啟動(dòng)前必須詢(xún)問(wèn)用戶(hù)的inittab命令(動(dòng)作類(lèi)型:askfirst)
初始化控制臺之后,BusyBox會(huì )檢查/etc/inittab文件是否存在,如果此文件不存在,BusyBox會(huì )使用缺省的inittab配置,它主要為系統重引導,系統掛起以及init重啟動(dòng)設置缺省的動(dòng)作,此外它還會(huì )為四個(gè)虛擬控制臺(tty1到tty4)設置啟動(dòng)shell的動(dòng)作。如果未建立這些設備文件,BusyBox會(huì )報錯。
7、網(wǎng)上有人問(wèn)“-”的作用
我很納悶:
?。海?respawn:-/bin/sh
這個(gè)-是干什么的,為什么有的時(shí)候有有的時(shí)候沒(méi)有???
還有啊,我從網(wǎng)上看到一個(gè)例程,如下,節選:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清兩個(gè)的區別,這樣控制臺就啟動(dòng)了,是第一句啟動(dòng)的還是第二句,那我內核啟動(dòng)參數里面的console=ttyS0會(huì )自動(dòng)來(lái)找這個(gè)控制臺???
原帖由 wavezone 于 2008-8-22 16:34 發(fā)表
我很納悶:
?。海?respawn:-/bin/sh
這個(gè)-是干什么的,為什么有的時(shí)候有有的時(shí)候沒(méi)有???
還有啊,我從網(wǎng)上看到一個(gè)例程,如下,節選:
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
我搞不清兩個(gè)的區別 ...
測試的時(shí)候是這樣的,加上”-”的語(yǔ)句會(huì )在登陸終端之后調用/etc/目錄下的profile文件,而不加”-”的不會(huì )執行這個(gè)腳本。
其實(shí)登陸終端的命令有幾種方便,但是標準的還是使用getty來(lái)登陸,但是直接使用如上的語(yǔ)句也是可以的,并且兼容性強一點(diǎn),因為它不需要指定對應的串口設備。
::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
查看你的以用程序依賴(lài)哪些庫
一般是因為缺少libc.so.6造成的,實(shí)際還是根文件系統的問(wèn)題,沒(méi)有將常用的庫文件拷貝到/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
網(wǎng)上有人提出這種解決方法:
需要注意的是insmod等模塊加載命令需要從lib/modules/2.6.26.6
的目錄下加載模塊,所以必須先建立此目錄,然后將模塊放到此目錄下面,否則將出現以下兩種情況:
一是沒(méi)有建立lib/modules/2.6.26.6目錄,取決于內核版本號,將出現insmod: chdir(2.6.26.6): No such file or directory的錯誤
二是只將模塊簡(jiǎn)單地放在根目錄或其它文件夾,沒(méi)有將其拷貝到指定的lib/modules/2.6.26.6目錄,將出現
insmod: module 'gpio_driver' not found錯誤
不過(guò)這種方法不是很奏效
根本原因是insmod的問(wèn)題,在busybox編譯的時(shí)候參考下面的選項,不要使用
Linux Module Utilities --->
[ ] Simplified modutils
//該選項不要選擇
[*] Support version 2.6.x Linux kernels
//此選項選上
參考如下:
10、不能執行”-h”命令
在執行xxx –h時(shí)沒(méi)有任何反應。是在lib目錄下缺少常見(jiàn)的庫文件
參考如下:
[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
[root@vm-dev rootfs]#
linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)
pid控制相關(guān)文章:pid控制原理
pid控制器相關(guān)文章:pid控制器原理
評論