ZYNQ嵌入式Linux编译启动方式

1 开发环境设置

1.1 安装虚拟机系统

  1. 安装VirtualBox
  2. 安装Ubuntu 18.04.4

注意:安装该版本系统后不要安装更新,否则系统版本更新会不兼容PetaLinux。

  1. 安装PetaLinux 2020.2

安装PetaLinux前,需先安装以下环境:
sudo apt-get install tofrodos iproute2 gawk gcc g++ git make net-tools libncurses5-dev tftpd zlib1g:i386 libssl-dev flex bison libselinux1 gnupg wget
diffstat chrpath socat xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential libsdl1.2-dev libglib2.0-dev screen pax gzip automake
在使用petalinux前,需执行指令source <PETALINX_INSTALL_DIR>/settings.sh,使得Petalinux环境变量生效

1.2 开启FTP服务

FTP(File Transfer Protocol)是一种文件传输协议。

  1. 安装FTP服务
sudo apt-get install vsftpd
  1. 编辑配置文件
sudo vim /etc/vsftpd.conf

使能以下配置:
write_enable=YES
local_enable=YES
  1. 重启FTP服务
sudo /etc/init.d/vsftpd restart 
或
service vsftpd restart

1.3 开启TFTP服务

TFTP(Trivial File Transfer Protocol)是一种简单的文件传输协议。

  1. 安装TFTP
sudo apt-get install tftp-hpa tftpd-hpa
tftp-hpa是客户端软件包,不用可以不装
  1. 配置TFTP
    建立TFTP工作目录,目录路径可自定义。
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot

编辑配置文件。

sudo vim /etc/default/tftpd-hpa
修改如下
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"

TFTP_DIRECTORY就是上面创建的/tftpboot 文件夹目录,该目录可自定义。

  1. 重启TFTP服务
sudo service tftpd-hpa restart

1.4 开启NFS服务

NFS(Network File System)网络文件系统。
安装NFS服务

sudo apt-get install nfs-kernel-server

配置NFS
NFS允许挂载的目录及权限在文件/etc/exports文件中定义,若定义挂载文件夹放置在/home/zynq/linux/nfs文件夹下,则在该配置文件末尾添加如下配置:

/home/zynq/linux/nfs *(rw,sync,no_root_squash)

*代表允许所有的网络段访问, rw 是可读写权限,sync 是文件同步写入存储器, no_root_squash是nfs客户端权限分享至该目录,即如果nfs客户端是root用户,则对该共享目录而言该用户就是root用户。
重启NFS服务

sudo service nfs-kernel-server restart

可运行如下命令显示共享目录

showmount -e

若在nfs运行过程中修改了exports文件,则运行如下命令使修改生效

sudo exportfs -rv

2 系统开发

2.1 使用PetaLinux编译Linux镜像

详细参考文档ug1144-petalinux-tools-reference-guide-v2020.2.pdf。

2.1.1 搭建ZYNQ硬件平台

硬件构成最低要求:

  1. 1个TTC(Triple Timer Counter);
  2. 外部存储器(DDR),至少32MB大小;
  3. 1个UART串口;
  4. 非易失性存储器,QSPI或者SD卡,若没有,则只能通过JTAG方式启动Linux系统;
  5. 网卡(可选),当从网络访问时需要,注意勾选MDIO。
    使用vivado构建工程,导出硬件描述文件.xsa文件。
2.1.2 构建工程并从SD卡启动

使用指令前,需先执行

source <PetaLinux_Install_Directory>/settings.sh

初始化运行环境。

  1. 创建工程
petalinux-create --type project --template zynq --name <PROJECT_NAME>

<PROJECT_NAME>为自定义的工程名。

  1. 导入硬件描述文件
petalinux-config --get-hw-description <PATH-TO-XSA Directory>/<XSA>
或
petalinux-config --get-hw-description=<PATH-TO-XSA Directory>/<XSA>

