U盘中打造属于自己的Linux (四) :自己写 initrd step by step(下)
作者: 西格玛 分类: IT悟语, Linux, 老西常谈 标签: Linux 评论: 0
## 接上文 我们了解了initrd的cpio包的形成方式
并且大体搭建好了initrd下的内容,现在我们要完善我们的init引导流程 让我们跑起来的initramfs中的linux尽量的像真正的linux系统。
因为要经常调试内核与initrd文件 因此为了避免频繁的插拔U盘 我们采用一个优秀的cpu仿真软件,–qemu
# apt-get install qemu
# apt-get install qemu-launcher //图形界面程序
#qemu-launcher
启动程序,界面如下:
上面添入我们生成的内核文件
下面就是initrd文件了
参数中 linux noapic 是一个解决bug用的 大家不用介意 用就是了。
(否则会出现一个 BIOS bus 什么timer 同步啊….)
点击 launch 就和一个正常系统一样启动了
我们以这个工具查看我们initrd的修改程度。
首先解决上次那个can’t access tty问题:
linux有一个init模式,就是按照一个叫做inittab的配置文件加载各种进程,其中也包括shell环境
inittab 详细介绍
busybox的默认在没有inittab时按照如下规则运行:
:sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
如果busybox检测到/dev/console不是串口控制台,init还要执行下面的动作:
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
经分析(这个不是我分析的…)busybox的缺省init模式无法满足我们的要求,
我们还是要写inittab,定制自己的init初始化流程。
要写自己的inittab,需要理解busybox的inittab文件格式。
busybox的inittab文件与通常的inittab不同,它没有runlevel的概念,语句功能上也有限制。inittab语句的标准格式是
id::?: c
各字段的含义如下
id:
id字段与通常的inittab中的含义不同,它代表的是这个语句中process执行所在的tty设备,内容就是/dev目录中tty设备的文件名。由于是运行process的tty设备的文件名,所以也不能象通常的inittab那样要求每条语句id的值唯一。
:
busybox不支持runlevel,所以此字段完全被忽略。
:
为下列这些值之一:
sysinit, respawn, askfirst, wait,once, restart, ctrlaltdel, shutdown
其
含义与通常的inittab的定义相同。特别提一下askfirst,它的含义与respawn相同,只是在运行process前,会打出一句话
“please press Enter to active this console”,然后等用户在终端上敲入回车键后才运行process。
:
指定要运行的process的命令行。
我们参考一下 写出自己的inittab:
# cd /mnt/initrd/etc/
# vi inittab
———–inittab—————–
::sysinit:/etc/init.d/rcS //用rcS这个脚本作为系统的init引导脚本
tty1::askfirst:/bin/sh
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
tty5::askfirst:/bin/sh //用户工作环境 (shell bash)
tty6::askfirst:/bin/sh
::restart:/sbin/init //定义一些行为
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
————————————
这样系统引导时 内核就会顺着这个文件去找etc/init.d/rcS
这个文件与我们上次编写的init文件作用相同 因此我们把init文件移过去,改名为rcS
并且删去最后一行的/bin/sh
#mkdir /etc/init.d
#mv init etc/init.d/rcS
注意 这时候它仍是可执行的!
# vi rcS
————-rcS-(beta)—————–
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mdev -s
—————————————-
我们不需要那linuxrc 文件 而init文件还不能少 所以我们拆一下 吧linuxrc改为init
# mv linuxrc init
这样我们的修改就完成了,打包
(/mnt/initrd)
# find . |cpio -o -H newc | gzip > /mnt/自己起名吧…..
然后把内核 和initrd文件(刚做好的) 添入qemu 设置
启动 看看效果吧:
正常应该是输出一句
please press Enter to active this console
然后输入回车出现
#
但是事实上没任何提示 输入回车倒是能够正常使用
这是为什么呢?仔细观察 发现在加载硬件过程中 please press Enter to active this console
一闪而过 呵呵 原来我们在启动初始化时
mdev 与 rcS的加载时同步进行的
inittab rcS
rcS ——> rcS
tty 初始化 mdev -s
. .
结束 <—- .
.
.
就是说 在我们的init处理结束时 mdev 对硬件的识别还没有完成 这样吧信息刷屏过去了,不光如此 如果我们在init脚本中写了挂载命令 也一样可能失败 解决这个问题 我们可以让init 的 rcS中加入
sleep 10 让他等待10s 直到 mdev 加载完成
同时 我们为了支持热插拔 要加入以下句子:
echo /sbin/mdev > /proc/sys/kernel/hotplug
#vi etc/init.d/rcS
——————rcS (RC)————-
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
echo /sbin/mdev > /proc/sys/kernel/hotplug //热插拔
echo ‘waiting to load all devices…..’
mdev -s
sleep 10
——————————————–
重新打包 加载 OK 终端显示:
please press Enter to active this console
#
这样我们就可以正常的使用了 用alt+F1~6 还可以切换工作台 和正常的linux一样了
到此 我们U盘linux的主干部分已经全部完成了。
O(∩_∩)O哈哈~
但是现在我们的linux还运行在内存中 没法把东西保存 掉电就会丢失
最后的一部分 我们会挂载我们的U盘 保存用户数据 并且用switch_root 命令启动U盘上的根文件系统。
| anyShare分享到: | |
| |
05-30
2009
