ZYNQ防火墙开发2-FSBL u-boot kernel rootfs PetaLinux

EBAZ4205概述

​ 声明:初级学员对此课程不要有太多压力,虽然此课程基于真实且复杂的项目,但我们在真正开发产品中很多都可以基于已有的模块实现。并不是所有都需要自己开发。当然有些细节我们自己操作一遍也可以增加理解。

loading-ag-498

EBAZ4205转接板资源汇总 (黑色现款)

image-20240323150812473

zynq启动流程

​ xilinx zynq 7000系列的芯片中包括两个部分,PS和PL,也就是FPGA的逻辑编程的部分跟嵌入式ARM的部分,ARM部分是双核的A9处理器。关于FPGA的部分在这里就不说了。其实说的简单点,可以吧这个芯片看成一个带有FPGA外设的ARM处理器,下面详细分析一下启动流程。

​ ..xxxx.sdk\standalone_bsp_0\ps7_cortexa9_0\libsrc\standalone_v5_1\src\asm_vectors.S中的开头也就是0地址的地方有这样得一段代码:

1
2
3
4
5
6
7
8
9
10
.section .vectors
_vector_table:
B _boot
B Undefined
B SVCHandler
B PrefetchAbortHandler
B DataAbortHandler
NOP /* Placeholder for address exception vector*/
B IRQHandler
B FIQHandler

boot.S

1
2
3
4
_boot:

b _start /* jump to C startup code */
and r0, r0, r0 /* no op */

xil-crt0.S

1
2
3
4
_start:

/* Let her rip */
bl main

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main(void)
{
/*
* PCW initialization for MIO,PLL,CLK and DDR
*/
Status = ps7_init();
/*
* PCAP initialization
*/
Status = InitPcap();
/*
* Initialize the Watchdog Timer so that it is ready to use
*/
Status = InitWatchDog();
/*
* Read bootmode register
*/
BootModeRegister = Xil_In32(BOOT_MODE_REG);
BootModeRegister &= BOOT_MODES_MASK;

if (BootModeRegister == NAND_FLASH_MODE) {
}else
if (BootModeRegister == NOR_FLASH_MODE) {
}else
if (BootModeRegister == SD_MODE) {
}else
if (BootModeRegister == JTAG_MODE) {
}

/*
* Load boot image
*/
HandoffAddress = LoadBootImage();
}

image_mover.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
u32 PartitionMove(u32 ImageBaseAddress, PartHeader *Header)
{

/*
* 完成了PL的加载
* Load Bitstream partition in to fabric only
* if checksum and authentication bits are not set
*/
Status = PcapLoadPartition((u32*)SourceAddr,
(u32*)Header->LoadAddr,
Header->ImageWordLen,
Header->DataWordLen,
EncryptedPartitionFlag);
}

FSBL介绍

  1. FSBL的作用

​ FSBL是ZYNQ 7000启动过程中的第一阶段,其主要作用是初始化硬件资源、加载FPGA bit文件、配置DDR等。在FSBL执行完毕后,系统会进入第二阶段——uboot。

  1. FSBL的代码结构
  • fsbl.h:定义了FSBL的全局变量和函数原型。

  • fsbl_config.h:定义了FSBL的配置信息,如DDR的大小和地址、FPGA bit文件的地址等。

  • fsbl_hooks.c:定义了FSBL的钩子函数,如FSBL的初始化函数、DDR的初始化函数等。

  • fsbl_main.c:FSBL的主函数,包含了FSBL的启动过程。

  1. FSBL的启动过程

​ FSBL的启动过程主要包括以下几个步骤:

  • 初始化硬件资源:包括初始化PS和PL的时钟、GPIO、UART等。

  • 加载FPGA bit文件:从SD卡或QSPI Flash中读取FPGA bit文件,并将其加载到PL中。

  • 配置DDR:初始化DDR控制器,并配置DDR的大小和地址。

  • 初始化FSBL的全局变量:包括FSBL的启动模式、DDR的大小和地址、FPGA bit文件的地址等。

  • 执行FSBL的钩子函数:包括FSBL的初始化函数、DDR的初始化函数等。

  • 跳转到uboot:将控制权转交给uboot,进入第二阶段的启动过程。

  1. FSBL的钩子函数

