4、根文件系统构建:BusyBox制作最小根文件系统、Yocto/Buildroot高级构建、文件系统优化与启动加速
根文件系统,说白了就是嵌入式Linux的「家」。
内核启动后,得有个地方放应用程序、库文件、配置文件、设备节点。这个「地方」就是根文件系统。我刚开始做医疗显微镜项目时,觉得随便搞个文件系统能跑就行。结果发现,启动慢、体积大、稳定性差,问题一堆。嗯,这章咱们就把根文件系统这件事彻底讲透。
4.1 BusyBox:最小根文件系统的基石
BusyBox是什么?它是个「瑞士军刀」。一个二进制文件,集成了两百多个Linux命令。ls、cp、mv、sh、init……全在里面。我习惯叫它「瘦身版Linux工具集」。
制作最小根文件系统,BusyBox是首选。为什么?因为它小。一个完整的BusyBox才几百KB,放在医疗显微镜这种资源受限的设备上,再合适不过了。
4.1.1 编译BusyBox
步骤其实不复杂。我带你走一遍:
# 下载源码
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xjf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
# 配置
make menuconfig
# 关键配置项
# Settings -> Build static binary (no shared libs) [建议不选,除非你静态编译]
# Settings -> Cross compiler prefix = arm-linux-gnueabihf-
# Settings -> Destination path for 'make install' = ../rootfs
# 编译并安装
make -j4
make install
这里有个坑。我曾经在配置时忘了指定交叉编译器前缀,结果编译出来的是x86版本,放到ARM板子上直接报「无法执行二进制文件」。你想想看,排查了半天才发现是架构不对,多耽误事。
4.1.2 构建最小根文件系统目录结构
BusyBox安装完成后,会在目标目录生成bin、sbin、usr等目录。但这还不够。我们需要手动创建一些关键目录和文件:
cd ../rootfs
mkdir -p dev etc lib proc sys tmp var mnt root
这些目录各有用途:
- dev:设备节点。没有它,你连串口都用不了。
- etc:配置文件。inittab、fstab、passwd都在这里。
- lib:动态库。如果BusyBox是动态编译的,这里必须有glibc或uClibc。
- proc、sys:虚拟文件系统挂载点。内核信息、硬件状态全靠它们。
我个人习惯,还会在root下放一个「first_run.sh」脚本,用于首次启动时的初始化工作。比如校准触摸屏、设置网络参数等。
4.1.3 配置init进程
根文件系统启动后,内核会执行第一个用户空间程序——init。BusyBox自带init,但需要配置文件:
# etc/inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
再创建rcS脚本:
# etc/init.d/rcS
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
mdev -s
echo "Welcome to Medical Microscope System"
记得给rcS加上执行权限:chmod +x etc/init.d/rcS。我曾经忘了这一步,启动后卡在「Kernel panic - not syncing: No init found」,排查了半小时才发现是脚本没权限。嗯,这种低级错误,犯过一次就记住了。
4.2 Yocto与Buildroot:高级构建工具
BusyBox适合快速原型。但如果你要构建一个完整的、可定制的、包含图形界面和医疗库的根文件系统,Yocto和Buildroot才是正解。
4.2.1 Buildroot:轻量级选择
Buildroot我用了很多年。它简单、直接、编译快。适合医疗显微镜这种中等复杂度的项目。
使用步骤:
# 下载
git clone https://git.buildroot.net/buildroot
cd buildroot
# 配置
make menuconfig
# 关键配置
# Target options -> Target Architecture = ARM (little endian)
# Toolchain -> Toolchain type = External toolchain
# System configuration -> Root filesystem overlay directory = ../my_overlay
# Filesystem images -> ext2/3/4, squashfs, tar
# 编译
make
Buildroot有个很贴心的功能:overlay目录。你可以把自定义的配置文件、脚本、应用程序放在my_overlay里,编译时会自动合并到根文件系统。我在项目中就用这个特性,把显微镜的校准参数和UI资源文件单独管理,方便版本迭代。
4.2.2 Yocto:企业级方案
Yocto比Buildroot复杂得多,但灵活性和可维护性也强得多。如果你要量产医疗显微镜,Yocto是更稳妥的选择。
Yocto的核心概念是「层」(Layer)。你可以把BSP层、应用层、GUI层分开管理。我参与的一个项目,BSP由硬件团队维护,应用层由软件团队维护,互不干扰。
一个典型的Yocto项目结构:
meta-microscope/ # 自定义层
├── conf/
│ └── layer.conf
├── recipes-core/
│ └── microscope-image/
│ ├── microscope-image.bb
│ └── files/
│ ├── inittab
│ └── rc.local
├── recipes-graphics/
│ └── qt5/
│ └── qt5-opengl_%.bbappend
└── recipes-bsp/
└── u-boot/
└── u-boot_%.bbappend
Yocto的编译时间确实长。第一次编译可能要几个小时。但好处是,一旦配置好,后续的增量编译很快。而且Yocto生成的根文件系统,所有依赖都自动解决,不会出现「缺库」这种烦心事。
4.3 文件系统优化与启动加速
医疗显微镜对启动时间有要求。病人等着做检查,你不能让设备启动两分钟吧?我见过一个项目,启动花了45秒,被客户直接退货。所以,优化启动速度是必修课。
4.3.1 文件系统体积优化
体积越小,加载越快。怎么瘦身?
- 删除不必要的命令:BusyBox配置时,只选需要的。比如医疗设备不需要ftp、telnet,去掉。
- 使用uClibc或musl:比glibc小得多。我测试过,musl编译的BusyBox体积减少40%。
- 剥离调试符号:
arm-linux-strip --strip-unneeded可以干掉二进制文件中的调试信息。 - 压缩文件系统:squashfs配合LZ4压缩,体积小且解压快。
4.3.2 启动流程优化
启动加速不只是压缩文件系统。整个启动链都要优化:
| 阶段 | 优化方法 | 效果 |
|---|---|---|
| Bootloader | 减少延时、去掉不必要的硬件初始化 | 节省1-2秒 |
| 内核 | 裁剪驱动、使用LZ4压缩内核 | 节省2-3秒 |
| 根文件系统 | 使用squashfs、并行初始化服务 | 节省3-5秒 |
| 应用程序 | 延迟加载、预链接 | 节省1-2秒 |
我个人最推荐的一个优化点是:并行启动服务。传统的init是串行执行rcS脚本,一个服务卡住,后面的全等。改用BusyBox的start-stop-daemon配合后台运行,可以大幅缩短启动时间。
4.3.3 使用initramfs加速
initramfs是把根文件系统打包进内核镜像。内核启动时直接解压到内存,省去了挂载存储设备的时间。
配置方法:
# 内核配置
General setup -> Initial RAM filesystem and RAM disk (initramfs/initrd) support
-> Initramfs source file(s) = ../rootfs.cpio.gz
initramfs的缺点是占用内存。如果你的设备内存只有64MB,可能不太合适。但医疗显微镜一般配256MB以上,用initramfs完全没问题。
4.4 实战:医疗显微镜根文件系统构建清单
好了,理论讲完了。我给你一个可以直接用的清单:
- 选择工具:快速原型用BusyBox,量产用Yocto或Buildroot。
- 配置内核:确保支持你选的文件系统格式(ext4、squashfs、overlayfs)。
- 构建根文件系统:包含必要的库、设备节点、配置文件。
- 优化体积:strip、压缩、去掉无用组件。
- 优化启动:并行初始化、initramfs、延迟加载。
- 测试验证:用QEMU模拟启动,确认无报错。再烧录到真机。
最后说一句。根文件系统不是「一次构建,终身使用」。随着功能迭代,文件系统也要持续优化。我每个季度都会重新审视一次根文件系统的配置,看看有没有可以精简的地方。毕竟,医疗设备对稳定性和启动速度的要求,永远没有上限。