<PATH-TO-XSA Directory>/为.xsa文件所在的目录,<XSA>为.xsa文件名。若硬件描述文件更新了,则再次使用此命令更新工程配置。
该命令执行后会出现系统配置菜单,该菜单由PetaLinux根据硬件配置文件自动生成相应选项,可根据需要进行相应的配置。

  1. 配置U-Boot(可选)
petalinux-config -c u-boot
  1. 配置Linux内核(可选)
petalinux-config -c kernel

该命令执行后,等待一段时间会出现Linux内核配置菜单。

  1. 配置根文件系统(可选)
petalinux-config -c rootfs

该命令执行后,出现根文件系统配置菜单,可以配置用户名及密码,默认用户root,密码root。

  1. 配置设备树
    根据需要配置设备树文件,用户设备树路径在当前工程目录下的
project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
  1. 编译工程
petalinux-build

该命令执行后,将生成设备树 DTB 文件、 fsbl 文件、 U-Boot 文件, Linux 内核和根文件系统映像。 编译完成后,生成的映像将位于工程目录下的 images/linux/ 目录下。 fsbl文件、u-boot由PetaLinux自动配置生成。

  1. 制作启动文件
    ZYNQ 的启动文件 BOOT.BIN 一般包含 fsbl 文件、 bitstream 文件和 uboot 文件。
petalinux-package --boot --fsbl --fpga --u-boot --force

该命令生成BOOT.BIN启动文件,–boot选项为生成可引导映像,其中–fsbl、–fpga、–u-boot后均跟文件相应的路径,若为空,则使用默认的images/linux/目录下相应的文件。

  1. 制作SD启动卡

1.卸载SD卡(sd卡节点为sdb)

umount /dev/sdb*

2.创建SD卡分区

sudo fdisk /dev/sdb
p 查看当前SD卡分区数
d 删除分区,多个分区时需指定删除的分区号
n 新建一个启动分区

p 使其为主分区,使用默认分区号 1 和第一个扇区 2048,最后一个扇区输入“+100M”,为该分区预留100MB空间
t 设置分区类型

c 选择分区类型为“W95 FAT32 (LBA)”
a 选择分区为引导分区

n 新建一个根文件系统分区,全部默认即可
w 保存分区设置

  1. 格式化SD卡分区

sudo mkfs.vfat -F 32 -n boot /dev/sdb1
sudo mkfs.ext4 -L rootfs /dev/sdb2

  1. 启动系统
    拷贝工程目录下images/linux/目录下的BOOT.BIN、boot.scr、image.ub文件到SD卡的boot分区,将SD卡插入开发板上电启动。

2.1.3 使用JTAG启动Linux系统

  1. 安装USBCable仿真器驱动
    在PetaLinux安装目录下的/tools/xsct/data/xicom/cable_drivers/lin64/install_script/install_drivers/install_drivers,安装此驱动。
  2. 生成预构建文件
petalinux-package --prebuilt --fpga <FPGA bitstream>

若没有FPGA位流文件可以不写。
3. Jtag启动系统
将ZYNQ设置为Jtag启动模式,连接USB仿真器,进入工程目录,输入命令启动

petalinux-boot --jtag --prebuilt <BOOT_LEVEL>

<BOOT_LEVEL>为数字1,2,3表示启动级别。1表示下载预构建的FPGA位流文件,2表示下载预构建的FPGA位流文件和启动预构建的U-Boot,3表示下载预构建的FPGA位流文件和FSBL文件,启动预构建的U-Boot和Linux内核。

petalinux-boot --jtag --prebuilt 3

2.1.4 使用QEMU启动Linux系统

  1. 生成预构建文件
petalinux-package --prebuilt --fpga <FPGA bitstream>

若没有FPGA位流文件可以不写。

  1. 进入工程目录启动系统
petalinux-boot --qemu --prebuilt 3

qemu启动时,不支持启动级别1。