​ FSBL的钩子函数包括:

  • FSBL的初始化函数:初始化FSBL的全局变量。
  • DDR的初始化函数:初始化DDR控制器,并配置DDR的大小和地址。
  • FSBL的打印函数:用于在启动过程中输出调试信息。
  1. FSBL的生成方式
  • vitis工具生成,New project选择Zynq FSBL模板生成fsbl.elf。
  • petalinux命令行生成。

BOOT.bin

BOOT.bin包含:

​ fsbl.elf文件

​ vivado生成的fpga的bit文件

​ app工程的elf文件(这里为led工程的elf)

linux BOOT.bin包含:

​ fsbl.elf文件

​ vivado生成的fpga的bit文件

​ u-boot.elf文件

​ system.dtb设备树文件

​ 注:SD模式 linux的内核镜像、文件系统在BOOT.bin之外。

在boot.bin中从地址0-0x8BF可以分成17个部分,每个部分都有一定的含义:

image-20240320162543032

对应的FSBL.h文件中的宏定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
/* Boot ROM Image defines */
#define IMAGE_WIDTH_CHECK_OFFSET (0x020) /**< 0xaa995566 Width Detection word */
#define IMAGE_IDENT_OFFSET (0x024) /**< 0x584C4E58 "XLNX" */
#define IMAGE_ENC_FLAG_OFFSET (0x028) /**< 0xA5C3C5A3 */
#define IMAGE_USR_DEF_OFFSET (0x02C) /**< undefined could be used as */
#define IMAGE_SOURCE_ADDR_OFFSET (0x030) /**< start address of image */
#define IMAGE_BYTE_LEN_OFFSET (0x034) /**< length of image> in bytes */
#define IMAGE_DEST_ADDR_OFFSET (0x038) /**< destination address in OCM */
#define IMAGE_EXECUTE_ADDR_OFFSET (0x03c) /**< address to start executing at */
#define IMAGE_TOT_BYTE_LEN_OFFSET (0x040) /**< total length of image in bytes */
#define IMAGE_QSPI_CFG_WORD_OFFSET (0x044) /**< QSPI configuration data */
#define IMAGE_CHECKSUM_OFFSET (0x048) /**< Header Checksum offset */
#define IMAGE_IDENT (0x584C4E58) /**< XLNX pattern */

准备开发环境

参考:

  1. ug1144-petalinux-tools-reference-guide.pdf

  2. [petalinux 2017.2安装指南]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ubuntu server缺少库,最好直接用ubuntu 16.04 desktop
#安装ssh和samba 方便操作
sudo apt-get install openssh-server
sudo service ssh start
sudo apt-get install u-boot-tools
sudo apt install samba
sudo smbpasswd -a username

#cat /etc/samba/smb.conf
[workspace]
comment = share folder
path = /home/dnsnat
valid users = dnsnat
force user = dnsnat
available = yes
browseable = yes
public = no
writable = yes
PetaLinux 2017.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#Firstly we need enable i386 architecture (if running Ubuntu x64):
sudo dpkg --add-architecture i386

#• PetaLinux Tools Installation Requirements is completed. Refer to the Installation Requirements section.
sudo apt-get install tofrodos iproute2 gawk
sudo apt-get install gcc git make
sudo apt-get install xvfb
sudo apt-get install net-tools libncurses5-dev tftpd
sudo apt-get install zlib1g-dev zlib1g-dev:i386 libssl-dev flex bison libselinux1
sudo apt-get install gnupg wget diffstat chrpath socat xterm
sudo apt-get install autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential libsdl1.2-dev libglib2.0-dev
sudo apt-get install screen pax gzip tar

#• PetaLinux release package is downloaded. You can download PetaLinux installer from PetaLinux Downloads.
#https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools.html
#Choose “PetaLinux 2017.2 Installer”. It is a single-file executable that is 7.54GB large

#直接在home目录下建
mkdir -p opt/pkg/petalinux1702
#千万不要使用root或者sudo
./petalinux-v2017.2-final-installer.run /home/dnsnat/opt/pkg/petalinux1702
1
2
3
4
5
6
7
#创建环境变量
#自己以普通用户模式下
vi ~/.bashrc
#在末尾添加:
source /home/dnsnat/opt/pkg/petalinux1702/settings.sh
#加载生效
source ~/.bashrc
1
2
3
4
5
6
mkdir EBAZ4205
#sync -azP system_wrapper.hdf 192.168.122.197:/home/dnsnat/EBAZ4205
cd EBAZ4205
petalinux-create -t project --template zynq -n project
cd project
petalinux-config --get-hw-description ../

