1) 标准的根文件系统目录如下:
Directory | Content |
---|---|
bin | Essential user command binaries |
boot | Static files used by the bootloader |
dev | Devices and other special files |
etc | System configuration files, including startup files |
home | User home directories, including entries for services such as FTP |
lib | Essential libraries, such as the C library, and kernel modules |
mnt | Mount point for temporarily mounted filesystems |
opt | Add-on software packages |
proc | Virtual filesystem for kernel and process information |
root | Root user's home directory |
sbin | Essential system administration binaries |
tmp | Temporary files |
usr | Secondary hierarchy containing most applications and documents useful to most users, including the X server |
var | Variable data stored by daemons and utilities |
其中这些目录(/home, /mnt, /opt, and /root)多用于多用户环境可以删除,当然也可以删除 /tmp and /var目录,不过最好保留住这两个目录。
/boot 的取舍取决于bootloader,如果bootloader能在内核启动前获得内核镜像,就可以移除/boot目录,否则请保留。
这时剩下的 /bin, /dev, /etc, /lib, /proc, /sbin, and /usr, 为必需目录,当然,特殊情形下除外。
现在开始创建根文件系统:
$mkdir bin dev etc lib proc sbin tmp usr var
$chmod 1777 tmp/ 目的是在/tmp下创建的文件只能由文件的创建者删除,
接着创建/usr目录结构
$ mkdir usr/bin usr/lib usr/sbin
最后创建/var目录结构
$ mkdir var/lib var/lock var/log var/run var/tmp
$ chmod 1777 var/tmp
这样根文件系统的骨架已经创建完毕,开始在适当的位置添加各种应用程序和软件。
2) 添加库文件
库文件主要有四种:共享库文件,主修订版本符号链接,版本无关的符号链接(指向主修订版本符号链接),静态库文件。
共享库文件:命名格式 libLIBRARY_NAME-GLIBC_VERSION.LIBRARY_NAME 是该共享库的名字,GLIBC_VERSION 是使用的 glibc库的版本号,
例如:glibc 2.2.3 使用的数学库文件为 libm-2.2.3.so.
主修订版本符号链接:命名格式libLIBRARY_NAME.so.MAJOR_REVISION_VERSION ,MAJOR_REVISION_VERSION是共享库的主修订版本号,
例如: For the actual C library, the symbolic link is libc.so.6. For libdl, it islibdl.so.2.
版本无关的符号链接(指向主修订版本符号链接):为使用某个共享库的程序提供一个通用的接口。不用关注该共享库的主版本好,
命名规则libLIBRARY_NAME.so, 例如: libm.so points tolibm.so.6, which itself points to the actual shared library,libm-2.2.3.so.
有个例外情况 libc.so。版本无关的符号链接(指向主修订版本符号链接)主要在链接程序的时候使用。
静态库文件:命名规则libLIBRARY_NAME.a,
上述的四种文件,我们常用共享库文件和主修订版本符号链接这两个,另外两个仅在链接可执行程序时使用,运行时不需要。
$ cd ${TARGET_PREFIX}/lib $ for file in libc libcrypt libdl libm \ > libpthread libresolv libutil > do > cp $file-*.so ${PRJROOT}/rootfs/lib > cp -d $file.so.[*0-9] ${PRJROOT}/rootfs/lib > done $ cp -d ld*.so* ${PRJROOT}/rootfs/lib
$ cd ${TARGET_PREFIX}/lib $ cp *-*.so ${PRJROOT}/rootfs/lib $ cp -d *.so.[*0-9] ${PRJROOT}/rootfs/lib $ cp libSegFault.so libmemusage.so libpcprocfile.so \ > ${PRJROOT}/rootfs/lib
Filename | Description | Type | Major number | Minor number | Permission bits |
---|---|---|---|---|---|
mem | Physical memory access | char | 1 | 1 | 600 |
null | Null device | char | 1 | 3 | 666 |
zero | Null byte source | char | 1 | 5 | 666 |
random | Nondeterministic random number generator | char | 1 | 8 | 644 |
tty0 | Current virtual console | char | 4 | 0 | 600 |
tty1 | First virtual console | char | 4 | 1 | 600 |
ttyS0 | First UART serial port | char | 4 | 64 | 600 |
tty | Current TTY device | char | 5 | 0 | 666 |
console | System console | char | 5 | 1 | 600 |
创建设备节点常用命令
# mknod -m 600 mem c 1 1
# mknod -m 666 null c 1 3
# mknod -m 666 zero c 1 5
# mknod -m 644 random c 1 8
除基本的设备节点外还需要创建一些特殊设备符号链接
Link name | Target |
---|---|
fd | /proc/self/fd |
stdin | fd/0 |
stdout | fd/1 |
stderr | fd/2 |
Because /sbin/init is a symbolic link to /bin/busybox, BusyBox is the first application to run on the target system. BusyBox identifies that the command being invoked is init
and immediately jumps to the init routine. BusyBox’s init routine carries out the following main tasks in order. (Action types are defined in the inittab file, described later in this section.)
1. Sets up signal handlers for init.
2. Initializes the console. By default, it uses the device specified with the kernel’s console boot option. If no console was specified to the kernel,
BusyBox tries touse /dev/console.
3. Parses the inittab file, /etc/inittab.
4. Runs the system initialization script. (/etc/init.d/rcS is the default for BusyBox.)
5. Runs all the inittab commands that block (action type: wait).
6. Runs all the inittab commands that run only once (action type: once).
After completing these steps, the init routine loops forever, carrying out the following tasks:
1. Runs all the inittab commands that have to be respawned (action type: respawn).
2. Runs all the inittab commands that have to be asked for first (action type: askfirst).
3. Waits for child processes to exit.
Each line in the inittab file follows this format:
id:runlevel:action:process
the id is used to specify the con-
trolling tty for the process to be started. If you leave this entry empty, BusyBox init will
use the system console, which is fine when the process to be started isn’t an interactive
shell, or when you start a shell on the console. BusyBox completely ignores the
runlevel field, so you can leave it blank. The process field specifies the path of the
program to run, along with its command-line options. The action field is one of eight
recognized actions to be applied to process, as described in Table 6-6.
Table 6-6. Types of inittab actions recognized by BusyBox init
Action Effect
sysinit Provides init with the path to the initialization script.
respawn Restarts the process every time it terminates.
askfirst Similar to respawn, but is mainly useful for reducing the number of terminal applications running on the system. It prompts init to display “Please press
Enter to activate this console.” at the console and waits for the user to press Enter before starting the process.
wait Tells init that it has to wait for the process to complete before continuing.
once Runs the process only once without waiting for its completion.
ctrlaltdel Runs the process when the Ctrl-Alt-Delete key combination is pressed.
shutdown Runs the process before shutting the system down.
restart Runs the process when init restarts. Usually, the process to be run here is init itself.
The following is a simple inittab file for our control module:
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty 115200 ttyS0
::respawn:/control-module/bin/init
::restart:/sbin/init
::shutdown:/bin/umount -a -r
This inittab file does the following:
1. Sets /etc/init.d/rcS as the system initialization file.
2. Starts a login session on the serial port at 115200 bps.
3. Starts the control module’s custom software initialization script.
4. Sets /sbin/init as the program to execute if init restarts.
5. Tells init to run the umount command to unmount all filesystems it can at system
shutdown and set the others as read-only to preserve the filesystems.