[UP] add some viki files, knowledge.
[arrow.git] / viki / kernel / initramfs / do-initramfs-steps04.viki
blob9640f2f6517cc64057853e09f7746abd50f3b888
1  精通initramfs构建step by step (四):mini linux
3 十一、自动生成/dev下的设备文件
4 上节用chroot方法试验busybox时,为了简单,是用“绑定”的方式把主机的/dev中的设备文件映射到image目录下的dev目录。在initramfs上,这种方法显然不能使用。
5 生成系统的设备文件,现在通常都是用udev动态生成,而initramfs为了做到通用,动态生成的要求是必须的。在busybox中有一个mdev命令,就是用来动态生成设备文件,填充到/dev目录的。
6 在系统启动时,用
7 mdev -s
8 命令可以根据内核的sysfs文件系统在/dev目录中自动生成相应的设备文件。命令执行前,需要先挂载内核的proc和sysfs虚拟文件系统。
10 十二、初始身手
11 解决了自动生成设备文件的问题后,我们可以试着做一个最简单的可运行的linux系统了:
12 (1)在image目录下写一个最简单的init脚本。
13 #!/bin/sh
14 mount -t proc proc /proc
15 mount -t sysfs sysfs /sys
16 mdev -s
17 /bin/sh
18 (2)为init脚本设置可执行权限,否则内核不会去执行它。
19 chmod +x init
20 (3)有些busybox配置中,mdev命令需要读取/etc/mdev.conf文件,为了避免出错信息,我们创建一个空文件。mdev.conf文件是用来控制mdev生成的设备文件的读写权限的,在这里我们不需要对设备文件设置特别的权限,就使用mdev缺省的660的权限设置。有关mdev的设备文件权限的控制详细信息,可参考busybox源码树docs目录下的mdev.txt文件。
21 touch etc/mdev.conf
22 (4)在内核源码目录下,执行
23 make
24 命令,重新编译内核,生成新的initramfs。
26 好了,在QEMU模拟环境下启动这个新的内核,系统初始化后,会进入SHELL环境。在这个SHELL环境下,试验一些常用命令,看看是否可以正常运行。
28 十三、can't access tty
29 上一步创建的简单linux系统在进入SHELL环境时,会打出下面这一句出错信息:
30 /bin/sh: can't access tty; job controll off
31 虽然不影响使用,但终究不够完美。
32 产生这个错误的原因是我们的SHELL是直接运行在内核的console上的,而console是不能提供控制终端(terminal)功能的,所以必须把 SHELL运行在tty设备上,才能消除这个错误。解决问题的办法是使用正规init机制,在执行SHELL前打开tty设备。
33 另外,这个简单系统的reboot、halt等命令是不起作用的,也必须通过init方式解决。
35 十四、busybox的缺省init模式
36 busybox支持init功能,当系统没有/etc/inittab文件时,它有一套缺省的模式,按下面配置执行:
37 ::sysinit:/etc/init.d/rcS
38 ::askfirst:/bin/sh
39 ::ctrlaltdel:/sbin/reboot
40 ::shutdown:/sbin/swapoff -a
41 ::shutdown:/bin/umount -a -r
42 ::restart:/sbin/init
43 如果busybox检测到/dev/console不是串口控制台,init还要执行下面的动作:
44 tty2::askfirst:/bin/sh
45 tty3::askfirst:/bin/sh
46 tty4::askfirst:/bin/sh
47 我们试试这种模式是否可以解决我们的问题。
48 (1)写/etc/init.d/rcS脚本
49 这个脚本实际是要执行系统的初始化操作。我们把前面的init脚本改造一下,将最后的/bin/sh命令删除,然后移到 etc/init.d目录下,改名为rcS。
50 (2)initramfs不需要linuxrc,而且如果没有init文件,内核就不认为它是一个有效的initramfs,因而不安装它,导致内核panic。于是,我们在image目录下,把busybox安装的linuxrc改名为init:
51 mv linuxrc init
52 (3)重新编译内核,生成新的initramfs
53 (4)用QEMU试验一下新编译的内核。系统启动后,会打出一句话“please press Enter to active this console”——感觉还不错。但是按下回车键后,系统依然会打出错误信息“-/bin/sh:
54 can't access tty; job controll off ”。用tty命令看看当前的终端设备文件名:
55 # tty
56 /dev/console
57 它还是console,不是tty设备,所以问题没有解决。不过,reboot和halt命令倒是可以正常工作了。
59 经过验证,busybox的缺省init模式无法满足我们的要求,我们还是要写inittab,定制自己的init初始化流程。
61 十五、busybox的inittab文件格式说明
62 要写自己的inittab,需要理解busybox的inittab文件格式。
63 busybox的inittab文件与通常的inittab不同,它没有runlevel的概念,语句功能上也有限制。inittab语句的标准格式是
64 <id>:<runlevels>:<action>:<process>
65 各字段的含义如下
66 <id>:
67 id字段与通常的inittab中的含义不同,它代表的是这个语句中process执行所在的tty设备,内容就是/dev目录中tty设备的文件名。由于是运行process的tty设备的文件名,所以也不能象通常的inittab那样要求每条语句id的值唯一。
68 <runlevels>:
69 busybox不支持runlevel,所以此字段完全被忽略。
70 <action>:
71 为下列这些值之一:
72 sysinit, respawn, askfirst, wait,once, restart, ctrlaltdel, shutdown
73 其含义与通常的inittab的定义相同。特别提一下askfirst,它的含义与respawn相同,只是在运行process前,会打出一句话 “please press Enter to active this console”,然后等用户在终端上敲入回车键后才运行process。
74 <process>:
75 指定要运行的process的命令行。
77 十六、写mini linux的inittab
78 理解了busybox的inittab格式,我们就可以写mini linux的inittab:
79 ::sysinit:/etc/init.d/rcS
80 tty1::askfirst:/bin/sh
81 tty2::askfirst:/bin/sh
82 tty3::askfirst:/bin/sh
83 tty4::askfirst:/bin/sh
84 tty5::askfirst:/bin/sh
85 tty6::askfirst:/bin/sh
86 ::restart:/sbin/init
87 ::ctrlaltdel:/sbin/reboot
88 ::shutdown:/bin/umount -a -r
90 把这个文件放到image的etc目录下。为了执行reboot命令时避免提示找不到/etc/fstab文件,我们再在etc目录下创建一个空文件:
91 touch fstab
93 做好了这些,就可以重新编译内核,生成新的initramfs了。在QEMU试验环境下验证新生成的mini linux,系统运行正常,而且象通常的linux系统一样,用ALT+F1~F6键可以在6个终端间切换。
94 由于mini linux系统不需要登录,所以用askfirst的方式来模拟登录,用户敲回车键后,init进程才会启动shell。
97 ---下节预告---
98 目前为止,我们的initramfs都由内核编译系统生成的,并链接到内核中。其实我们也可以用cpio命令生成单独的initramfs,与内核编译脱钩,在内核运行时以initrd的形式加载到内核,以增加灵活性。请看下一个step:
99 精通initramfs构建step by step (五):initrd