Zynq 7000使用NAND Flash启动UBIFS文件系统全攻略(基于PetaLinux 2017.4)

Zynq 7000使用NAND Flash启动UBIFS文件系统全攻略(基于PetaLinux 2017.4)

前言

在Zynq 7000的嵌入式开发中,NAND Flash由于容量大、价格便宜,常被用作主要的存储介质。但NAND Flash存在坏块问题,如果直接使用传统的ext4或jffs2文件系统,容易导致数据损坏。UBIFS(Unsorted Block Image File System) 专为裸NAND设计,自带坏块管理和磨损均衡,是NAND Flash的最佳搭档。

本文将手把手教你,如何在 PetaLinux 2017.4 环境下,配置Zynq 7000从NAND Flash启动,并挂载UBIFS根文件系统。新手小白只要跟着步骤一步步复制粘贴,也能轻松搞定!


🛠️ 准备工作

  1. 硬件基础:带有NAND Flash的Zynq 7000开发板。
  2. Vivado工程 :已经在Zynq IP核中开启了SMC(NAND Flash控制器),并导出了硬件描述文件(.hdf)。
  3. 软件环境:Ubuntu虚拟机,已成功安装 PetaLinux 2017.4。

第一步:创建并初始化PetaLinux工程

首先,把Vivado导出的 xxx.hdf 文件拷贝到Ubuntu中。打开终端,依次执行以下命令:

bash 复制代码
# 1. 设置PetaLinux环境变量(根据你的实际安装路径修改)
source /opt/pkg/petalinux/2017.4/settings.sh

# 2. 创建PetaLinux工程(假设工程名为zynq_nand_ubifs)
petalinux-create --type project --template zynq --name zynq_nand_ubifs

# 3. 进入工程目录
cd zynq_nand_ubifs

# 4. 导入硬件描述文件(注意把/path/to/hdf替换为你hdf文件所在的目录)
petalinux-config --get-hw-description=/path/to/hdf

执行完最后一步后,会弹出一个蓝底灰字的配置菜单。


第二步:系统级配置(划分NAND分区)

在刚弹出的 petalinux-config 菜单中,我们需要配置Flash分区和根文件系统类型。

1. 配置Flash分区

按照以下路径进入:
Subsystem AUTO Hardware Settings -> Flash Settings

  • 确保当前的Flash选中的是你的NAND。
  • 重点来了!进入 Advanced Flash Auto Partitioning,我们需要给NAND划分分区。建议划分如下:
    • boot (存放BOOT.BIN):大小 0x00800000 (8MB)
    • bootenv (存放U-Boot环境变量):大小 0x00100000 (1MB)
    • kernel (存放image.ub):大小 0x00A00000 (10MB)
    • rootfs (存放UBIFS文件系统):剩下的所有空间(比如填 0x1F0E0000,根据你的NAND总大小计算)

💡 新手避坑指南 :请务必记住这里名为 rootfs 的分区名称,后面的配置要用到!

2. 设置根文件系统类型为UBIFS

退回主菜单,按照以下路径进入:
Image Packaging Configuration -> Root filesystem type

  • 将其修改为 other。因为没有UBIFS

接下来修改petalinuxbsp.conf文件

上图中的后两个是关于nand falsh的参数具体说明如下,其中-s项对于不支持子页的flash应填写与页大小相同的数值。

继续在 Image Packaging Configuration 菜单下找到:
Device node of SD device(或者Bootargs配置),我们需要修改内核启动参数(Bootargs)。

  • 取消勾选 generate boot args automatically
  • user set kernel bootargs 中输入以下内容(一字不差地复制):
text 复制代码
console=ttyPS0,115200 earlyprintk root=ubi0:rootfs ubi.mtd=rootfs rootfstype=ubifs rw rootwait

(解释:ubi.mtd=rootfs表示在名为rootfs的MTD分区寻找UBI;root=ubi0:rootfs表示挂载UBI里面的rootfs卷)

配置完成后,连续按 Exit 退出并保存(Save)。


第三步:内核配置(开启UBI和UBIFS支持)

终端输入以下命令打开内核配置:

bash 复制代码
petalinux-config -c kernel

在内核菜单中,按 / 键可以搜索,我们需要确保开启以下几项功能(输入 Y 选中,变成 [*]<*>):

