U盘中打造属于自己的Linux (四) :自己写 initrd step by step(上)
作者: 西格玛 分类: IT悟语, Linux, 老西常谈 标签: Linux 评论: 0
###接上文 我们已经配置内核支持独立的initrd了 下面我们了解一下initrd的构造和配置方法:
工作目录
# cd /mnt/initrd
initrd 是一个小型的文件系统,因此 文件系统需要有的它基本都要有
# ls / 我们看看宿主机根文件系统中都有些什么
我们可以看到,其中浅蓝色的是一些链接文件
而在文件系统中 比较重要的是以下文件夹以及存放的内容:
######## 根目录下的文件夹们
/bin 二进制可执行命令
/dev 设备特殊文件
/etc 系统管理和配置文件
/etc/rc.d 启动的配置文件和脚本
/home 用户主目录的基点,比如用户user的主目录就是/home/user,可以用~user表示
/lib 标准程序设计库,又叫动态链接共享库,作用类似windows里的.dll文件
/sbin 系统管理命令,这里存放的是系统管理员使用的管理程序
/tmp 公用的临时文件存储点
/root 系统管理员的主目录(呵呵,特权阶级)
/mnt 系统提供这个目录是让用户临时挂载其他的文件系统。
/lost+found 这个目录平时是空的,系统非正常关机而留下“无家可归”的文件(windows下叫什么.chk)就在这里
/proc 虚拟的目录,是系统内存的映射。可直接访问这个目录来获取系统信息。
/var 某些大文件的溢出区,比方说各种服务的日志文件
/usr 最庞大的目录,要用到的应用程序和文件几乎都在这个目录。其中包含:
/usr/bin 众多的应用程序
/usr/sbin 超级用户的一些管理程序
/usr/doc linux文档
/usr/include linux下开发和编译应用程序所需要的头文件
/usr/lib 常用的动态链接库和软件包的配置文件
/usr/man 帮助文档
/usr/src 源代码,linux内核的源代码就放在/usr/src/linux里
/usr/local/bin 本地增加的命令
/usr/local/lib 本地增加的库
###############
我们的U盘linux没有这么多要求,分析一下我们只需要单用户 home地不要,特权root就行了,我们需要的部分如下:
# mkdir
bin dev etc lib mnt proc sbin sys usr
这样 我们initrd文件系统的骨架就算是建好了,虽然这个系统很小 但是功能不能少,但是功能需要的那些命令从什么地方来呢?
下面介绍一位帮手,这位在嵌入式领域里神通广大的万用通:busybox
busybox实际上是一个常用的二进制命令的软件包,它可以帮你把这些程序安装到指定的位置去。
我们到busybox官方网站上下载源码包。注意 又是源码包 不是一个现成的应用程序,呵呵 看来又要编译了。
# cd /home/你/
#mkdir busybox //编译环境目录
我们把下载好的源码压缩包放到这个目录下
#tar -jxvf busybox-XXXXX.tar.bz2 //解压
#make menuconfig //我们在菜单界面下配置我们的busybox 这里不详述配置了
#make defconfig //这里为了保证功能 我们推荐用默认配置 强调几点
########
Busybox Settings >
General Configuration >
[*] Support for devfs
Build Options >
[*] Build BusyBox as a static binary (no shared libs)
/* 将busybox编译为静态连接,少了启动时找动态库的麻烦 */
[*] Do you want to build BusyBox with a Cross Compiler?
(/usr/local/arm/3.3.2/bin/armlinux)
Cross Compiler prefix/* 指定交叉编译工具路径 */
Init Utilities >
[*] init
[*] Support reading an inittab file
/* 支持init读取/etc/inittab配置文件,一定要选上 */
Shells >
Choose your default shell (ash) >
/* (X) ash 选中ash,这样生成的时候才会生成bin/sh文件
#######
#make
不详述了 都知道make怎么回事了,编译后 我们生成的东西在busybox/busybox-XXXXX./_install 下
比如 我们要将其安装到 /mnt/initrd 下:
# make CONFIG_PREFIX=/mnt/initrd install 就可以了
#cd /mnt/initrd
# cd bin 或 sbin
就会看到 多了一堆牛X的命令 哈哈 可以用了
其实 其他所有的命令都只是一个指向busybox文件的链接
# ldd busybox
linux-gate.so.1 => (0xb806c000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb8036000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7ed3000)
/lib/ld-linux.so.2 (0xb806d000)
这说明这个程序需要一些库 我们需要从宿主机拷贝以下文件到/mnt/initrd/lib 文件夹下:
ld-linux.so.2
libc.so.6
libcrypt.so.1
libm.so.6
例如:cp /lib/tls/i686/cmov/libm.so.6 /mnt/initrd/lib/libm.so.6
到此 我们initrd的功能部分都由busybox摆平了,我们要做的就是使用它就是了。
回想一下 内核调用时 要先自爱initrd根目录下找到init这个文件 作为启动中pid=1的启动进程 负责处理系统启动的“后事”。
如果找不到这个文件,那么内核就不认为它是一个initrd文件。
但是,busybox的设置和默认的有些地方不一样 ,在busybox中 负责启动的是一个叫linuxrc的脚本 安装完你会发现它在
/mnt/initrd
文件夹下,它用于负责busybox 生成的文件系统的引导 ,但是我们看不到其中的内容,因此我们不用它 我们根据busybox的规则来尝试创建我们自己的启动规则
我们先在/mnt/initrd 下自己写一个init文件:
#vi init
我们首先要挂载必要的文件系统,并且要生成一些能够正确识别硬件设备的文件就是/dev下的内容,这里面实际上是为硬件提供了一堆接口
—————init————-
# !bin/sh //这是个脚本
mount -t proc proc /proc
mount -t sysfs sysfs /sys //挂载两个虚拟文件系统 其实是在内存中 与内核紧密相连
mdev -s //mdev是busybox提供的一个程序 可以识别硬件信息 并填充到/dev 目录下。
/bin/sh //调出shell
——————————-
# chmod a+x init //给与所有用户都能够执行的权限。
有些busybox配置中,mdev命令需要读取/etc/mdev.conf文件,为了避免出错信息,我们创建一个空文件。
# touch etc/mdev.conf
这样 内核就会在启动时找到我们写的init文件 并将其执行 完成初始化工作
上述调用的SHELL是直接运行在内核的console上的因此在initrd目录下,要创建一个dev/console的设备文件,否init程序无法在内核console中输出信息:
# mknod -m 600 dev/console c 5 1
console是不能提供控制终端(terminal)功能,因此上述方法还不完善,为了提早看到成果 我们先不将其更改 在此基础上生成一个initrd。
这里我们要用到cpio命令 因为initrd是cpio格式的。
# cd /mnt/initrd
# find . | cpio -o -H newc | gzip > /mnt/usblinux.img
找到文件夹下所有文件 输送 以cpio压缩 参数 输送 压缩 输出给文件
cpio 命令参数大家自己查 以上参数不可缺少!
到此 我们自己的initrd 就形成了 我们可以将其考入我们的U盘
# cp /mnt/usblinux.img /mnt/usb/boot/usblinux.img
如果有 覆盖掉我们之前“拿来”的img文件 然后修改grub.conf ;menu.lst
重新安装grub 后
# umount /mnt/usb
用U盘引导 我们就可以看到 在识别了一堆硬件之后 有如下状况:
/bin/sh: can’t access tty; job controll off
然后一般按下回车 就会出现
#
试一下 是不是很像一个正常的linux系统?
上面的错误信息是因为我们还泡在 console状态下 而不是分配的tty shell 因此我们还需要调整。
#########
| anyShare分享到: | |
| |
05-30
2009