配置参考正点原子文档

1
2
petalinux-config -c kernel
petalinux-config -c rootfs
1
2
petalinux-build
petalinux-package --boot --format BIN --fsbl ./images/linux/zynq_fsbl.elf --fpga system_wrapper.bit --u-boot --force

备份原始系统

1、链接调试串口,上电查看启动信息,记录分区情况

上电后,串口会打印启动信息,其中可以看到如下相关信息:

1
2
3
4
5
6
7
8
9
10
Creating 9 MTD partitions on "pl35x-nand":                                                                                    
0x000000000000-0x000000300000 : "nand-fsbl-uboot"
0x000000300000-0x000000800000 : "nand-linux"
0x000000800000-0x000000820000 : "nand-device-tree"
0x000000820000-0x000001220000 : "nand-rootfs"
0x000001220000-0x000002220000 : "nand-jffs2"
0x000002220000-0x000002a20000 : "nand-bitstream"
0x000002a20000-0x000006a20000 : "nand-allrootfs"
0x000006a20000-0x000007e00000 : "nand-release"
0x000007e00000-0x000008000000 : "nand-reserve"

这就是nand分区结构,下面就开始对这些分区进行备份,以防不时之需。

2、重新启动,按‘d’进入U-BOOT

1
2
Hit 'd' to stop autoboot(eric): 0  
zynq-uboot>

3、修改网络配置

1
2
setenv serverip 192.168.200.1
setenv ipaddr 192.168.200.99
1
sudo systemctl start tftpd.service

4、 备份分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
zynq-uboot> nand read 0x100000 0x000000 0x300000
zynq-uboot> tftpput 0x100000 0x300000 fsbl-uboot

zynq-uboot> nand read 0x100000 0x300000 0x500000
zynq-uboot> tftpput 0x100000 0x500000 linux

zynq-uboot> nand read 0x100000 0x800000 0x20000
zynq-uboot> tftpput 0x100000 0x20000 device-tree

zynq-uboot> nand read 0x100000 0x820000 0xA00000
zynq-uboot> tftpput 0x100000 0xA00000 rootfs

zynq-uboot> nand read 0x100000 0x2220000 0x800000
zynq-uboot> tftpput 0x100000 0x800000 bitstream

zynq-uboot> nand read 0x100000 0x2a20000 0x4000000
zynq-uboot> tftpput 0x100000 0x4000000 allrootfs

zynq-uboot> nand read 0x100000 0x6a20000 0x13e0000
zynq-uboot> tftpput 0x100000 0x13e0000 release

zynq-uboot> nand read 0x100000 0x7e00000 0x200000
zynq-uboot> tftpput 0x100000 0x200000 reserve

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ynq-uboot> nand read 0x100000 0x000000 0x300000

NAND read: device 0 offset 0x0, size 0x300000
3145728 bytes read: OK
zynq-uboot> md.b 100000 80
00100000: fe ff ff ea fe ff ff ea fe ff ff ea fe ff ff ea ................
00100010: fe ff ff ea fe ff ff ea fe ff ff ea fe ff ff ea ................
00100020: 66 55 99 aa 58 4e 4c 58 00 00 00 00 00 00 01 01 fU..XNLX........
00100030: 00 17 00 00 10 80 01 00 00 00 00 00 00 00 00 00 ................
00100040: 10 80 01 00 01 00 00 00 20 45 16 fc 00 00 00 00 ........ E......
00100050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00100060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00100070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
zynq-uboot> tftpput 0x100000 0x300000 fsbl-uboot
Gem.e000b000:0 is connected to Gem.e000b000. Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete..... done
Gem.e000b000----100----4047----
Using Gem.e000b000 device
TFTP to server 192.168.0.139; our IP address is 192.168.0.99
Filename 'fsbl-uboot'.
Save address: 0x100000
Save size: 0x300000
Saving: ################################################################
1.2 MiB/s
done
Bytes transferred = 3145728 (300000 hex)
zynq-uboot>

其中使用了u-boot的md命令查看了以下内存的内容,只显示了部分(0x80即128字节),再查看以下上传到服务其上的文件内容:

