【ZYNQ Linux移植】6-搭建日常开发的环境

0 写在前面

​       这是一个系列博客,详细介绍如何在 ZYNQ 与 ZYNQ MP 平台上如何移植 Linux 系统。目前网络上的大部分教程都是全程基于 Petalinux 的开发,虽然这样简化了开发流程,但对于初学者深入理解掌握 Linux 是不利的,所以,有了这个系列的博客,从几乎为 0 开始教大家怎么移植 Linux 系统。

       本人的软件与环境版本:

       Windows 的 Vivado 与 Vitis 版本:2020.2(前期学习 ZYNQ7020 跟随正点原子安装);

​       Ubuntu版本:18.04.2

       虚拟机上的 Vivado、Vitis 与 Petalinux 版本:2020.1(前期学习 ZYNQ MP 跟随 Alinx 安装)。

       所有相关的文件存放在虚拟机的以下路径:

~/Linux_tp

       如果后面涉及到一些命令行操作的文件路径,大家可以参考着修改为自己的路径。

在这里插入图片描述

       此外,我后续的操作与实测都是黑金(Alinx)基于 ZYNQ MP 系列的 zu3eg 操作,但基本也会对 ZYNQ-7000系列的一些不同做一些说明,如果你使用的是 ZYNQ-7000 系列的板卡,可以自己灵活变通一下。

1 移植回顾与文件剖析

       通过前面1~5篇内容,我们移植了 u-bootLinux内核根文件系统,并使用 SD 卡的 FAT 分区存放启动所需文件,EXT 分区存放根文件系统(Petalinux文件系统、Debian、Ubuntu)。

​       在移植过程中的整体结构与涉及文件如下图所示:

在这里插入图片描述

       其中,我们前面移植时是没有把设备树文件包含在 BOOT.BIN 中,它实际上也是可以被包含在 BOOT.BIN 中加载的。


       对于 FAT 分区内的有效文件,就使用的角度来说:

       1,bl31.elf 都是完全不会更改的

​       2,fsbl.elf、pmufw.elf 在不大幅度改变处理器的启动/使用情况(如后面想从纯 linux 转到 freertos + Linux 双架构)也是不需要更改的;

​       3,uboot.elf 在确保 u-boot 好用后也不需要更改;

       4,FPGA的比特文件 xxx.bit 在每次更新 Vivado 的工程后,都需要使用新生成的比特文件;

       5,与 Linux 直接相关的镜像文件 Image 和设备树文件 xxx.dtb 都是在实际开发中可能经常修改的。

​       而EXT 分区的根文件系统由于需要一直使用,不需要每次都重新解压


       因此,我们可以改变 BOOT.BIN 的包含内容,使得其内全是不太可能变化的内容,再通过 u-boot 去加载所谓可能随着我们学习与开发变化的内容。修改 SD 卡结构为:

在这里插入图片描述

       FAT 分区放入5个文件:BOOT.BINLinux镜像 Image、设备树文件 xxx.dtb、FPGA的比特文件 xxx.bit 、u-boot 的启动脚本 boot.scr;EXT 分区则是根文件系统

2 准备文件

2.1 BOOT.BIN

2.1.1 使用 Xilinx bootgen工具生成

​       具体的方法可以参考第三篇:【ZYNQ Linux移植】3-u-boot移植

       主要是需要对 .bif 进行修改,因为我们现在 BOOT.BIN 只包含 zynqmp_fsbl.elf、pmufw.elf、bl31.elf、u-boot.elf 这四个文件了:

//arch = zynqmp; split = false; format = BIN
the_ROM_image:
{
  [bootloader]./zynqmp_fsbl.elf
  [pmufw_image]./pmufw.elf
  [destination_cpu=a53-0,exception_level=el-3]./bl31.elf
  [destination_cpu=a53-0,exception_level=el-2]./u-boot.elf
}

       这里同样需要注意 arch 芯片架构的问题!

2.1.2 使用Petalinux

       先正常编译petalinux的工程:

petalinux-build

​       在打包 BOOT.BIN 时,需要注意与之前的差别!之前一般使用的是:

petalinux-package --boot --u-boot --fsbl --force(无pl端)
petalinux-package --boot --u-boot --fpga --fsbl --force(有pl端,既包含比特文件)

       而现在,我们不再把设备树和比特打包进去,需要使用:

petalinux-package --boot --fsbl --u-boot --dtb no --force

​       从打包时打印的信息,也可以看出这里打包的 BOOT.BIN 包含的内容:

​       事实上,这里文件的顺序也是至关重要的!如果是使用 bootgen 生成的话在编写 .bif 时需要特别注意。

2.2 boot.scr

       boot.scr 是 u-boot 的脚本文件,如果我们设置 u-boot 的环境变量 boot_cmd 为 run distro_bootcmd 的话,u-boot 会尝试从可能的启动设备上去扫描 boot.scr 这个文件,有的话就会自动执行

       这个文件在执行:petalinux-build 后,就会生成,放在 Petalinux工作目录/images/linux。如果没有 Petalinux,也可以直接使用以下内容作为 boot.cmd.default。不过我们需要对这个 boot.src 进行一定的修改。先进入那个目录,先使用以下命令创建一个临时的文件:

cp boot.scr boot.cmd.default

       如果是自己移植,没有Petalinux,可以自己找个文件夹,创建一个文件,把里面的内容修改为:

# This is a boot script for U-Boot
# Generate boot.scr:
# mkimage -c none -A arm -T script -d boot.cmd.default boot.scr
#
################


for boot_target in ${boot_targets};
do
	if test "${boot_target}" = "jtag" ; then
		booti 0x00200000 0x04000000 0x00100000
		exit;
	fi
	if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; then
		if test -e ${devtype} ${devnum}:${distro_bootpart} /image.ub; then
			fatload ${devtype} ${devnum}:${distro_bootpart} 0x10000000 image.ub;
			bootm 0x10000000;
			exit;
                fi
		if test -e ${devtype} ${devnum}:${distro_bootpart} /Image; then
			fatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 Image;;
		fi
		if test -e ${devtype} ${devnum}:${distro_bootpart} /system-top.dtb; then
			fatload ${devtype} ${devnum}:${distro_bootpart} 0x00100000 system-top.dtb;
		fi
		if test -e ${devtype} ${devnum}:${distro_bootpart} /rootfs.cpio.gz.u-boot; then
			fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 rootfs.cpio.gz.u-boot;
			booti 0x00200000 0x04000000 0x00100000
			exit;
		fi
		if test -e ${devtype} ${devnum}:${distro_bootpart} /system.bit; then
			fatload ${devtype} ${devnum}:${distro_bootpart} 0x02000000 system.bit;
			fpga loadb 0 ${fileaddr} ${filesize}
		fi
		booti 0x00200000 - 0x00100000
		exit;
	fi
	if test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; then
		sf probe 0 0 0;
		if test "image.ub" = "image.ub"; then
			sf read 0x10000000 0xF00000 0x6400000;
			bootm 0x10000000;
			exit;
		fi
		if test "image.ub" = "Image"; then
			sf read 0x00200000 0xF00000 0x1D00000;
			sf read 0x04000000 0x4000000 0x4000000
			booti 0x00200000 0x04000000 0x00100000
			exit;
		fi
		exit;
	fi
	if test "${boot_target}" = "nand" || test "${boot_target}" = "nand0"; then
		nand info
		if test "image.ub" = "image.ub"; then
			nand read 0x10000000 0x4100000 0x6400000;
			bootm 0x10000000;
			exit;
		fi
		if test "image.ub" = "Image"; then
			nand read 0x00200000 0x4100000 0x3200000;
			nand read 0x04000000 0x7800000  0x3200000;
			booti 0x00200000 0x04000000 0x00100000
			exit;
		fi
	fi
done

       如果是使用Petalinux的话,就对复制出来的这个文件进行修改,先把头部的第一行去掉。

​       再找到跟设备树相关的部分,把名称改为 system-top.dtb(因为内核中是让它编译成这个名字,就不用来回改了,这个可以根据自己的情况决定),再在下图位置添加对于 bit 文件的搜索的 u-boot 命令:

if test -e ${devtype} ${devnum}:${distro_bootpart} /system.bit; then
	fatload ${devtype} ${devnum}:${distro_bootpart} 0x02000000 system.bit;
	fpga loadb 0 ${fileaddr} ${filesize}
fi