1. 开启MTD的UBI支持:
Device Drivers --->
Memory Technology Device (MTD) support --->
Enable UBI - Unsorted block images ---> 选中(设为 *

2. 开启UBIFS文件系统支持:
File systems --->
Miscellaneous filesystems --->
UBIFS file system support ---> 选中(设为 *

保存并退出。


第四步:文件系统配置(添加测试工具)

终端输入:

bash 复制代码
petalinux-config -c rootfs

为了以后我们在板子上能手动操作NAND,我们需要把 mtd-utils 工具包编译进去。

路径:
Filesystem Packages --->
base --->
mtd-utils --->

进去后,把 mtd-utils 及其下的 mtd-utils-ubifs 都打上星号 [*]

保存并退出。

第五步:设备树配置(关联NAND硬件)

虽然在第二步划分了分区,但最保险的做法是在设备树中再硬性声明一次。

打开文件 project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi

将其修改为类似如下内容(根据你的NAND节点名称 smcc 调整):

dts 复制代码
/include/ "system-conf.dtsi"
/ {
};

&smcc {
    nand0: nand@0,0 {
        compatible = "arm,pl353-nand-r2p1";
        reg = <0 0 0x1000000>;
        #address-cells = <1>;
        #size-cells = <1>;

        partition@0 {
            label = "boot";
            reg = <0x00000000 0x00500000>;
        };
        partition@1 {
            label = "bootenv";
            reg = <0x00500000 0x00020000>;
        };
        partition@2 {
            label = "kernel";
            reg = <0x00520000 0x00A00000>;
        };
        partition@3 {
            label = "rootfs";
            reg = <0x00F20000 0x1F0E0000>; /* 根据你的实际剩余容量修改 */
        };
    };
};

保存退出。

如nand flash有时序要求,可按下图方式增加nand时序。


第六步:编译生成

激动人心的时刻到了,终端输入:

bash 复制代码
petalinux-build

(这个过程可能需要十几分钟到半小时,去喝杯咖啡吧~ ☕)

编译成功后,我们需要打包生成最终的 BOOT.BIN。终端输入:

bash 复制代码
petalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga images/linux/system.bit --u-boot --force

此时,在 images/linux/ 目录下,我们拥有了烧写所需的三剑客:

  • BOOT.BIN (引导程序)
  • image.ub (内核与设备树)
  • rootfs.ubifs (UBIFS根文件系统镜像)

第七步:U-Boot烧写与启动(关键!)

由于是新板子,NAND里是空的。通常我们需要通过TFTP服务器,在U-Boot命令行下把这三个文件烧写到NAND中。(前提:开发板用网线连上电脑,电脑开启TFTP服务并将上述三个文件放入TFTP目录)。

在开发板串口终端中,上电狂按回车进入 U-Boot命令行

1. 配置网络

bash 复制代码
setenv ipaddr 192.168.1.100   # 开发板IP
setenv serverip 192.168.1.10  # 电脑Ubuntu IP

2. 烧写 BOOT.BIN

bash 复制代码
tftp 0x100000 BOOT.BIN
nand erase 0x0 0x500000
nand write 0x100000 0x0 $filesize

3. 烧写 image.ub (Kernel)

bash 复制代码
tftp 0x100000 image.ub
nand erase 0x520000 0xA00000
nand write 0x100000 0x520000 $filesize

4. 烧写 rootfs.ubifs

这是最特殊的一步!UBIFS不能用普通的nand write,必须按UBI格式写入。

bash 复制代码
# 擦除rootfs所在分区 (对应分区起始地址 0xF20000)
nand erase 0xF20000 0x1F0E0000

# 格式化该MTD分区为UBI格式
ubi part rootfs

# 创建名为rootfs的UBI卷 (注意这里不要超出大小)
ubi create rootfs

# 将文件系统下载到内存
tftp 0x100000 rootfs.ubifs

# 将内存中的文件系统写入UBI卷
ubi write 0x100000 rootfs $filesize

5. 保存环境变量并重启

确保U-Boot的启动指令是正确的:

bash 复制代码
# 设置U-Boot去NAND的kernel分区读取内核
setenv bootcmd 'nand read 0x3000000 0x520000 0xA00000; bootm 0x3000000'
saveenv
boot

🎉 成功启动

如果你在串口打印信息中看到了类似下面的字眼:

text 复制代码
UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
...
Welcome to PetaLinux!
zynq_nand_ubifs login: 

恭喜你,大功告成! 你的Zynq 7000已经成功从NAND Flash启动了UBIFS系统,以后断电重启你的代码和文件都不会再丢失啦!


结语

配置NAND和UBIFS的过程中,最容易在分区大小计算U-Boot烧写命令上踩坑。新手一定要耐心对照设备树中的地址和U-Boot操作的地址,确保完全一致。

相关推荐
千歌叹尽执夏1 天前
Vek385评估板(一):EDF成功烧录启动及一些问题
petalinux·versal·vek385·edf·ufs烧录
Soari9 天前
Ziggo-CaaS-Switch软件配置: undefined reference to pthread_create
java·开发语言·fpga开发·tsn·zynq·交换机配置
s09071369 天前
ZYNQ 软硬件协同踩坑日记:PS写BRAM后,PL端连续4个地址读出相同数据的原因与解决办法
fpga开发·zynq·硬件设计
weixin_4509072812 天前
[ZYNQ Linux] 端侧AI模型部署(DPU)
zynq
s090713613 天前
ZYNQ7000 AXI DMA 接收中断(S2MM_introut)全解析:从硬件原理到Linux驱动开发
linux·驱动开发·dma·zynq
日拱一卒的小田20 天前
ZYNQ学习笔记1-裸机-PS端中断配置、IO配置及PS/PL AXI交互
io·zynq·中断
s090713624 天前
Zynq-7000 PetaLinux 千兆网卡 Link UP 但无法 Ping 通的终极排查与解决(以 KSZ9031 为例)
linux·skew·zynq·ksz9031·ping不通
weixin_4509072824 天前
[ZYNQ Linux] V4L2视频驱动
zynq
s09071361 个月前
【Zynq 进阶一】深度解析 PetaLinux 存储布局:NAND Flash 分区与 DDR 内存分配全攻略
linux·fpga开发·设备树·zynq·nand flash启动·flash分区