2.2 不使用PetaLinux编译镜像

  1. 文件准备
  1. FPGA的.bit文件
  2. fsbl文件
  3. 获取设备树源码模板 设备树Device-Tree仓库
  4. 获取U-Boot源码 U-Boot仓库
  5. 获取Linux源码 Linux仓库
  1. 生成FSBL与设备树
  1. 打开vitis软件,点击菜单栏Xilinx->Software Respositories->新建一个local respositories,路径选择刚刚下载好的设备树模板源代码目录,保存关闭。
  2. 导入硬件描述文件.xsa,新建硬件平台,类型选择为Device-Tree,编译完后,工程目录下将出现fsbl文件,在 ps7_cortexa9_0/device_tree_domain/bsp/目录下出现根据硬件描述文件生成的设备树源文件。
  1. 编译U-Boot
  1. 将vitis生成的设备树文件,做适当修改后,拷贝到u-boot目录下arch/arm/dts/文件夹下,文件有pcw.dtsi、system-top.dts、zynq-7000.dtsi

system-top.dts需修改网络部分:

&gem0 {
  local-mac-address = [00 0a 35 00 00 00];
  phy-handle = <&ethernet_phy>;
  phy-mode = "rgmii-id";
  status = "okay";
  xlnx,ptp-enet-clock = <0x69f6bcb>;
  ethernet_phy: ethernet-phy@1 {          /* rtl8211e */
      reg = <0x1>;
      device_type = "ethernet-phy";
  };
};
  1. 修改u-boot目录下arch/arm/dts/Makefile文件,在dtb-$(CONFIG_ARCH_ZYNQ)配置选项下添加system-top.dtb,表示生成设备树二进制文件
  2. 修改include/configs/zynq-common.h文件,该文件是用于配置 zynq 系列处理器的通用配置文件,修改CONFIG_CPU_FREQ_HZ宏定义,修改为666666678,表示实际zynq的运行频率
  3. 拷贝一份u-boot目录下configs/xilinx_zynq_virt_defconfig配置文件为xilinx_zynq7020_defconfig,修改该文件如下:
  • 屏蔽有关SPL启动的配置选项,如CONFIG_SPL,包含SPL的都屏蔽
  • CONFIG_SD_BOOT=y
  • CONFIG_DEFAULT_DEVICE_TREE=“system-top”
  • CONFIG_OF_LIST=“system-top”
  • 也可用make ARCH=arm CROSS_COMPILE=arm-none-eabi- menuconfig命令图形化配置
  1. 使用make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j8编译u-boot,生成u-boot.elf文件
  2. 将编译u-boot时生成的system-top.dtb文件,在u-boot目录下arch/arm/dts/文件夹下,拷贝到petalinux工程目录下的images/linux/目录下,并重命名为system.dtb。使用petalinux-package --boot --fsbl <FSBL_PATH> --u-boot <U-BOOT_PATH> --fpga <BITSTREAM_PATH>命令生成启动文件BOOT.BIN。
  1. 编译Linux
  1. 将vitis生成的设备树文件,做适当修改后,拷贝到linux目录下arch/arm/boot/dts/文件夹下,文件有pcw.dtsi、system-top.dts、zynq-7000.dtsi

system-top.dts需修改网络部分:

&gem0 {
  local-mac-address = [00 0a 35 00 00 00];
  phy-handle = <&ethernet_phy>;
  phy-mode = "rgmii-id";
  status = "okay";
  xlnx,ptp-enet-clock = <0x69f6bcb>;
  ethernet_phy: ethernet-phy@1 {          /* rtl8211e */
      reg = <0x1>;
      device_type = "ethernet-phy";
  };
};
  1. 修改linux目录下arch/arm/boot/dts/Makefile文件,在dtb-$(CONFIG_ARCH_ZYNQ)配置选项下添加system-top.dtb,表示生成设备树二进制文件
  2. 执行命令make ARCH=arm CROSS_CPMPILE=arm-none-eabi- xilinx_zynq_defconfig配置linux内核
  3. 执行命令make ARCH=arm CROSS_CPMPILE=arm-none-eabi- -j8执行编译,生成的文件在arch/arm/boot/目录下
  1. SD卡启动
  1. 将BOOT.BIN、system.dtb、system.bit、zImage拷贝至SD卡的fat分区
  2. 设置u-boot环境变量SD卡启动指令,不使用ramdisk
