西格玛向量™

U盘中打造属于自己的Linux (四) :自己写 initrd step by step(下)

作者: 西格玛   分类: IT悟语, Linux, 老西常谈   标签:    评论: 0

## 接上文 我们了解了initrd的cpio包的形成方式

  并且大体搭建好了initrd下的内容,现在我们要完善我们的init引导流程 让我们跑起来的initramfs中的linux尽量的像真正的linux系统。
  因为要经常调试内核与initrd文件 因此为了避免频繁的插拔U盘 我们采用一个优秀的cpu仿真软件,–qemu

# apt-get install qemu

# apt-get install qemu-launcher               //图形界面程序

#qemu-launcher

启动程序,界面如下:

 U盘中打造属于自己的Linux (四) :自己写 initrd step by step(下)

  上面添入我们生成的内核文件

下面就是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分享到: U盘中打造属于自己的Linux (四) :自己写 initrd step by step(下)
          
05-30
2009
loading...