制作根文件系统:一站式配置脚本
本文承接自用VSCode + QEMU跑起来能够可视化Debug的NOVA文件系统,在上篇文章中我们使用CentOS8自带的initramfs来作为qemu的initramfs,这样实在不方便:不可定制化,启动时间太长等,在这篇文章中博主将介绍利用busybox制作initramfs的方法,并会提供一套全自动化构建rootfs脚本,不多BB,直接起飞。如果不想看步骤,直接看第二节:一站式配置脚本即可。
参考资料:
- https://emreboy.wordpress.com/2012/12/20/building-a-root-file-system-using-busybox/
- https://zhuanlan.zhihu.com/p/399857241
1. 利用BusyBox构建根目录文件系统
1.1 BusyBox安装与编译
- 下载BusyBox源码
在Github上有BusyBox的镜像源码,直接克隆即可:git clone https://github.com/mirror/busybox.git
- 配置BusyBox
接下来,勾选Build static binary(回车或者Y都可以勾选)。注意: 这个选项在Setting大目录下cd busybox make menuconfig
勾选完成后,方向键右→退出,并且选择保存
- 编译BusyBox
接下来的工作就简单啦,直接:make && make install
这里可能会提示-lxx找不到的问题,例如,博主就被提示了-lm
找不到,也就是libmath
(Stackoverflow 上搜一搜就知道了),数学库找不到,经过查询,这个库包含在glibc中,离谱了,OS不可能没有这个库吧。那经过查阅资料呢,发现这个问题一般来说是没有静态链接库导致的,(当然,也有另外的方法可以制作根文件系统,利用lld
命令查看busybox所需的所有动态链接库,并且把动态链接库都复制到根目录文件系统中就好了,这个留作未来介绍吧)。
如果运气好,这些静态链接库能通过包管理器找到(yum、apt等),但如果运气不好,就像CentOS8一样,就倒霉了。解决方法博主在解决在CentOS 8编译glibc-static中已经介绍了,按照这个思路就可以下载各种各样的包。
1.2 制作文件系统
在当前目录下会多出一个_install
文件夹,这个便是我们用作我们的根文件系统,我们将他复制到与busybox相同的目录下,方便管理:
[deadpool@localhost busybox]$ ls _install
bin linuxrc sbin usr
[deadpool@localhost busybox]$ cp _install ../initramfs -r && cd ../initramfs
- 添加必要文件夹
我们还需要运行必备的:proc
、sys
、dev
文件夹,另外,我们还要建立etc
文件夹,里面需要存放init
脚本:mkdir -p proc sys dev etc mkdir -p etc/init.d
- 添加开机启动脚本
# 1. 创建rcS touch etc/init.d/rcS # 2. 写入以下内容 echo """ #!bin/sh mount -t proc none /proc mount -t sysfs none /sys /sbin/mdev -s # 扫描并填充/dev文件夹 """ > etc/init.d/rcS # 3. 修改rcS为可执行文件 chmod +x etc/init.d/rcS
- 打包为initramfs
find . -print0 | cpio --null -ov --format=newc > ../initramfs.cpio
最终目录结构如下:
[deadpool@localhost rootfs]$ ls
busybox initramfs initramfs.cpio
其中,initramfs.cpio
即可作为QEMU系统-initrd
的参数
2. 一站式配置脚本
主要通过脚本消除make menuconfig
的交互,直接将Linux的config脚本复制到busybox的scripts下,这里博主已经为大家做好了,就在这个仓库中。一站式配置脚本就是将1中的步骤整合起来,形成一个单独的脚本。如下:
#!/usr/bin/bash
# 编译busybox
git clone https://github.com/Deadpoolmine/auto-make-rootfs.git
cd auto-make-rootfs
make defconfig
./scripts/config -e STATIC
make -j$(nproc)
make install
# 制作根文件系统
cp _install ../initramfs -r
cd ../initramfs
mkdir -p proc sys dev etc
mkdir -p etc/init.d
touch etc/init.d/rcS
echo """
#!bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s # 扫描并填充/dev文件夹
""" > etc/init.d/rcS
chmod +x etc/init.d/rcS
# 打包
find . -print0 | cpio --null -ov --format=newc > ../initramfs.cpio
# 查看
cd .. && ls