第4章:输出产物分析——output/images目录详解
Buildroot编译完成后,所有成果都集中在 output/images 目录下。我第一次看到这个目录时,说实话有点懵——一堆文件,后缀各异,到底哪个才是我们需要的?
今天我就带你逐个拆解。你想想看,嵌入式系统启动需要什么?无非是:内核、根文件系统、设备树。嗯,这三个东西,就是images目录的核心产出。
4.1 目录概览:一张图看懂
先给你一张结构图,把整体脉络理清楚:
4.2 zImage:内核的“可执行文件”
zImage 就是编译好的Linux内核。说白了,它跟你在PC上看到的 vmlinuz 是一个东西,只不过针对ARM架构做了压缩。
我个人习惯用 file 命令看一眼:
$ file output/images/zImage
zImage: Linux kernel ARM boot executable zImage (little-endian)
这里有个关键点:zImage 是自解压的。Bootloader把它加载到内存后,它会自己解压,然后跳转到入口地址。我在项目中遇到过一个问题——明明内核编译成功了,但板子就是起不来。后来发现是Bootloader加载地址不对,zImage自解压时把自己覆盖了。嗯,这种坑踩过一次就记住了。
bootz 命令直接启动zImage。如果内核太大,也可以用 uImage(在zImage前面加了个U-Boot头)。
4.3 rootfs.cpio:内存里的“临时家园”
rootfs.cpio 是一个打包的根文件系统。它用cpio格式(不是tar哦),专门给initramfs用的。
为什么需要它?因为内核启动时,磁盘驱动可能还没加载。这时候内核需要先挂载一个临时的根文件系统,加载必要的驱动,然后再切到真正的磁盘根文件系统。
我记得第一次调试时,发现系统启动到一半卡住了。检查日志才发现,initramfs里少了 dev 目录的设备节点。后来我在Buildroot配置里勾选了 BR2_ROOTFS_DEVICE_CREATION_STATIC,问题就解决了。
4.4 rootfs.ext4:磁盘上的“永久家园”
rootfs.ext4 是一个ext4格式的磁盘镜像。你可以直接把它烧写到SD卡、eMMC或NAND Flash上。
用 dd 命令就能烧写:
$ sudo dd if=output/images/rootfs.ext4 of=/dev/sdX bs=1M status=progress
这里有个细节:ext4镜像的大小是固定的。如果你在Buildroot里设置了 BR2_TARGET_ROOTFS_EXT2_SIZE,那么生成的镜像就是那个大小。我建议设成实际需要的1.5倍左右,留点余量。
| 文件系统类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| cpio | initramfs、内存启动 | 启动快、不占磁盘 | 占用内存、容量有限 |
| ext4 | 磁盘存储、产品量产 | 容量大、支持日志 | 需要磁盘驱动 |
| squashfs | 只读文件系统 | 压缩率高、防篡改 | 不能写 |
4.5 dtb文件:硬件的“身份证”
*.dtb 是设备树二进制文件。它告诉内核:你的板子上有哪些硬件、内存多大、外设接在哪个GPIO上。
设备树源文件是 .dts,编译后变成 .dtb。Buildroot会自动编译你指定的设备树文件。
我曾经犯过一个低级错误:给A板子编译了B板子的dtb。结果内核启动时,GPIO初始化全乱套了,屏幕不亮、网口不通。排查了半天才发现是dtb搞错了。所以我现在每次烧写前都会确认一下:
$ strings output/images/board.dtb | grep model
model = "My Custom Board v2.0";
嗯,确认model名字对得上,再烧写。
4.6 其他文件:别忽略它们
除了上面四个核心文件,images目录里还有一些“配角”:
- u-boot.bin:如果你选了U-Boot,这里就是Bootloader镜像
- sdcard.img:完整的SD卡镜像,包含分区表和所有文件
- rootfs.tar:根文件系统的tar包,方便手动解压到磁盘
- *.its:FIT image的配置文件,用于打包多个镜像
我个人习惯是:开发阶段用 zImage + dtb + rootfs.cpio 通过TFTP启动,调试方便。量产阶段用 sdcard.img 或 rootfs.ext4 烧写到板载存储。
rootfs.ext4 烧写到NAND Flash,结果启动失败。后来发现NAND需要UBIFS格式,ext4不支持。所以一定要根据你的存储介质选择合适的文件系统格式。
4.7 总结:一张表记住核心
| 文件 | 作用 | 启动阶段 | 我的建议 |
|---|---|---|---|
| zImage | Linux内核 | Bootloader之后 | 保持默认,除非需要调试 |
| rootfs.cpio | 临时根文件系统 | 内核启动初期 | 用于initramfs,别太大 |
| rootfs.ext4 | 永久根文件系统 | initramfs之后 | 产品量产首选 |
| *.dtb | 硬件描述 | 内核启动时 | 确认板子型号匹配 |
好了,output/images目录里的东西,你现在应该心里有数了。下次编译完Buildroot,打开这个目录,你就能一眼认出每个文件是干什么用的。这就是经验积累的过程——见得多了,自然就熟了。
公众号:蓝海资料掘金营,微信deep3321