Zynq> setenv kernel_load_address 0x4000000
Zynq> setenv devicetree_load_address 0x8000000
Zynq> setenv bitstream_load_address 0x100000
Zynq> setenv bitstream_image system.bit
Zynq> setenv bitstream_size 0x300000
Zynq> setenv kernel_image zImage
Zynq> setenv devicetree_image system.dtb
Zynq> setenv sdboot 'if mmcinfo; then echo Copying Linux from SD to RAM... && load mmc 0
${bitstream_load_address} ${bitstream_image} && fpga loadb 0 ${bitstream_load_address} ${bitstream_size} &&
load mmc 0 ${kernel_load_address} ${kernel_image} && load mmc 0 ${devicetree_load_address}
${devicetree_image} && bootz ${kernel_load_address} - ${devicetree_load_address}; fi'
Zynq> saveenv
Zynq> run sdboot
  1. 烧写u-boot至QSPI Flash并从SD卡启动Linux
  1. 使用PetaLinux工具

此方式启动Linux系统时,需将Linux系统镜像image.ub放置在SD卡的fat分区中,从SD读取Linux启动并执行。u-boot启动后执行sd卡启动脚本,即启动linux系统。
u-boot从spi flash引导linux启动的配置步骤: petalinux-config --> Subsystem AUTO Hardware Settings --> Advanced bootable images storage Settings --> boot image settings --> image storage media --> primary flash。保存退出。
petalinux-build编译工程
打开vitis,建立一个zynq fsbl工程,菜单xilinx->Program Flash,启动文件选择上一步生成的BOOT.BIN文件,烧写完成将开发板调整成QSPI启动模式即可

  1. 使用u-boot源码构建
    将Linux系统镜像zImage、ramdisk文件、设备树文件放置在SD卡的fat分区中,并使用fat load指令加载镜像、ramdisk、设备树,使用bootz启动Linux。

进入u-boot源码目录,执行make ARCH=arm CROSS_COMPILE=arm-none-eabi- menuconfig
进入Environment菜单项,进行如下配置:

[x] Environment is in SPI flash

[x] Use automatically detected sector size

(0x500000) Environment offset
(0x1000) Environment Sector-Size
保存

执行make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j8编译生成u-boot.elf
最后进入petalinux工程目录并使用petalinux-package对fsbl与u-boot进行打包生成BOOT.BIN文件,注意需要将u-boot的设备树.dtb文件拷贝至images/linux/目录下,重命名为system.dtb。也可使用vitis的打包工具将fsbl.elf、system.bit、u-boot.elf打包生成BOOT.BIN文件。
打开vitis,建立一个zynq fsbl工程,菜单xilinx->Program Flash,启动文件选择上一步生成的BOOT.BIN文件,烧写完成将开发板调整成QSPI启动模式即可

  1. 烧写u-boot、linux、ramdisk至QSPI Flash并启动
  1. 在u-boot目录中修改设备树chosen节点的bootargs启动参数,使linux使用ramdisk文件系统:
chosen {
       bootargs = "console=ttyPS0,115200 root=/dev/ram/ rw earlyprintk earlycon";
       stdout-path = "serial0:115200n8";
   };

编译设备树

  1. 制作烧写文件

需要文件 fsbl.elf、system.bit、u-boot.elf、zImage、system.dtb、rootfs.cpio.gz.u-boot
编写vitis制作烧写文件所需的.bif文件,内容如下(文件路径可自定义)

