1)实验平台:正点原子MPSoC开发板
2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html
第十二章U-Boot移植
上一章节我们讲解了uboot的使用,对uboot有了一个初步的了解。前两章我们都是使用的正点原子提供的uboot,本章我们就来学习如何将Xilinx官方的uboot移植到正点原子的ZYNQ MPSoC开发板上,学习如何在uboot中添加我们自己的板子。
12.1U-Boot源码获取及目录分析
12.1.1获取U-Boot源码
Xilinx官方提供的uboot源码发布在github网站https://github.com/Xilinx/u-boot-xlnx,如下图所示:
图 12.1.1 Xilinx发布的uboot源码
可以从github网站clone或下载uboot源码,注意要与Petalinux版本一致,否则可能会出现一些问题,我们使用的是2019.2版本的Petalinux,所以选择的uboot要带2019.2(Tags带2019.2)。不过我们不从上面的github网站下载,因为在11.2节使用Petalinux配置和编译U-Boot时,Petalinux工具就已经生成了uboot源码,如图 11.2.2 uboot源码所示,所以没有必要从github网站下载。
本章的uboot移植需要使用该源码,为了方便访问以及和后面章节的linux内核源码放在同一目录下,方便管理,我们在当前用户home目录下新建一个名为git.d的文件夹,并将Petalinux生成的uboot源码拷贝到该文件夹下,如下图所示:
图 12.1.2 拷贝uboot源码到git.d目录
进入~/git.d/u-boot-xlnx目录,输入“git status”和“git remote -v”命令,如下图所示:
图 12.1.3 git status
可以看到当前uboot源码位于devtool分支,而且与Xilinx发布在github网站的uboot源码是同步的,没有做任何修改。由于笔者没有在github网站找到devtool分支以及tags,所以将其切换到与Petalinux 2019.2版本兼容的最新的tags标签上,也就是tag xilinx-v2019.2,并在此tag上创建分支u-boot-xlnx,命令如下:
git fetch origin tag xilinx-v2019.2
git checkout tags/xilinx-v2019.2 -b u-boot-xlnx
结果如下图所示:
图 12.1.4 创建u-boot-xlnx分支
当然了,也可以使用默认的devtool分支,没有实质上的区别。
12.1.2U-Boot工程目录分析
在移植uboot之前,我们需要先了解uboot工程目录结构,如下图所示:
图 12.1.5解压后的uboot
上图中除了oe-logs、oe-workdir和oe-local-files这三个Petalinux工具相关的文件外,其他的文件和文件夹都是uboot源码本身的。这些文件夹或文件的含义如下表所示:
表 12.1.1 uboot目录列表
上表中的很多文件夹和文件我们都不需要去关注,我们要关注的文件夹或文件如下:
1.arch文件夹
这个文件夹里面存放着和芯片架构有关的文件,如下图所示:
图 12.1.6 arch文件夹
从上图可以看出有很多架构,比如arm、x86、riscv等,我们现在用的是ARM芯片,所以只需要关注arm文件夹即可,进入arm文件夹里面内容如下图所示:
图 12.1.7 arm文件夹
mach开头的文件夹是跟具体的设备有关的,比如“mach-exynos”就是跟三星的exyons系列CPU有关的文件。我们使用的是Zynq UltraScale+ MPSoC,所以要关注“mach-zynqmp”这个文件夹。另外“cpu”这个文件夹也是和cpu架构有关的,文件夹内容如下图所示:
图 12.1.8 cpu文件夹
从上图可以看出有多种ARM架构相关的文件夹,Zynq UltraScale+ MPSoC使用的是Cortex-A53内核,Cortex-A53属于armv8,所以我们要关注“armv8”这个文件夹。cpu文件夹里面有个名为“u-boot.lds”的链接脚本文件,这个就是ARM芯片所使用的u-boot链接脚本文件。armv8文件夹里面的文件都是跟ARMV8架构有关的。
2.board文件夹
board文件夹就是和具体的开发板有关的,打开此文件夹,里面全是不同的板子,borad文件夹里面有个名为“xilinx”的文件夹,里面存放的是Xilinx厂商所有支持uboot的芯片系列,如下图所示:
图 12.1.9 xilinx文件夹
所有使用xilinx芯片的板子都放到此文件夹中。该文件夹下有7个文件夹,其中bootscripts用于生成启动脚本boot.scr、common是所有开发板通用的、microblaze-generic表示使用microblaze软核IP的FPGA开发板、zynq表示使用ZYNQ-7000系列芯片的开发板、zynqmp表示使用ZYNQ MPSOC系列芯片的开发板、zynqmp_r5表示使用ZYNQ MPSoC系列芯片的R5处理器的开发板、versal表示使用Versal系列芯片的开发板。正点原子的开发板是ZYNQ MPSoC系列的开发板,我们后面移植uboot的时候就是参考zynqmp这个文件夹来定义我们的开发板。
3.configs文件夹
此文件夹为uboot配置文件,uboot是可配置的,但是你要是自己从头开始一个一个项目的配置,那就太麻烦了,因此一般半导体或者开发板厂商都会制作好一个配置文件。我们可以在这个做好的配置文件基础上来添加自己想要的功能,这些半导体厂商或者开发板厂商制作好的配置文件统一命名为“xxx_defconfig”,xxx表示开发板名字,这些defconfig文件都存放在configs文件夹,因此,Xilinx官方开发板的配置文件肯定也在这个文件夹中,如下图所示:
图 12.1.10 Xilinx芯片系列开发板配置文件
上图中的以“xilinx”开头的文件都是xilinx芯片系列的配置文件。其中“xilinx_zynqmp_zcu102_rev1_0_defconfig”、“xilinx_zynqmp_zcu102_revA_defconfig”、“xilinx_zynqmp_zcu102_revB_defconfig”是我们参考的Xilinx官方的ZYNQ ZCU102开发板配置文件的不同版本,后面我们使用“xilinx_zynqmp_zcu102_rev1_0_defconfig”这个版本的配置文件。
4.Makefile文件
这个是顶层Makefile文件,Makefile是支持嵌套的,也就是顶层Makefile可以调用子目录中的Makefile文件。Makefile嵌套在大项目中很常见,一般大项目里面所有的源代码都不会放到同一个目录中,各个功能模块的源代码都是分开的,各自存放在各自的目录中。每个功能模块目录下都有一个Makefile,这个Makefile只处理本模块的编译链接工作,这样所有的编译链接工作就不用全部放到一个Makefile中,可以使得Makefile变得简洁明了。
uboot源码根目录下的Makefile是顶层Makefile,它会调用其它的模块的Makefile文件,比如drivers/cpu/Makefile。当然了,顶层Makefile要做的工作可远不止调用子目录Makefile这么简单。
5.README
README文件描述了uboot的详细信息,包括uboot该如何编译、uboot中各文件夹的含义、相应的命令等等。建议大家详细的阅读此文件,可以进一步增加对uboot的认识。
关于uboot根目录中的文件和文件夹的含义就讲解到这里,接下来就要开始移植uboot了。
12.2Petalinux使用外部U-Boot源码
上一节我们将Petalinux生成的uboot源码移动到~/git.d/u-boot-xlnx目录(绝对路径/home/shang/git.d/u-boot-xlnx),这样导致Petalinux工程无法使用访问uboot源码了,所以在移植uboot之前,我们了解下如何让Petalinux能访问移动后的uboot源码。
方法如下:
- 进入到Petalinux工程目录下,设置好Petalinux工作环境后,输入“petalinux-config”命令配置Petalinux工程。
设置Linux Components Selection —> u-boot (u-boot-xlnx) —>为“ext-local-src”,如下图所示:
图 12.2.1配置u-boot
该配置项将u-boot来源配置为外部的本地源。设置好后按回车键返回。设置External u-boot local source settings —> External u-boot local source path为“/home/shang/git.d/u-boot-xlnx”,也就是当前uboot源码存放的目录,结果如下图所示:
图 12.2.2 配置External u-boot local source path
保存配置并退出,现在该Petalinux工程就可以访问和使用/home/shang/git.d/u-boot-xlnx中的源码了。
但是笔者在使用petalinux2019.2时,按照上面步骤设置后,编译petalinux工程会出现报错,猜测可能是这个版本的petalinux存在bug。解决的方法是在u-boot-xlnx原来的位置建立一个指向/home/shang/git.d/u-boot-xlnx的链接,如下图所示:
图 12.2.3 建立u-boot-xlnx链接
需要注意的一点是在Petalinux工程中配置和编译u-boot时需要先清理~/git.d/u-boot-xlnx中的源码(命令make distclean),否则配置和编译会报错,如下图所示:
图 12.2.4 编译petalinux工程
12.3Xilinx官方开发板uboot编译测试
uboot的移植并不是说我们完完全全的从零开始将uboot移植到我们现在所使用的开发板或者开发平台上。这个对于我们来说基本是不可能的,这个工作一般是半导体厂商做的,半导体厂商负责将uboot移植到他们的芯片上,因此半导体厂商都会自己做一个开发板,这个开发板就叫做原厂开发板,比如大家学习STM32的时候听说过的discover开发板就是ST自己做的。半导体厂商会将uboot移植到他们自己的原厂开发板上,测试好以后就会将这个uboot发布出去,这就是大家常说的原厂BSP包。我们一般做产品的时候就会参考原厂的开发板做硬件,然后在原厂提供的BSP包上做修改,将uboot或者linux kernel移植到我们的硬件上。这个就是uboot移植的一般流程:
① 在uboot中找到参考的开发平台,一般是原厂的开发板。
② 参考原厂开发板移植uboot到我们所使用的开发板上。
正点原子的ZYNQ MPSoC开发板参考的是Xilinx官方的ZYNQ ZCU102开发板做的硬件,因此我们在移植uboot的时候就可以以Xilinx官方的ZYNQ ZCU102开发板为蓝本。
在移植之前,我们先编译一下Xilinx官方ZCU102开发板对应的uboot。编译uboot源码之前,需要先添加交叉编译工具链路径,然后设置环境变量ARCH和CROSS_COMPILE。ARCH指定源码适配的芯片架构,即编译好的uboot运行在什么平台上,CROSS_COMPILE指定所用的交叉编译工具前缀。比如对于ZYNQ MPSoC而言,可以按照如下方式设置:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
而对于我们使用的ZYNQ MPSoC开发板,不用上面的方法设置环境变量,只需要执行10.5节的设置SDK的工作环境即可,SDK会自动设置相应的环境变量,如下图所示:
图 12.3.1 设置SDK的工作环境
12.3.1查找Xilinx官方的开发板默认配置文件
在12.1.2节U-Boot工程目录分析章节中,configs目录下存放了很多跟Zynq MPSoC有关的配置,如下图所示,
图 12.3.2 Xilinx官方Zynq MPsoc默认配置文件
从上图可以看出有很多的默认配置文件,其中以xilinx_zynqmp开头的是ZYNQ MPSoc相关开发板的配置文件。其中“xilinx_zynqmp_zcu102_rev1_0_defconfig”、“xilinx_zynqmp_zcu102_revA_defconfig”、“xilinx_zynqmp_zcu102_revB_defconfig”是ZYNQ ZCU102开发板的配置文件。
12.3.2编译Xilinx官方开发板对应的uboot
注:需要先执行10.5节设置SDK的工作环境。
找到Xilinx官方ZYNQ ZCU102开发板对应的默认配置文件以后可以编译一下,这里我们使用“xilinx_zynqmp_zcu102_rev1_0_defconfig”配置文件。编译uboot命令如下:
make distclean
make xilinx_zynqmp_zcu102_rev1_0_defconfig
make -j8
编译完成以后结果如下图所示:
图 12.3.3编译结果
从上图可以看出,编译成功。其中“make distclean”表示清除所有生成的文件,“make -j8”表示使用8核来编译uboot。“-j”参数用于设置主机使用多少个核来编译uboot,设置的核越多,编译速度越快。-j8表示使用8个核编译uboot,具体设置多少个要根据自己的虚拟机或者电脑配置,如果你给VMware分配了4个核,那么最多只能使用-j4。
编译完成以后会生成u-boot.bin、u-boot.elf、u-boot.dtb等文件。需要下载到开发板上运行的文件有u-boot.elf、u-boot.dtb。这两个文件是运行uboot必不可少的。
12.3.3验证与驱动测试
使用Petalinux工具,测试还是比较方便的,可以直接生成BOOT.bin文件,不过每次生成BOOT.bin文件并将其拷贝到SD卡还是比较麻烦的。最简便的方法是直接使用JTAG下载,使用JTAG下载需要做的准备工作如下:
1)需要手动在Ubuntu虚拟机中安装JTAG驱动,安装方式见5.5小节Linux系统安装JTAG cable驱动;
2)用下载器连接开发板和电脑,连接完成后,进入如下操作将下载器对接到虚拟机中——在Vmware软件的菜单栏点击“虚拟机(M)”菜单,在弹出的子菜单中移动到“可移动设备(D)”,会弹出相应的移动设备,里面带有“Digilent USB”的是JTAG的USB接口,连接该USB接口,如下图所示:
图 12.3.4在Vmware中连接JTAG的USB接口到虚拟机内
3)开发板的启动模式设置成JTAG启动,开发板上电后,按下PS的复位按键;
4)打开串口软件如SecureCRT或Putty,设置好MPSoc开发板所使用的串口并打开。
做好以上准备工作后,就可以使用JTAG进行下载了。
当然了,使用JTAG下载还是需要借助Petalinux工具的。首先我们设置好Petalinux的工作环境,然后进入第六章Petalinux设计流程实战章节建立的Petalinux工程目录中。由于编译生成的uboot文件不在Petalinux工程范围内,Petalinux无法使用,怎么解决呢?
用软链接就可以了,方法如下:
首先备份Petalinux工程images/linux目录下的u-boot.elf和system.dtb文件,命令如下:
cd images/linux
mv u-boot.elf u-boot.elf.bak
mv system.dtb system.dtb.bak
然后软链接编译生成的u-boot.elf和system.dtb文件,命令如下:
ln -s ~/git.d/u-boot-xlnx/u-boot.elf u-boot.elf
ln -s ~/git.d/u-boot-xlnx/u-boot.dtb system.dtb
结果如下图所示:
图 12.3.5 软链接u-boot.elf和system.dtb
前面我们说过使用SD卡下载比较麻烦,所以使用JTAG下载,但是笔者通过JTAG下载后,发现不能通过uboot启动内核,原因是对于MPSoc器件,petalinux2019.2不支持petalinux-boot命令下uboot启动linux内核,所以本次实验需要先将linux镜像文件放在SD卡中,然后uboot从SD卡启动镜像。接下来将linux镜像文件image.ub复制到SD卡分区1(boot分区)中,复制完成后按照9.6节拷贝根文件系统到SD卡的ext4分区中的命令卸载SD卡,并将SD卡插到开发板上,如下图所示:
图 12.3.6 复制image.ub到sd卡分区1
现在用JTAG下载u-boot文件,命令如下(注意,下载前要先设置petalinux环境变量):
petalinux-boot --jtag --fpga --u-boot
在更高版本的petalinux中,可以使用“petalinux-boot --jtag --fpga --u-boot --kernel”命令通过JTAG下载uboot并启动linux内核,但是petalinux2019.2不支持直接通过JTAG下载uboot并启动linux内核。本次测试,我们通过“petalinux-boot --jtag --fpga --u-boot”命令,先将uboot下载到开发板上,然后进入uboot,通过sd卡启动内核。
上面的命令将下载fpga(system.bit)、pmu firmware、FSBL、uboot和ATF(bl31.elf)。执行结果如下图所示(下载前需要按下开发板的PS复位按键,否则会下载失败):
图 12.3.7 下载u-boot
观察串口接收软件,uboot启动倒计时很短,只有两秒,当出现倒计时的时候,立即按“enter”键进入uboot,如下图所示:
图 12.3.8 进入uboot
进入uboot后,使用“iminfo”命令查询镜像的起始地址为“0x8000000”,然后使用“fatload”文件系统命令将镜像文件image.ub从SD卡传输到内存中地址0x8000000处,最后通过“bootm”命令启动内核镜像,如下图所示:
图 12.3.9 串口软件接收情况
从上图可以看到,除了因为以太网的PHY地址不对导致不能找到以太网设备外,是可以正常启动linux内核的。当然了还有一些其他的小问题,比如只检测到了mmc0,这些问题主要跟设备树有关。至于启动linux内核后出现的问题,就不归属于uboot了,后面的章节会解决。