1
2
3
4
5
6
7
8
9
10
zhy@ubuntu:/var/tftpboot$ xxd -l 0x80 fsbl-uboot 
00000000: feff ffea feff ffea feff ffea feff ffea ................
00000010: feff ffea feff ffea feff ffea feff ffea ................
00000020: 6655 99aa 584e 4c58 0000 0000 0000 0101 fU..XNLX........
00000030: 0017 0000 1080 0100 0000 0000 0000 0000 ................
00000040: 1080 0100 0100 0000 2045 16fc 0000 0000 ........ E......
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
zhy@ubuntu:/var/tftpboot$

修改原始系统

1、挂载文件系统,将备份好的文件系统allrootfs。

参考《已有 JFFs2文件系统的修改》先安装mtd工具,然后进行如下操作即可

1
2
3
4
5
6
7
8
9
10
sudo pacman -S mtd-utils
sudo modprobe -v mtd
sudo modprobe -v jffs2
sudo modprobe -v mtdram total_size=100100 erase_size=128 (单位:K)
#查看空间大小
sudo fdisk /dev/mtdblock0 -l
sudo modprobe -v mtdblock
sudo flash_eraseall /dev/mtd0
#用dd命令将allrootfs装入mtd0分区:
sudo dd if=allrootfs of=/dev/mtd0
1
2
3
4
5
6
zhy@ubuntu:/var/tftpboot$ sudo mkdir fsmount
zhy@ubuntu:/var/tftpboot$ sudo mount -t jffs2 /dev/mtdblock0 fsmount
zhy@ubuntu:/var/tftpboot$ cd fsmount/
zhy@ubuntu:/var/tftpboot/fsmount$ ls
bin dev home lib mnt proc sbin tmp var
boot etc init media opt run sys usr

2、清除root用户密码

将etc/passwd改为

1
root::0:0:root:/home/root:/bin/sh

将自动挖矿的程序停止。将etc/rcS.d/S95cgminer.sh下的shell脚本移动到其它目录或直接删除即可

1
zhy@ubuntu:/var/tftpboot/fsmount$ sudo mv etc/rcS.d/S95cgminer.sh home/root/ 

3、重新生成jffs2文件系统

1
2
zhy@ubuntu:/var/tftpboot/fsmount$ cd .. 
zhy@ubuntu:/var/tftpboot$ mkfs.jffs2 -r fsmount -o allrootfs.new -e 0x20000 –pad=0x4000000 -n -l

4、把改好的文件系统烧回nand对应分区

1
2
3
zynq-uboot> tftpboot 0x100000 allrootfs.new 
zynq-uboot> nand erase 0x2a20000 0x4000000
zynq-uboot> nand write 0x100000 0x2a20000 0x4000000

uboot引导流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bootcmd=run $modeboot 
modeboot=nandboot

preboot=
if test $modeboot = sdboot && env run sd_uEnvtxt_existence_test; then
if env run loadbootenv; then
env run importbootenv;
fi;
fi;

importbootenv=echo Importing environment from SD ...; env import -t ${loadbootenv_addr} $filesize
loadbootenv=load mmc 0 ${loadbootenv_addr} ${bootenv}
loadbootenv_addr=0x2000000

devicetree_load_address=0x2000000
devicetree_size=0x20000
kernel_image=uImage
kernel_load_address=0x2080000
kernel_size=0x500000

nandboot=echo Copying Linux from NAND flash to RAM... && nand info && run nandroot;nand read 0x100000 0x2220000 0x300000 && fpga loadb 0 0x100000 0x300000 && nand read ${kernel_load_address} 0x300000 ${kernel_size} && nand read ${devicetree_load_address} 0x800000 ${devicetree_size} && bootm ${kernel_load_address} - ${devicetree_load_address}

如果是sd卡可以通过

编译uboot

下载 xilinx uboot https://github.com/Xilinx/u-boot-xlnx/archive/refs/tags/xilinx-v2018.3.zip

参考zynq_zc702_defconfig 添加 zynq_ebaz4205_defconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cp configs/zynq_zc702_defconfig  configs/zynq_ebaz4205_defconfig
gedit zynq_ebaz4205_defconfig

删除:
CONFIG_ENV_IS_IN_SPI_FLASH=y.