//arch = zynq; split = false; format = BIN
the_ROM_image:
{
	[bootloader]C:\Users\Desktop\program\fsbl.elf
    C:\Users\Desktop\program\system.bit
	C:\Users\Desktop\program\u-boot.elf
	[offset = 0x520000]C:\Users\Desktop\program\zImage
	[offset = 0xFA0000]C:\Users\Desktop\program\system.dtb
	[offset = 0xFB9000]C:\Users\Desktop\program\rootfs.cpio.gz.u-boot (注:64字节的头部信息 + 文件系统包,是使用u-boot源码下tools/mkimage工具生成的RamDisk文件)
}

镜像地址分配如下,SPI Flash大小为32MB,各部分分配如下图所示
在这里插入图片描述

  1. 编写启动脚本

开发板上电从spi启动,进入u-boot命令行界面,编写启动脚本,也可以直接编译进入u-boot的源码中,可更改源文件u-boot目录下include/configs/zynq-common.h添加启动脚本指令
加载FPGA的bit文件

setenv sf_boot 'sf probe 0 0 0 && echo loading bitstream... && sf read 0x800000 0x1A00000 0x500000 && fpga loadb 0 0x800000 0x400000 && echo loading zImage... && sf read 0x4000000 0x520000 0x433334 && echo loading deviceTree... && sf read 0x8000000 0xFA0000 0x3000 && echo loading rootfs.cpio.gz... && sf read 0x9000000 0xFB9000 0x700000 && bootz 0x4000000 0x9000000 0x8000000'
saveenv
run sf_boot

不加载FPGA的bit文件

setenv sf_boot 'sf probe 0 0 0 && echo loading zImage... && sf read 0x4000000 0x520000 0x433334 && echo loading deviceTree... && sf read 0x8000000 0xFA0000 0x3000 && echo loading rootfs.cpio.gz... && sf read 0x9000000 0xFB9000 0x700000 && bootz 0x4000000 0x9000000 0x8000000'
saveenv
run sf_boot
  1. 烧写eMMC并启动
  1. 方法1
    总体步骤:烧写fsbl、fpga.bit、u-boot(上述文件可打包)到QSPI flash中,从QSPIFlash启动Linux系统,也可SD卡启动或者从网络启动,进入linux系统后,对mmc通过指令进行分区,boot分区和文件系统分区,随后在boot分区中放置linux镜像、设备树文件,在文件系统分区放置文件系统。注意:u-boot需设置为从emmc中启动系统,设备树的bootargs根文件系统修改rootfs=/dev/mmcblk1p1。
  2. 方法2(未验证)
  1. 将fsbl、u-boot烧写进QSPI Flash中并从QSPI Flash启动
  2. 通过u-boot将emmc进行分区
  3. 通过tftp将zImage、rootfs、device-tree.dtb文件加载到DDR
  4. 通过fatwrite指令将上述文件写入emmc相应分区
  5. 通过u-boot指令脚本从emmc中加载相应文件,通过bootz指令启动linux系统
  1. 通过网络NFS启动

1.修改u-boot的bootargs变量(也可硬编码至设备树choosen节点的bootargs变量),重新编译u-boot(IP地址根据实际进行修改)

setenv bootargs root=/dev/nfs rw nfsroot=192.168.0.25:/home/zlc/nfs,v3 ip=192.168.0.23:192.168.0.25:192.168.1.1:255.255.255.0::eth0:off init=/sbin/init console=ttyPS0,115200

2.创建tftp镜像加载指令(不加载FPGA的bit文件)

setenv kernel_load_address 0x4000000
setenv device_tree_load_address 0x8000000
setenv kernel_image zImage
setenv device_tree system.dtb
setenv netboot 'tftpboot ${kernel_load_address} ${kernel_image} && tftpboot ${device_tree_load_address} ${device_tree} && bootz ${kernel_load_address} - ${device_tree_load_address}'
saveenv
启动 run netboot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值