​       这段 u-boot 命令的意思是检查指定的存储设备上是否存在 system.bit 文件,如果有的话,就把它加载到内存 0x02000000,再把内存中的比特流配置到 fpga

       修改后,参照这个文件上面的注释使用 mkimage 重新生成 boot.src:

mkimage -c none -A arm -T script -d boot.cmd.default boot.scr

       如果提示没有 mkimage,使用以下命令安装:

sudo apt install u-boot-tools

2.3 Linux 镜像与设备树文件

2.3.1 自己单独移植

       在获取文件前,首先需要先完善一下我们之前在移植过程中的设备树文件,如果是使用 Petalinux,就修改对应的 system-user.dtsi,如果是自己单独移植,就修改我们之前移植过程中放在 Linux 内核源码下设备树文件夹的 system-top.dts,把跟节点下 chosen 节点进行修改,主要是为了给 u-boot 传递环境变量的值:

/ {
	chosen {
		bootargs = "console=ttyPS0,115200 earlycon root=/dev/mmcblk1p2 rw rootwait";
		stdout-path = "serial0:115200n8";
	};
};

       bootargs 指定使用串口 0 (115200波特率)作为控制台,根文件系统的目录为 SD 卡的第二个分区(EXT分区)。需要注意的是,修改完设备树后,还需要按下面步骤重新编译

       设备树其实我们之前在 u-boot 和 Linux 内核移植中都进行了编译,实际上,使用这两个地方获取的设备树都是可以的,但在后续实际的学习与开发中,还是推荐使用 Linux 内核源码包去编译获取设备树,这是由于 u-boot 在初始完成编译,得到 u-boot.elf 后,我们就不需要更改了,设备树由于和 Linux 强相关,常常需要同时修改 Linux 镜像与设备树文件,所以不如直接一次性在编译内核时搞定

       如果是完全编译 Linux内核,可以使用我们在第四篇创建的脚本:

./zynqmp.sh

​       当然也可以单独只编译设备树:

make dtbs

       最后获得的文件位置为:

Image镜像文件:内核源码根目录/arch/arm64/boot
设备树文件 :内核源码根目录/arch/arm64/boot/dts/xilinx

2.3.2 使用Petalinux

       首先需要对 Petalinux 的一些设置进行修改。在读取 xsa 时设置,或者使用以下命令打开:

petalinux-config

       首先查看系统主存储设备的配置选项,根据需要修改:

-->Subsystem AUTO Hardware Settings
	-->SD/SDIO Settings
		-->Primary SD/SDIO

​       把它改为 psu_sd_1 ,这个选项指定哪个 SD/SDIO 控制器将被用作系统的主要存储接口,该控制器将用于访问启动设备(如 SD 卡),是系统启动和根文件系统所在的设备。一般的ZYNQ硬件设计里面,SD0 是用作EMMC,SD1才是用作SD卡使用,具体是否需要修改,要根据具体硬件设计以及 Vivado 中 Block Design 中的 ZYNQ 核配置来决定:


​       修改完后,修改 dtb image settings ,绝对的路径为:

-->Subsystem AUTO Hardware Settings
	-->Advanced bootable images storage Settings(确保这个选项勾选,回车进入下一级)
		-->dtb image settings
			-->image storage media

       这样修改,相当于是设置了 dtb 文件将从 SD卡进行加载,而不是从 image.ub 中获取。

注意这也会影响 bootloader (我们用的 U-Boot) 加载 DTB 的方式。

       这里还需要注意一个点,在 image storage media 同级目录下,有个image name的选项,它默认是 system.dtb。这个选项是指,后面在系统加载时,会在 SD 卡中搜索 system.dtb 进而加载,所以我们后面放进去的设备树文件,最后也得改成这个名字。


       然后,修改 SD 卡相关的选项。

​       一是启动的文件系统类型,绝对路径为:

-->Image Packaging Configuration
	-->Root filesystem type

       把它改为 EXT4 ,这是指定根文件系统的文件系统类型

​       二是在同级的菜单里,有一个选项叫:Device node of SD device

​       把它改为 /dev/mmcblk1p2 。即指定 SD 卡第二个分区作为根文件系统。(一般 SD 卡是第一个分区设置为 FAT 分区用来启动,第二个分区设置为 EXT4 分区,作为根文件系统,具体原因,见:嵌入式Linux开发为什么要设置FAT与EXT两个分区 )。

       修改完所有后,保存退出。一定要记得保存!一定要记得保存!一定要记得保存!

       在 build 完后(修改了.xsa记得重新加载 .xsa),就可以在以下目录获取镜像与设备树:

