Zynq-7000 系列基于 NAND Flash 的 Linux 系统网络在线更新 BOOT.BIN 教程(Petalinux 2017.4)
在嵌入式开发中,经常需要对设备的固件进行升级。对于使用 NAND Flash 并运行 Linux(UBIFS 文件系统)的 Zynq-7000 系统,如果每次更新
BOOT.BIN 都要通过 JTAG 烧写或者拆卸芯片,效率会非常低。
本文将介绍如何利用 Zynq PS 端的网络接口,在 Linux 系统运行状态下,远程将新的 BOOT.BIN 写入 NAND Flash 的启动分区。
一、 基本原理与注意事项
- BOOT.BIN 的存储位置:
在 Zynq NAND Flash 启动模式下,BootROM 只能识别未格式化的原始 MTD 分区(Raw MTD Partition)。因此,虽然你的 Linux 根文件系统使用的是 UBIFS,但BOOT.BIN必须直接烧写在 MTD 的起始分区(通常是/dev/mtd0),而不是放在 UBIFS 文件系统中。 - NAND Flash 的特殊性:
NAND Flash 存在坏块管理和 OOB(Out of Band)区。因此,不能使用普通的dd命令直接写入,必须使用专门的 MTD 工具(如flash_erase和nandwrite),它们能够自动处理坏块。

二、 准备工作(Petalinux 配置)
为了实现网络传输和 NAND 写入,Linux 系统中需要具备以下工具:
- 网络传输服务:SSH/SCP(推荐,默认集成且安全)或 TFTP。
- MTD 分区操作工具:
mtd-utils(包含flash_erase、nandwrite等)。
1. 配置 Rootfs 启用 mtd-utils
在 Petalinux 工程根目录下,运行配置命令:
petalinux-config -c rootfs
在弹出的菜单中,使能以下工具:
- 进入
Filesystem Packages->base->mtd-utils,勾选mtd-utils。 - 确保
mtd-utils-flash-erase和mtd-utils-nandwrite被选中(通常勾选mtd-utils后会自动选中相关子项)。
2. 确认网络服务
Petalinux 默认集成了 dropbear(一个轻量级的 SSH 服务器,支持 SCP)。
- 可以在
Filesystem Packages->console/network->dropbear中确认其是否处于使能状态。
3. 编译并烧录
配置完成后,重新编译并生成新的系统镜像:
petalinux-build
将更新后的系统部署到板子上,确保系统能够正常启动并联网。
三、 具体操作步骤
第一步:确认 NAND Flash 分区信息
连接到 Zynq 板子的串口或通过 SSH 登录,输入以下命令查看 MTD 分区表:
cat /proc/mtd
输出信息大致如下:
dev: size erasesize name
mtd0: 00800000 00020000 "boot"
mtd1: 00800000 00020000 "bootenv"
mtd2: 02000000 00020000 "kernel"
mtd3: 1d000000 00020000 "rootfs"
- 解释:在这个例子中,
mtd0分区名为"boot",大小为 8MB,这就是用来存放BOOT.BIN的分区。请根据你实际的设备树(Device Tree)分区命名来确认对应的mtdX编号。
第二步:将新的 BOOT.BIN 通过网络传输到板子
你可以选择 SCP 或 TFTP 方式将 PC 上的 BOOT.BIN 传输到 Zynq 板子的 /tmp 目录(/tmp 是内存文件系统,读写速度快且不占用 Flash 寿命)。
方法 A:使用 SCP(推荐)
在 Windows PC 上可以使用 WinSCP、MobaXterm 等可视化工具,或者直接在主机命令行执行:
scp BOOT.BIN root@<板子IP地址>:/tmp/
(注意:Petalinux 默认的用户名为 root,密码通常在第一次启动时会要求设置,或者默认为空/root)
方法 B:使用 TFTP
如果在 PC 上搭建了 TFTP 服务器(如 tftpd64),可以在 Zynq 板子上执行:
cd /tmp
tftp -g -r BOOT.BIN <PC的IP地址>
第三步:在 Linux 中擦除并烧写 NAND Partition
请注意:以下操作涉及底层 Flash 写入,请确保写入的分区对应无误,且中途不要断电。
1. 擦除原有的 Boot 分区
在写入新数据之前,必须先擦除 MTD 分区(NAND Flash 的物理特性决定了只能将 1 写为 0,写数据前必须擦除为全 1)。
使用 flash_erase 命令:
flash_erase /dev/mtd0 0 0
- 参数解释:
/dev/mtd0是目标分区,第一个0表示从偏移量 0 开始,第二个0表示擦除整个分区。
2. 将 BOOT.BIN 写入分区
使用 nandwrite 命令将临时目录中的 BOOT.BIN 写入 mtd0:
nandwrite -p /dev/mtd0 /tmp/BOOT.BIN
- 参数解释:
-p(or--pad):表示如果文件大小未对齐到 NAND 的页大小,则自动填充(Padding),这是 NAND 烧写常用的参数。
如果终端显示类似如下信息,说明写入完成:
Writing data to block 0 at offset 0x0
Writing data to block 1 at offset 0x20000
...
第四步:重启验证
确认无报错后,可以安全重启板子以验证新的 BOOT.BIN 是否生效:
reboot
四、 常见问题与注意事项(FAQ)
-
为什么不用
dd命令?
dd命令是直接进行按字节复制,它既不关心 NAND Flash 的坏块(Bad Blocks),也不会妥善处理 OOB 数据。如果写入区域刚好有坏块,使用dd可能会导致系统无法启动。而nandwrite会跳过坏块并进行标记。 -
如果更新失败导致无法开机怎么办?
网络更新如果因为断电或分区写错导致损坏,BootROM 将无法引导。此时需要通过底线手段恢复:使用 JTAG(如 Vivado/SDK 的 Program Flash 工具)重新烧写基础的BOOT.BIN。 -
BOOT.BIN 文件大小超出了分区限制?
如果新的BOOT.BIN大小超过了mtd0的分区大小(例如分区只有 8MB,而文件有 9MB),nandwrite会报错提示空间不足。遇到这种情况需要修改设备树(dts)中的分区定义,重新规划 Flash 空间。
&spm=1001.2101.3001.5002&articleId=162718898&d=1&t=3&u=dc4218d6b7614552a933f68dd3544ab2)
347

被折叠的 条评论
为什么被折叠?



