作者: 付漢傑
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編譯,既適應開發人員的工作習慣,也提高了速度。
