首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
Hi3559AV100 eMMC烧录与ext4根文件系统制作实践指南
📅 2026/10/6 12:45:21
✍️ 爱科研究院
👁 阅读 3,247
1. 先把启动链路和 eMMC 分区规划搞清楚再谈烧录1.1 Hi3559AV100 的启动顺序决定了烧录动作的先后接触过海思平台的工程师应该都有体会烧录这件事本身不难难的是你手上的板子为什么烧完之后起不来。Hi3559AV100 这颗芯片在安防摄像头、AI Box、边缘计算盒子里非常常见Cortex-A73 加 A53 的大小核架构跑 Linux 的时候性能很充裕但它的启动链路有一个非常固定的顺序所有烧录动作都必须顺着这个顺序来。Hi3559AV100 上电之后先执行芯片内部的 BootROM 代码BootROM 会根据 boot 引脚的上下拉电平选择启动介质然后在介质上的固定偏移位置寻找 u-boot把 u-boot 加载到 DDR 里执行。u-boot 起来之后再从存储介质上读内核、读设备树、挂载根文件系统。整个过程是串行的前一级校验失败后面全部停摆。串口上如果只打印 ROM 相关的字符而没有 u-boot 的 Logo十有八九是 u-boot 写入的位置不对或者 BootROM 根本没有在那块介质上找到可用的镜像。所以要烧录之前第一件事不是在 PC 上敲命令而是确认你的板子当前是从哪个介质启动的。Hi3559AV100 的 eMMC 方案一般是用 eMMC 作为主存储但烧录阶段通常先让板子从 SD 卡启动 u-boot再用这个 u-boot 去烧写 eMMC。这种SD 卡中转的模式比直接吹焊 eMMC 或者用烧录器方便得多也安全得多——万一 eMMC 里的 u-boot 写坏了SD 卡还能救回来。1.2 一张表理清 eMMC 的用户分区布局官方 SDK 里给了一套默认的分区表但我建议你自己先画一张表再动手尤其是要确认每个分区在 eMMC 里的起始位置。以我手上的板子为例整颗 eMMC 的用户数据区被规划成这样分区起始偏移大小内容fastboot0块01MBu-boot.binkernel1MB块20488MBuImage / dtb 组合rootfs9MB 左右块18432剩余空间或指定大小rootfs.ext4实际的偏移数值以你 SDK 里的 parameter 文件或环境变量为准不同版本会有差别。但有一点是共通的eMMC 的块设备是线性寻址的u-boot 通常必须放在用户数据区的第 0 块或者非常靠前的位置因为 BootROM 找到 eMMC 后会在固定偏移去读。这里不要自作聪明地给 u-boot 前面腾出一段空白除非你确认 BootROM 支持跳过偏移。分区规划这件事还有一个容易忽略的点eMMC 内部除了用户数据区之外还有 boot1、boot2 硬件分区和 RPMB 分区。普通 Linux 下看到的 mmcblk0 是整个用户数据区boot 硬件分区是 mmcblk0boot0、mmcblk0boot1。fireware 级别的东西才需要用到硬件分区像我们只是烧 u-boot、内核和根文件系统全部写在用户数据区就行不需要去动硬件分区。动硬件分区之前必须确认 eMMC 的 EXT_CSD 寄存器配置否则很容易把一颗好端端的片子搞到不可用后面我会单独说这个坑。2. 用 busybox 和 mke2fs 手工制作 ext4 根文件系统镜像2.1 为什么要自己做而不是直接拿 SDK 的现成 rootfs海思 SDK 里确实有编译 rootfs 的整套脚本一键生成就能用。但你真拿到手会发现两个痛点第一体积很大一堆你用不到的模块和服务全在里面对 eMMC 容量小的板子很不友好第二不好定制想加自己的应用程序、改权限、换 glibc 版本都得在别人的目录结构里折腾拆东墙补西墙。自己做镜像的本质很简单先搭一个完整的根文件系统目录然后用 mke2fs 这个工具把这个目录打包成一个 ext4 格式的镜像文件。整个过程完全可控之后往 eMMC 里一写就是一套完整的 Linux 用户态环境。对 Hi3559AV100 这种跑摄像头应用的板子来说busybox 加必要的动态库和几个应用就完全够用精简下来的 rootfs 可能也就几十兆烧录和启动都快很多。2.2 搭建 rootfs 目录骨架一份可以反复使用的清单我先列出根文件系统目录里必须具备的内容这是之后一切应用的基础mkdir -p rootfs/{bin,sbin,etc,proc,sys,dev,lib,usr,var,tmp,mnt,opt} chmod 755 rootfs目录建好之后要往里面放东西第一步是 busybox。你可以从 busybox 官网下载源码交叉编译make menuconfig 里选静态编译然后 make 和 make install 把结果安装到 rootfs 目录下。静态编译的好处是不依赖动态库一个 busybox 文件就能提供 shell 和大部分常用命令。第二步是库文件。如果你的应用是动态编译的需要从工具链的 sysroot 目录拷贝必要的 .so 文件到 rootfs/lib 和 rootfs/usr/lib。这里有一个我犯过的错误只拷贝了应用依赖的库结果启动到一半发现缺 libm.so.6 或者 ld-linux-aarch64.so.1initramfs 阶段就崩了。稳妥的做法是你把用到的几个库全拷上去然后在目标板上用 ldd 检查一遍缺哪个补哪个。第三步是设备节点和关键配置文件cd rootfs/dev sudo mknod -m 666 console c 5 1 sudo mknod -m 666 null c 1 3/etc/inittab、/etc/fstab、/etc/passwd 这些基础文件也要准备好。fstab 里至少要有 proc 和 sysfs 的挂载项不然很多工具的执行会报错。其实这里可以偷个懒如果 SDK 有现成的 rootfs你完全可以照着它的 /etc 目录结构来整理自己的版本比自己从零写要快得多。2.3 mke2fs 制作镜像参数逐个拆开讲目录准备好之后下一步是生成 ext4 镜像文件。标准做法是先创建一个指定大小的空文件再在上面格式化dd if/dev/zero ofrootfs.ext4 bs1M count512 mke2fs -t ext4 -b 4096 -L rootfs -d rootfs rootfs.ext4第一行命令生成 512MB 的稀疏空文件第二行把之前搭建的 rootfs 目录直接填充进去。这里把每个参数都解释清楚方便你自己调整-t ext4指定文件系统类型为 ext4。-b 4096块大小设为 4KB。这个值不是随意选的eMMC 内部的最小擦除块通常也是 4KB 的倍数块大小对齐可以减少写入放大对性能和寿命都有好处。-L rootfs给文件系统设置卷标。虽然 Linux 挂载时不一定用卷标但有个标识在排查时会方便很多。-d rootfs把 rootfs 这个目录的内容当作文件系统的根目录原样写入镜像。还有一个需要你自己权衡的选项是否创建 journal。mke2fs 默认会创建 ext4 日志好处是意外断电后文件系统更不容易损坏坏处是每次写入都会有额外的日志写放大。对 eMMC 这种有擦写寿命限制的存储介质很多做产品的人会倾向于去掉 journalmke2fs -t ext4 -O ^has_journal -L rootfs -d rootfs rootfs.ext4如果你打算做成只读挂载或者频繁掉电的应用关掉 journal 是合理的。但如果 rootfs 上会有大量运行时写入比如日志文件、临时文件我还是建议保留 journal毕竟 eMMC 掉电损坏一个关键配置文件要比多写几行日志严重得多。2.4 制作完成后一定要做的两步检查镜像做好之后不要急着烧录先在本机验证一下这一步能省掉目标板上的大量调试时间e2fsck -f rootfs.ext4 dumpe2fs -h rootfs.ext4 | grep -E Filesystem state|Block counte2fsck 检查文件系统完整性dumpe2fs 查看文件系统状态和块数量。如果 e2fsck 报错说明 mke2fs 生成的镜像有问题这时候烧进 eMMC 大概率也是起不来的。另外一个非常实用的验证方式是把镜像挂载到本机回环设备上直接看内容sudo mount -o loop rootfs.ext4 /mnt/rootfs_check ls -la /mnt/rootfs_check sudo umount /mnt/rootfs_check这样能看到最终烧录后根目录的真实结构确认 busybox、配置文件、设备节点都齐全。我在实际做的时候有一次漏掉了 /dev/console 这个节点镜像检查时没发现结果目标板内核启动后 console 设备找不到init 进程直接卡死。这种低级错误在 PC 上检查很容易就能避免。3. 烧录 eMMCSD 卡启动 u-boot再用 fastboot 写镜像3.1 制作一键可用的 SD 启动卡烧录 eMMC 之前必须先让板子从一个已知良好的环境启动我习惯用 SD 卡做这个跳板。Hi3559AV100 的 SDK 里一般会提供 make_sd_boot 之类的工具脚本它会自动把 u-boot 写到 SD 卡的特定偏移位置。如果没有现成工具也可以手动操作sudo dd ifu-boot.bin of/dev/sdb bs1K seek1 convfsync这里的 seek1 表示跳过 SD 卡的前 1KB 写入 u-boot因为 SD 卡的 MBR 区域要保留。不同平台的偏移可能不同务必确认你的 u-boot 期望在哪个位置被 BootROM 加载。SD 卡写完 u-boot 之后建议再分一个 FAT 分区出来把 uImage、dtb 文件、rootfs.ext4 镜像都放进去。这样在 u-boot 里可以直接用 fatload 命令把镜像加载到内存方便后续烧写。我在实际操作中会先在 SD 卡上验证这一套 u-boot 能正常启动到内核毕竟 SD 卡上的读写比 eMMC 烧录环境容易调试。不过要注意SD 卡上的 u-boot 和最终要烧进 eMMC 的 u-boot 最好保持一致避免两套环境变量和驱动配置互相干扰。3.2 fastboot 烧录最推荐的方式板子从 SD 卡进入 u-boot 之后最简单可靠的烧录方式是开启 fastboot 协议。Hi3559AV100 的 u-boot 里支持 fastboot USB 模式步骤如下。先设置必要环境变量并让 u-boot 进入 fastboot 状态setenv bootargs mem1024M consolettyAMA0,115200 root/dev/mmcblk0p3 rootfstypeext4 rw rootwait saveenv fastboot usb 0然后主机端用 fastboot 工具逐个分区烧写fastboot flash fastboot u-boot.bin fastboot flash kernel uImage fastboot flash rootfs rootfs.ext4fastboot flash 的逻辑非常直接把本地文件写入目标设备的指定分区分区的偏移由 u-boot 里的 fastboot 配置决定。我在用这种方式烧 Hi3559AV100 的时候速率能达到几十 MB/s比通过 SD 卡中转读数据再写 eMMC 要快得多。而且 fastboot 时会先对镜像做校验比直接 dd 可靠很多。需要注意的一个细节是fastboot 模式下的 USB 连接线。有些数据线只支持充电不支持数据传输会导致 fastboot 设备在主机上反复枚举失败。建议先确认主机端lsusb能看到海思的 USB 设备再执行 flash 命令。3.3 老派的 mmc write 方式当 fastboot 不可用时有时候 u-boot 里的 fastboot 驱动没配置好或者 USB 通路出问题就得用 u-boot 原生的 mmc write 命令来烧录。流程是先通过网络把镜像下载到内存再从内存写入 eMMC整个过程在 u-boot 命令行手工执行。setenv ipaddr 192.168.1.10 setenv serverip 192.168.1.1 mw.b 0x82000000 0xff 0x1000000 tftp 0x82000000 uImage mmc write 0x82000000 0x800 0x4000这里有几个关键点要理解。mw.b 命令先把内存区域清零0xff确保下载失败时不会把残留数据误写入 eMMC这是一个容易被忽略的保护性操作。mmc write 的三个参数分别是内存地址、eMMC 起始块号、要写的块数每块固定是 512 字节。比如上面例子中 0x800 就是 2048 块起始位置是 2048 乘以 512 等于 1MB也就是内核分区的起始偏移0x4000 是 16384 块相当于 8MB正好是内核分区的大小。每次算偏移都要心里过一遍这个换算关系这是手工烧录最容易出错的地方。rootfs 因为是 ext4 镜像可以直接整体写入tftp 0x82000000 rootfs.ext4 mmc write 0x82000000 0x9000 0x400000x9000 起始块对应 9MB 偏移0x40000 块对应 128MB 空间这里要确保 rootfs.ext4 的实际大小不超过预留空间。如果镜像超过预留分区要么扩大分区规划要么缩小 rootfs.ext4 的文件系统大小任何超出都会覆盖后面的数据导致灾难性后果。4. 烧录过程中我真实踩过的几个坑4.1 rootfs 写入 eMMC 后内核报 VFS 错误的完整排查链路我第一次给 Hi3559AV100 的 eMMC 烧完 rootfs 后上电启动内核走到一半直接崩溃串口打印VFS: Cannot open root device mmcblk0p3 or unknown-block(179,3): error -2 Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,3)这个报错看起来像是内核找不到根设备。我的第一反应是检查 bootargs 里的 root 参数是不是写错了分区号。仔细检查了一遍root/dev/mmcblk0p3 没错分区号也对得上。然后检查内核配置里有没有编进 ext4 驱动make menuconfig 确认 CONFIG_EXT4_FSy 没问题。再到设备树里查 mmc1 节点的 status 是不是 okay也没发现异样。排到最后才发现问题出在一个看似不相干的地方内核虽然能看到 mmcblk0 这个设备但 mmcblk0p3 这个分区节点根本不存在。因为我在 eMMC 里烧的 u-boot、内核、rootfs 是三个独立的镜像而不是一个完整的带分区表的磁盘镜像Linux 内核并没有从 eMMC 上识别出任何分区表mmcblk0p3 自然就不存在。解决思路有两种。一种是保持独立镜像但 bootargs 里用 root/dev/mmcblk0 配合 rootfstypeext4 直接挂载整个 eMMC 设备为根文件系统因为 rootfs 镜像本来就是一个完整的文件系统。另一种是在 eMMC 里写一个分区表通常用 parameter 文件描述分区再用固定偏移去对应。海思的典型做法是前者因为 SOC 的 BootROM 只认固定偏移没必要依赖分区表。我最后把 bootargs 改成 root/dev/mmcblk0 rw rootwait 就正常启动了。这个排查过程让我深刻理解了嵌入式设备里 mmcblk0p3 的分区号必须由环境里的分区表支撑否则就是空中楼阁。4.2 烧录后 u-boot 偶尔起不来eMMC 的 boot 硬件分区和 RST_n 使能位有块板子在烧录完 eMMC 之后出现了一个很诡异的现象断电再上电一半概率能进 u-boot一半概率卡死在 BootROM完全随机。第一次遇到这种情况时我怀疑是 u-boot 镜像没写稳重新烧了一遍情况依旧。后来用 eMMC 的协议分析工具配合官方资料梳理才找到原因。Hi3559AV100 上用的 eMMC 芯片有一个 RST_n 功能的配置位这个位决定 RST_n 引脚是作为复位功能使用还是作为普通 GPIO 使用。如果 eMMC 的 EXT_CSD 里 RST_n function 被配置成了 disabled那么某些时序下 BootROM 对 eMMC 发起的启动序列会受影响导致偶发启动失败。解决方法是进入 u-boot 后执行mmc rst-function 0这条命令把 RST_n 功能重新配置为 normal让 eMMC 处于最通用的工作模式。执行完之后 saveenv再反复断电上电验证了几十次问题不再复现。这里有两点经验一是拿到新板子先做一轮完整的掉电启动压力测试别在功能正常后就跳过这一步二是遇到偶发性启动失败优先怀疑 eMMC 的扩展配置位而不是反复重烧 u-boot。4.3 烧完 rootfs 之后不建议立刻执行 fstrim刚烧完系统进入 Linux 后很多人会习惯性地执行 fstrim 或者用 mount 的 discard 选项来优化 eMMC理由是 trim 可以延长存储寿命。这个思路在 PC 的 SSD 上是对的但在刚烧录完的 eMMC 上有隐患。ext4 文件系统在初始化时mkfs 阶段会建立块位图标记哪些块是空闲的。如果整个 rootfs 镜像里大部分块都被数据填满剩余的空闲块本来就很少。fstrim 的语义是这些块已经空闲可以擦除文件系统层认为安全的空闲块和 eMMC 实际的物理映射之间隔着 FTL你无法控制 FTL 在 trim 之后做什么。尤其是在刚烧录、还没有建立完整稳定运行日志的情况下某些 eMMC 控制器对 trim 命令的处理可能跟你预期不符极端情况下会影响文件系统的一致性。我的建议是eMMC 方案里 ext4 根文件系统不要默认开 discard 挂载选项。eMMC 本身有后台垃圾回收机制正常运行中产生的碎片它会自己整理。如果确实要 trim先在测试板上充分跑一段时间验证稳定性确认不丢数据之后再推广到生产环境。我在实际产品中从来没有在 rootfs 上启用过 discard跑了半年多也没见写性能有明显劣化。5. 烧录完成后的验证与运行状态确认5.1 从串口日志判断启动链路是否健康烧录完成后第一次上电串口日志是判断系统是否正常的第一手依据。Hi3559AV100 的 u-boot 启动早期会打印 BootROM 相关的提示以及 DRAM 初始化信息。接着出现 u-boot 版本号和编译时间说明 BootROM 已经成功从 eMMC 里加载了 u-boot。再往后是内核解压、设备树校验、驱动初始化最后到 init 进程执行。一个容易忽略的检查点是u-boot 到底是从哪个介质启动的。在 u-boot 命令行输入mmc list和mmc dev确认当前选中的设备是 eMMC 而不是还在用 SD 卡。有时候 SDK 的环境变量里 bootcmd 还指向 SD 卡你以为在测 eMMC实际跑的还是 SD 卡上的老系统这样测出来的结果全部没有意义。另外u-boot 会打印类似MMC: mmc...的初始化日志能看到 eMMC 的型号、容量、时序模式。如果这里出现 HS400 或者 HS200 的字样说明 eMMC 已经工作在高速模式这也是性能验证的一部分。5.2 进入系统后检查文件系统挂载状态启动到 Linux 后第一件事是执行mount和df -h确认根文件系统挂载情况mount | grep root df -h /如果 root 挂载的是 /dev/mmcblk0 且文件系统类型是 ext4基本说明整个烧录链路是通的。接着用dmesg | grep mmc看内核识别的 eMMC 设备信息确认容量、传输模式和是否存在 CRC 错误。如果 dmesg 里出现大量mmc0: Timeout waiting for hardware interrupt或mmc0: error -110之类的日志多半是 eMMC 时序不稳定需要检查硬件电路或者降级模式而不是软件的问题。针对 Hi3559AV100 的 eMMC 方案我还会做一个写测试确认 rootfs 所在的分区可写、写完之后能正常读回echo test /test_write_check.txt sync cat /test_write_check.txt rm /test_write_check.txt写测试通过之后再执行 reboot 验证完整重启流程。到这里一套制作 ext4 文件系统 烧录 eMMC的流程才算真正闭环。5.3 关于 HS400 模式和 eMMC 坏块处理的个人建议Hi3559AV100 支持 eMMC 5.1 规范理论上可以跑 HS400 模式。HS400 的读写性能确实漂亮顺序读能到 200MB/s 以上但它的时序裕量比 HS200 更紧张对 PCB 走线和 eMMC 芯片质量要求更高。量产阶段如果 HS400 出现偶发 CRC 错误可以直接在设备树里把 mmc 的 max-frequency 降下来或者让 eMMC 工作在 HS200 模式性能和可靠性折中一下比反复软件优化更管用。eMMC 的坏块处理是很多入门工程师没注意的问题。eMMC 芯片内部有坏块管理机制Flash Translation Layer 会帮你屏蔽坏块你不需要像管理裸 NAND 一样去建坏块表。但这不代表文件系统层面就完全不用管记得要监控 dmesg 里频繁出现的 block 错误日志如果某个区域反复报错用 dd 测试确认后就要考虑更换 eMMC 批次了。在 rootfs 上启用日志文件系统的意义在这里体现得最明显即使 eMMC 出现少量坏块ext4 的 journal 也能最大程度保证文件系统元数据的一致性不至于一次掉电或坏块就让整个系统变砖。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/6 12:45:21
C# UDP通信实战:从Socket到UdpClient,避开端口与丢包坑
2026/10/6 12:45:21
Git Notes实战指南:不改commit hash为提交历史添加元信息
2026/10/6 12:45:21
Visual C++远程监控源码编译与调参实战指南
2026/10/6 13:50:27
用caveman为Go项目生成类型安全的HTTP客户端
2026/10/6 13:50:27
OpenShell:Windows上的类Unix桌面适配层
2026/10/6 13:50:27
快充技术底层原理与四大核心模块解析
2026/10/6 13:50:27
从内容质量到AI辅助审校:打造impeccable写作标准与自动化工作流
2026/10/6 13:50:27
C/C++自增运算符辨析:++i与i++的语义、性能及工程实践
2026/10/6 13:45:27
Agent Skills 完全指南:从概念到开发实战
2026/10/6 1:04:29
搭建无线EEG采集前端:BW16+ESP32-CYD实时波形显示实战
2026/10/6 1:04:29
CH10D功放芯片DIY音箱实战:从选型到调试的完整指南
2026/10/6 1:04:29
视频序列目标跟踪实战:解决ID跳变与遮挡丢失
2026/10/5 4:43:56
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/6 4:47:52
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/6 13:15:25
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/5 20:28:25
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/5 20:28:23
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/5 20:28:21
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)