rk3399定制rootfs.img与update.img全流程解析 1. RK3399镜像定制基础概念RK3399作为一款高性能的处理器芯片在嵌入式设备和开发板中广泛应用。当我们拿到一块搭载RK3399的开发板时第一件事往往就是定制系统镜像。这里主要涉及两种关键镜像文件rootfs.img和update.img。rootfs.img是Linux系统的根文件系统镜像包含了操作系统运行所需的所有文件和目录结构。而update.img则是完整的固件包包含了引导加载程序、内核镜像和根文件系统等所有组件。在实际开发中我们经常需要修改rootfs.img比如添加自定义应用程序、修改系统配置然后重新打包成update.img进行烧录。我遇到过不少开发者第一次接触RK3399镜像定制时常常搞不清楚这两个镜像的关系。简单来说rootfs.img就像是你的电脑C盘里的Windows系统文件夹而update.img则相当于一个完整的系统安装U盘。修改rootfs.img后必须重新打包成update.img才能刷写到设备上生效。2. 准备工作与环境搭建2.1 获取必要的工具和文件在开始定制镜像前我们需要准备以下工具和文件AndroidTool.exe瑞芯微提供的官方烧录工具RK3399开发板配套的SDK或原始镜像包Linux环境推荐Ubuntu 18.04或以上版本基础工具链e2fsprogs包含resize2fs等工具我建议在Linux系统下进行镜像定制操作因为很多文件系统操作在Linux下更加直接和可靠。如果你只有Windows系统可以使用WSL2或者虚拟机来运行Linux环境。2.2 解压原始update.img首先我们需要从原始update.img中提取出rootfs.img。使用AndroidTool.exe的Advanced Function功能可以解包update.img。具体步骤是打开AndroidTool.exe点击Advanced Function选项卡选择Unpack功能载入update.img文件指定输出目录点击Run按钮开始解包解包完成后你会在输出目录中找到rootfs.img和其他组件文件。把这些文件备份到一个安全的位置因为后续所有操作都将基于这些原始文件。3. rootfs.img的定制与修改3.1 调整文件系统大小原始rootfs.img的大小通常是固定的但我们需要更多空间来添加自己的应用程序和文件。这时就需要使用resize2fs工具来扩展文件系统。首先检查并修复文件系统e2fsck -p -f rootfs.img然后调整大小这里扩展到2GBresize2fs rootfs.img 2G值得注意的是resize2fs只是调整了文件系统的逻辑大小并没有实际占用这么多物理空间。这也是为什么压缩后文件大小看起来没变化但实际上可用空间已经增加了。3.2 挂载和修改文件系统现在我们可以挂载rootfs.img进行修改了mkdir -p /mnt/rootfs mount -o loop rootfs.img /mnt/rootfs进入挂载点后你就可以像操作普通Linux系统一样进行各种修改cd /mnt/rootfs # 添加你的应用程序到/usr/local/bin # 修改/etc下的配置文件 # 安装额外的库文件到/lib或/usr/lib修改完成后记得卸载文件系统cd / umount /mnt/rootfs3.3 优化和压缩文件系统在修改完成后建议对文件系统进行优化和压缩e2fsck -p -f rootfs.img resize2fs -M rootfs.img这里有个常见误区很多人以为resize2fs -M会显著减小.img文件的大小但实际上它只是调整文件系统到最小所需大小而.img文件本身的大小可能变化不大。这是因为.img文件是稀疏文件实际占用的磁盘空间是根据实际内容计算的。4. 打包生成update.img4.1 准备打包所需的文件要生成update.img我们需要准备以下文件修改后的rootfs.img原始的或修改过的boot.imgMiniLoaderAll.binparameter.txttrust.imguboot.img这些文件需要放置在SDK的特定目录中通常是{sdk_dir}/tools/linux/Linux_Pack_Firmware/rockdev/Image/4.2 修改package-file配置package-file文件决定了哪些组件会被打包进update.img。典型的package-file内容如下# NAME Relative path # #HWDEF HWDEF package-file package-file bootloader Image/MiniLoaderAll.bin parameter Image/parameter.txt trust Image/trust.img uboot Image/uboot.img boot Image/boot.img rootfs:grow Image/rootfs.img backup RESERVED如果你打包的是Ubuntu系统而非Android可能需要调整这个文件的内容。特别是rootfs:grow这一行grow参数表示允许根文件系统在首次启动时扩展到整个存储设备。4.3 执行打包脚本一切准备就绪后就可以运行打包脚本了cd ${sdk_dir}/tools/linux/Linux_Pack_Firmware/rockdev/ ./mkupdate.sh打包过程会输出详细日志你应该能看到类似这样的信息start to make update.img... Android Firmware Package Tool v1.65 ------ PACKAGE ------ Add file: ./package-file Add file: ./Image/MiniLoaderAll.bin Add file: ./Image/parameter.txt Add file: ./Image/trust.img Add file: ./Image/uboot.img Add file: ./Image/boot.img Add file: ./Image/rootfs.img Add CRC... Make firmware OK! ------ OK ------最终生成的update.img会出现在Image目录下现在你就可以用AndroidTool.exe将它烧录到设备上了。5. 常见问题与解决方案5.1 文件系统挂载失败如果在挂载rootfs.img时遇到错误很可能是文件系统损坏。可以尝试e2fsck -y rootfs.img这个命令会尝试修复文件系统错误。如果问题依旧可能需要从原始update.img重新提取rootfs.img。5.2 打包后系统无法启动update.img打包成功但设备无法启动时建议按以下步骤排查检查boot.img是否与rootfs.img版本匹配确认parameter.txt中的分区设置正确验证rootfs.img是否完整且可挂载检查打包过程中是否有错误或警告信息5.3 自定义应用程序无法运行如果你在rootfs.img中添加了自己的应用程序但无法运行可能是以下原因缺少依赖库使用ldd命令检查依赖文件权限不正确确保可执行文件有x权限架构不匹配确认应用程序是为ARM64架构编译的6. 高级定制技巧6.1 自动化定制流程对于需要频繁修改和测试的场景可以编写脚本自动化整个过程。下面是一个简单的示例#!/bin/bash # 解压update.img unpack_update() { # 使用AndroidTool命令行工具解压 echo 解压update.img... } # 修改rootfs customize_rootfs() { echo 挂载rootfs.img... mkdir -p /mnt/rootfs mount -o loop rootfs.img /mnt/rootfs # 在这里添加你的定制命令 # 例如cp myapp /mnt/rootfs/usr/local/bin/ umount /mnt/rootfs } # 打包update.img pack_update() { echo 打包update.img... cd ${sdk_dir}/tools/linux/Linux_Pack_Firmware/rockdev/ ./mkupdate.sh } # 主流程 unpack_update customize_rootfs pack_update6.2 使用build.sh编译rootfs如果你有完整的SDK还可以使用build.sh脚本从头编译rootfs./build.sh rootfs这种方式适合需要深度定制的场景比如修改基础系统组件或内核模块。6.3 多系统支持RK3399支持多种操作系统包括Android、Ubuntu、Debian等。打包不同系统时主要区别在于boot.img的内容rootfs.img的文件系统结构package-file的配置例如打包Ubuntu系统时package-file中的rootfs行通常不需要:grow参数因为Ubuntu有自己的分区扩展机制。