您的位置:首页 > 其它

制作嵌入式根文件系统(常见问题详解)

2009-10-19 20:16 267 查看



document.body.oncopy = function() {
if (window.clipboardData) {
setTimeout(function() {
var text = clipboardData.getData("text");
if (text && text.length>300) {
text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href;
clipboardData.setData("text", text);
}
}, 100);
}
}

function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}

首先介绍点背景知识,关于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

[root@vm-dev rootfs]#
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: