整合Xilinx PetaLinux工程编译和Open Source U- Boot/Linux编译
作者: 付汉杰
1. 测试环境
- Ubuntu 16.04
- PetaLinux 2019.1
- PetaLinux 2019.1 ZCU106 BSP
- ZCU106
2. PetaLinux介绍
PetaLinux是Xilinx基于Yocto推出的Linux开发工具。Yocto是业界主流的Linux发行版的构建工具,它不仅可以从源代码编译Linux 内核,还可以编译Linux发行版必须的数以千计的的应用程序,功能非常强大。Yocto的出现,大幅度降低了构建嵌入式Linux发行版的难度。
万物总有两面性。虽然PetaLinux/Yocto可以一键编译出一个自定义的嵌入式Linux发行版,但是编译整个文件系统很耗费时间。完整的一次PetaLinux/Yocto编译,可能需要从网络下载上GB的文件,可能需要几个小时。即使只更改一行代码,也需要数分钟时间。PetaLinux/Yocto的编译流程,也和很多开发人员原来的基于make的工作方法不一样,它会分析文件系统里所有应用程序的配置文件,执行下载、配置、编译、打包等过程。
如果在调试单板时,仅仅改动一行代码,也需要执行这些操作,显得冗余,也影响开发效率。
为了适应开发人员的工作习惯,也为了提高速度,可以整合PetaLinux工程编译和OpenSource U-Boot/Linux编译。
3. PetaLinux的安装
对于PetaLinux的安装,请参考Xilinx文档, UG1144 PetaLinux Tools Reference Guide, 和 一键离线安装PetaLinux依赖包
4. 提高PetaLinux/Yocto的编译速度 4.1. 下载SState cache
在Xilinx网站下载sstate cache,2019.1版的大小时32.84 GB。下载前,需要注册Xilinx网站的帐号。
登录后,文件从类似于https://www.xilinx.com/member/forms/download/xef.html?filename=sstate-rel-v2019.1.tar.gz的地址下载。
下载后,解压到本地,可以看到类似下面的目录结构。
$ ls aarch64 arm downloads mb-full mb-lite versal $ cd aarch64/ aarch64$ ls 00 07 0e 15 1c 23 2a 31 38 3f 46 4d 54 5b 62 69 70 77 7e 85 8c 93 9a a1 a8 af b6 bd c4 cb d2 d9 e0 e7 ee f5 fc 01 08 0f 16 1d 24 2b 32 39 40 47 4e 55 5c 63 6a 71 78 7f 86 8d 94 9b a2 a9 b0 b7 be c5 cc d3 da e1 e8 ef f6 fd 02 09 10 17 1e 25 2c 33 3a 41 48 4f 56 5d 64 6b 72 79 80 87 8e 95 9c a3 aa b1 b8 bf c6 cd d4 db e2 e9 f0 f7 fe 03 0a 11 18 1f 26 2d 34 3b 42 49 50 57 5e 65 6c 73 7a 81 88 8f 96 9d a4 ab b2 b9 c0 c7 ce d5 dc e3 ea f1 f8 ff 04 0b 12 19 20 27 2e 35 3c 43 4a 51 58 5f 66 6d 74 7b 82 89 90 97 9e a5 ac b3 ba c1 c8 cf d6 dd e4 eb f2 f9 universal 05 0c 13 1a 21 28 2f 36 3d 44 4b 52 59 60 67 6e 75 7c 83 8a 91 98 9f a6 ad b4 bb c2 c9 d0 d7 de e5 ec f3 fa universal-4.8 06 0d 14 1b 22 29 30 37 3e 45 4c 53 5a 61 68 6f 76 7d 84 8b 92 99 a0 a7 ae b5 bc c3 ca d1 d8 df e6 ed f4 fb
4.2. 设置SState cache
在PetaLinux工程目录下执行命令petalinux-config,在菜单Yocto Settings->Local sstate feeds settings->local sstate feeds url设置本地SState cache的目录。
对于ZynqMP,使用aarch64,比如/opt/Xilinx/peta/sstate-rel-v2019.1/aarch64。对于Zynq-7000,使用arm,比如/opt/Xilinx/peta/sstate-rel-v2019.1/arm。设置后,文件project-spec/configs/config会包含指定的目录,比如下行:
CONFIG_YOCTO_LOCAL_SSTATE_FEEDS_URL="/opt/Xilinx/peta/sstate-rel-v2019.1/aarch64/"
对于sstate的使用,可以参考Xilinx下载网站嵌入式工具下载区的README for state-cache。
4.3. 利用离线下载文件
SState文件包里,还有很多常用软件的压缩包。
hankf@xszgs4:/opt/Xilinx/peta/2019.1.sstate.downloads$ ls acl-2.2.52.src.tar.gz lame-3.100.tar.gz acpica-unix2-20180508.tar.gz less-530.tar.gz adwaita-icon-theme-3.28.0.tar.xz libarchive-3.3.3.tar.gz alsa-lib-1.1.6.tar.bz2 libassuan-2.5.1.tar.bz2 alsa-plugins-1.1.6.tar.bz2 libcap-2.25.tar.xz alsa-tools-1.1.6.tar.bz2 libcroco-0.6.12.tar.xz alsa-utils-1.1.6.tar.bz2 libdaemon-0.14.tar.gz ... ...
在project-spec/meta-user/conf/petalinuxbsp.conf里,添加如下内容,就可以重用这些文件。编译过程需要的件,如果已经在其中,就不会再去网络下载,而是直接创建连接到本地文件。
PREMIRRORS_prepend = " \ git://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ ftp://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ http://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ https://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ "
4.4. 重用下载文件
PetaLinux在编译过程中下载所需要的文件,编译结束后,目录build/downloads/下含有很多下载的文件。
$ ls build/downloads/*.xz build/downloads/atk-2.28.1.tar.xz build/downloads/grep-3.1.tar.xz build/downloads/netbase_5.4.tar.xz build/downloads/at-spi2-atk-2.26.2.tar.xz build/downloads/gst-rtsp-server-1.14.4.tar.xz build/downloads/ofono-1.24.tar.xz build/downloads/at-spi2-core-2.28.0.tar.xz build/downloads/gtk+-2.24.32.tar.xz build/downloads/pango-1.42.4.tar.xz build/downloads/autoconf-archive-2018.03.13.tar.xz build/downloads/gtk+-3.22.30.tar.xz build/downloads/pciutils-3.6.2.tar.xz build/downloads/bash-completion-2.8.tar.xz build/downloads/gtk-doc-1.29.tar.xz build/downloads/pcmanfm-1.3.0.tar.xz ... ... $ ls build/downloads/*.bz2 build/downloads/alsa-lib-1.1.6.tar.bz2 build/downloads/libassuan-2.5.1.tar.bz2 build/downloads/pcre-8.42.tar.bz2 build/downloads/alsa-plugins-1.1.6.tar.bz2 build/downloads/libgpg-error-1.32.tar.bz2 build/downloads/pixman-0.34.0.tar.bz2 build/downloads/alsa-tools-1.1.6.tar.bz2 build/downloads/libICE-1.0.9.tar.bz2 build/downloads/sysvinit-2.88dsf.tar.bz2 build/downloads/busybox-1.29.2.tar.bz2 build/downloads/libmnl-1.0.4.tar.bz2 build/downloads/xcb-proto-1.13.tar.bz2 ... ...
建议把这些文件拷贝到一个工程外的本地目录,比如/opt/Xilinx/peta/downloads/。然后在project-spec/meta-user/conf/petalinuxbsp.conf里,添加如下内容,就可以重用这些文件。
PREMIRRORS_prepend = " \ git://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ ftp://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ http://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ https://.*/.* file:///opt/Xilinx/peta/2019.1.sstate.downloads/ \n \ git://.*/.* file:///opt/Xilinx/peta/downloads/ \n \ ftp://.*/.* file:///opt/Xilinx/peta/downloads/ \n \ http://.*/.* file:///opt/Xilinx/peta/downloads/ \n \ https://.*/.* file:///opt/Xilinx/peta/downloads/ \n \ "
后续编译时,downloads目录下的大部分文件都是链接。这时候,检查新下载的文件,就很困难。可以使用命令“ls -l | grep -v ">" | grep -v done”排除链接和后缀为done的标志文件,从而只显示新下载的文件。建议也把这些新下载的文件拷贝到上述本地目录,方便以后编译。
hankf@xszgs4:/proj/hankf/zcu106/v191/zcu106-2019.1-bsp/build/downloads$ ls -l total 3972 lrwxrwxrwx 1 hankf hankf 72 Oct 15 15:32 acl-2.2.52.src.tar.gz -> /xilinxtool/peta/2019.1/components/yocto/downloads/acl-2.2.52.src.tar.gz -rw-rw-r-- 1 hankf hankf 141 Oct 15 15:32 acl-2.2.52.src.tar.gz.done lrwxrwxrwx 1 hankf hankf 73 Oct 15 15:32 alsa-lib-1.1.6.tar.bz2 -> /xilinxtool/peta/2019.1/components/yocto/downloads/alsa-lib-1.1.6.tar.bz2 hankf@xszgs4:/proj/hankf/zcu106/v191/zcu106-2019.1-bsp/build/downloads$ ls -l | grep -v ">" | grep -v done total 3972 drwxrwxr-x 62 hankf hankf 12288 Oct 15 16:11 git2 -rw-rw-r-- 1 hankf hankf 2515756 Oct 15 16:11 git2_github.com.xilinx.gst-omx.git.tar.gz ... ...
4.5. 离线编译
如果确信所有软件包都已经在本地,可以去掉网络连接,执行离线编译,会提高编译速度。
在菜单Yocto Settings里,去掉“Enable Network sstate feeds”,选择“Enable BB NO NETWORK”。
5. Open Source Linux和UBoot 5.1. 保留Linux和UBoot源代码
缺省情况下,PetaLinux在编译完成后会删除源代码,以节省硬盘空间。在project-spec/meta-user/conf/petalinuxbsp.conf里,添加如下内容,可以保留Linux和UBoot源代码。
RM_WORK_EXCLUDE += "linux-xlnx" RM_WORK_EXCLUDE += "u-boot-xlnx"
5.2. 取得Linux源代码
如果为Linux添加了上述RM_WORK_EXCLUDE字段,PetaLinux工程在编译后,在build目录下的某一级子目录kernel-source,含有所有Linux源代码。对于PetaLinux 2019.1的ZCU106 BSP工程,Linux源代码在目录 ./build/tmp/work-shared/zcu106-zynqmp/kernel-source/。可以复制这个目录里的Linux源代码,用来使用open source流程编译。
PetaLinux工程在编译后,在build目录下的某一级子目录kernel-build-artifacts保存了Linux的配置文件.config. 对于PetaLinux 2019.1的ZCU106 BSP工程,Linux的配置文件.config在./build/tmp/work-shared/zcu106-zynqmp/kernel-build-artifacts/。
为了方便使用,可以把文件.confi复制到Linux源代码的子目录arch/arm/configs/下,重命名为xilinx_peta_defconfig。这样使用make xilinx_peta_defconfig,可以创建PetaLinux使用的Linux配置。
生成image.ub,需要一个后缀名为its的配置文件,来指定使用的设备树文件、根文件系统文件、内核文件。its文件的相关信息,请参考蜗窝科技 u-boot FIT image介绍。在PetaLinux 2018.2/2018.3里,images/linux/下有文件rootfs.its。但是在PetaLinux 2019.1里,已经没有这个文件。在build目录下的文件fit-image-petalinux-user-image.its,也可以用于生成image.ub。对于PetaLinux 2019.1的ZCU106 BSP工程,它在目录build/tmp/work/zcu106_zynqmp-xilinx-linux/linux-xlnx/4.19-xilinx-v2019.1+gitAUTOINC+9811303824-r0/linux-zcu106_zynqmp-standard-build/下。
fit-image-petalinux-user-image.its使用了build下的层次很深的子目录来指定文件。为了方便,可以修改为使用images/linux下的文件。PetaLinux工程的目录"images/linux/"里,含有创建image.ub的devicetree、rootfs文件等。
5.3. 取得UBoot源代码
如果为UBoot添加了上述RM_WORK_EXCLUDE字段,PetaLinux工程在编译后,在build目录下的某一级子目录u-boot-xlnx里的子目录git,含有所有UBoot源代码。对于PetaLinux 2019.1的ZCU106 BSP工程,UBoot源代码在目录 ./build/tmp/work/zcu106_zynqmp-xilinx-linux/u-boot-xlnx/v2019.01-xilinx-v2019.1+gitAUTOINC+d895ac5e94-r0/git/。如果使用了外部UBoot源代码编译,则没有这个源代码。可以复制前面提到的UBoot源代码,用来使用open source流程编译。
值得注意的是,从PetaLinux工程里得到的UBoot源代码的include/configs/platform-auto.h文件里的宏定义里的连接符后有空格,导致编译时编译器会产生大量警告。建议修改platform-auto.h,消除编译器警告。下面是修改之前的宏定义的一部分。
"nc=setenv stdout nc;setenv stdin nc;\0" \ "ethaddr=00:0a:35:00:22:01\0" \
PetaLinux工程在编译后,在build目录下的某一级子目录u-boot-xlnx里的子目录build下,保存了Linux的配置文件.config. 对于PetaLinux 2019.1的ZCU106 BSP工程,UBoot的配置文件.config在./build/tmp/work/zcu106_zynqmp-xilinx-linux/u-boot-xlnx/v2019.01-xilinx-v2019.1+gitAUTOINC+d895ac5e94-r0/build/.config。
为了方便使用,可以把文件.confi复制到UBoot源代码的子目录configs下,重命名为xilinx_peta_defconfig。这样使用make xilinx_peta_defconfig,可以创建PetaLinux使用的UBoot配置。
PetaLinux工程生成boot.bin时,会在build目录下生成文件bootgen.bif。编译UBoot后,需要创建boot.bin,也需要bootgen.bif,所以把bootgen.bif一起复制到UBoot源代码目录。bootgen.bif里用的是临时目录,最好改成
PetaLinux工程的目录"images/linux/". PetaLinux工程的目录"images/linux/"里,含有创建boot.bin的pmu, fsbl, ATF的ELF文件。
5.4. Open Source 编译Linux
取得Linux源代码和配置后,可以在其中执行make,编译Linux。注意,编译前请导入PetaLinux环境变量,设置和导出ARCH为arm或者arm64;设置和导出CROSS_COMPILE,比如aarch64-linux-gnu-。编译后得到vmlinux,还需要用下列命令,把它打包成image.ub。
aarch64-linux-gnu-objcopy -O binary -R .note -R .comment -S vmlinux linux.bin gzip -9 linux.bin mv -f linux.bin.gz linux.bin mkimage -f fit-image-petalinux-user-image.its image.ub
5.5. Open Source编译Linux时间
更改Xlnx_vcu.c, Xlnx_vcu_clk.c, Xlnx_vcu_core.c, 在它们的开始增加DEBUG宏定义,并增加两个printk打印后,使用petalinux-build编译,耗时337秒。同样更改,使用外部Linux源代码编译,并创建image.ub,只耗时8秒钟。
5.6. Open Source编译UBoot
取得UBoot源代码和配置后,可以在其中编译UBoot,得到u-boot.elf。然后再使用下列命令创建boot.bin。
bootgen -arch zynqmp -image bootgen.bif -o BOOT.BIN -w on
5.7. Open Source编译UBoot时间
在PetaLinux里,编译UBoot,并创建boot.bin,总共耗时84秒钟。
在外部UBoot源代码里,从头编译UBoot,并创建boot.bin,总共耗时26秒钟。
所以从外部源代码里编译UBoot,速度快两倍多。
6. 总结
通过整合PetaLinux工程编译和Open Source U-Boot/Linux编译,既适应开发人员的工作习惯,也提高了速度。