修改:
CONFIG_SYS_CONFIG_NAME="zynq_ebaz4205"
CONFIG_IDENT_STRING=" Xilinx Zynq EBAZ4205"
CONFIG_DEFAULT_DEVICE_TREE="zynq-ebaz4205"
CONFIG_DEBUG_UART_BASE=0xe0001000

增加:
CONFIG_NAND=y
CONFIG_NAND_ZYNQ=y
CONFIG_BOOTDELAY=3

CONFIG_DEBUG_UART_BASE=0xe0001000
说明使用uart1(个人猜测fsbl对fpga配置完成后,uart1 ip就连上了特定的mio/emio,只要告诉uboot,使用uart1的地址而不是uart0)

增加头文件

1
cp include/configs/zynq_zc70x.h include/configs/zynq_ebaz4205.h

增加: #define CONFIG_CPU_FREQ_HZ 666666667

gedit arch/arm/mach-zynq/Kconfig 改动点如下:

1
2
3
config SYS_CONFIG_NAME
string "Board configuration name"
default "zynq_ebaz4205"

把之前.bit和.elf文件复制到当前目录,名字改为top_pl.bit fsbl.bit。然后执行:

1
2
3
# 设置petalinux编译器环境变量
source ../petalinux-v2018.3/settings.sh
./run.sh

产生BOOT.bin和devicetree.dtb

编译kernel

下载 xilinx linux内核 https://github.com/Xilinx/linux-xlnx/archive/refs/tags/xilinx-v2018.3.zip

进入linux-xlnx-xilinx-v2018.3目录直接编译zynq Linux内核

1
2
3
4
5
6
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
cp ./arch/arm/zImage ./
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage
cp ./arch/arm/uImage ./

产生./arch/arm/zImage

1
rsync -azP ./arch/arm/boot/zImage 192.168.122.1:/home/dnsnat/workspace/share/

开发板上启动测试kernel

1
nand info && run nandroot;nand read 0x100000 0x2220000 0x300000 && fpga loadb 0 0x100000 0x300000 && tftpboot ${kernel_load_address} uImage   && nand read ${devicetree_load_address} 0x800000 ${devicetree_size} && bootm ${kernel_load_address} - ${devicetree_load_address}

查看内核版本

1
2
root@zedboard-zynq7:~# uname -a
Linux zedboard-zynq7 4.14.0-xilinx #1 SMP PREEMPT Sat Mar 23 14:47:53 CST 2024 armv7l GNU/Linux

准备文件系统

进入Linux后会报根文件系统挂载错误。可以直接使用的根文件系统:linaro-precise-ubuntu-desktop-20120723-305.tar.gz(https://releases.linaro.org/archive/12.07/ubuntu/precise-images/ubuntu-desktop/)

建议在命令行解压到SD卡ext4分区:

1
sudo tar --strip-components=3 -C /media/xxx/rootfs -xzpf linaro-precise-ubuntu-desktop-20120723-305.tar.gz binary/boot/filesystem.dir
1
2
3
4
5
6
7
8
9
10
11
vi /etc/apt/sources.list
# 源改为以下内容
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ precise main universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ precise main universe
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ precise-security main universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ precise-security main universe
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ precise-updates main universe
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ precise-updates main universe
# 安装sshd
apt-get update
apt-get openssh-server

EBAZ4205矿板petalinux开发 LINUX工程

https://blog.csdn.net/qq_36322990/article/details/107845484

zynq-7000系列板卡

https://www.fpgadeveloper.com/list-of-zynq-7000-dev-boards/

Xilinx之FPGA器件系列简介

https://zhuanlan.zhihu.com/p/622334501?utm_id=0

boot.scr、script.bin文件介绍

https://blog.csdn.net/qq_28877125/article/details/124724089

EBAZ4205 ZYNQ 7Z010原始LINUX系统的修改与使用

https://blog.csdn.net/zhys2007/article/details/106175366/

the PetaLinux Tools Documentation: Reference Guide (UG1144)

Zynq-7000 SoC Technical Reference Manual (UG585)


ZYNQ防火墙开发2-FSBL u-boot kernel rootfs PetaLinux
http://witbit.cn/视频课程/FIREWALL_GATEWAY/ZYNQ防火墙开发2-FSBL u-boot kernel rootfs PetaLinux.html
作者
朝彻
发布于
2025年2月13日
许可协议