petalinux工程目录/images/linux

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

       这里有两种 image,一种是 Image,它与我们单独在第四篇:【ZYNQ Linux移植】4-内核移植 中编译所得的镜像是一致的,其实就是 Petalinux 帮我们编译得到的。

​       第二种则是 Petalinux 三件套的 image.ub,我们知道使用 Petalinux 的话,一般是在 FAT 分区放置上图的连续三个文件:boot.scr 、BOOT.BIN 、Image.ub。而 Petalinux 在使用时打包 BOOT.BIN 一般是把比特文件包含在内的,也就是说,与我们在第一部分的原始结构图相比,可以推测 Petalinux 的这个 image.ub 是最起码也包含上面的 Image 和设备树文件的。我们也可以通过以下命令来分析这个文件:

mkimage -l image.ub

       结果与推测一致:

       如果采用 Petalinux 的三件套启动方式,就使用 image.ub,同时也就不需要把设备树文件 system.dtb 放入 FAT 分区了。

2.4 FPGA部分的比特文件

2.4.1 通过 Vitis 获取

       这部分在第二篇:【ZYNQ Linux移植】2-获取设备树 中的 2.2 节介绍从 Vitis 获取设备树时同时获取了 xxx.bit。

2.4.2 通过 Petalinux 获取

​       如果是使用 Petalinux 的话,在加载完 .xsa 并 build 后,可以在以下目录找到 xxx.bit:

petalinux工程目录/project-spect/hw-description

2.4.3 通过 Vivado 获取

       当然,对于比特文件,最熟悉的应该是从 Vivado 获取,其生成后的所在路径为:

Vivado工程目录/xxx.runs/impl_x/

2.5 根文件系统

​       根文件系统直接按照第五篇:【ZYNQ Linux移植】5-根文件系统移植的步骤进行即可,这里没有变化。

       如果是使用 Petalinux 提供的最小系统的话,还有一个可以优化的点是让根文件系统自动登录,不再需要我们再每次手动输入用户名和密码。

       在 Petalinux 的工程目录下,执行以下命令:

petalinux-config -c rootfs

       按以下路径进入:

-->Image Features
	-->auto-login

       勾选 auto-login,再保存退出,重新编译 Petalinux

3 u-boot修改

​       按照以上步骤准备好所有的文件后,放入 SD 卡的对应分区,使用 SD 卡模式启动开发板,然后快速地按回车键,在u-boot 下修改环境变量。

       为了避免大家的不一致性,可以先把所有环境变量恢复到初始值

env default -a

       这里修改的主要是两个变量:bootcmd 与 boot_targets。bootcmd 是 u-boot 启动后就会运行的命令,这里的 “run distro_bootcmd” 是尝试从可能的启动设备上(也就是后面的 boot_targets)扫描 boot.scr 文件,再通过 boot.scr 文件尝试启动。使用以下命令进行修改:

env set bootcmd "run distro_bootcmd"
env set boot_targets "mmc0 mmc1 jtag qspi0 nand0 usb0 usb1 scsi0 pxe dhcp"

​       关于细致的这两个环境变量为什么要这么修改,可以看我另一篇关于 debug u-boot 的博客:占位。而由于我们在设备树已经对 boot_args 进行了指定,它会在执行 boot.scr 加载完设备树文件后写入,这里就不需要修改了,修改了也是无效的。

       最后记得保存到 Flash,然后重新启动即可:

saveenv
reset

​       我这里使用的是 Debian,reset 后会自动启动系统,最后如下图所示:

4 总结

       本篇主要是对前面几篇中 FAT 中的文件进行了重新组织,把原来包含在 BOOT.BIN 中的设备树文件剥离出来,让 BOOT.BIN 只包含基本不会更改的部分:fsbl.elf、pmufw.elf、bl31.elf、u-boot.elf,使用 boot.scr 加载需要经常修改的设备树文件 xxx.dtb、 Image和 xxx. bit

5 参考资料

1,DeepSeeker相关搜索结果;

2,《正点原子 MPSoC-P5B之嵌入式Linux开发指南_V1.0》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辣个蓝人QEX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值