1. 程式人生 > 實用技巧 >ZYNQ Linux 移植:包含petalinux移植和手動移植debian9

ZYNQ Linux 移植:包含petalinux移植和手動移植debian9

參考:https://electronut.in/workflow-for-using-linux-on-xilinx-zynq/https://blog.csdn.net/m0_37545528/article/details/90177983?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159826227019725222462909%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=159826227019725222462909&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_blog_v1-1-90177983.pc_v2_rank_blog_v1&utm_term=zynq&spm=1018.2118.3001.4187

問題:1.ZYNQ
環境:虛擬機器ubuntu16.04petalinux2018.3vivado2018.3開發板:小熊貓z7020
前言使用ZYNQ大概率會用到Linux。這裡就對linux移植的整個流程做一個記錄。
移植有兩種方式:(1)使用petalinux工具鏈進行移植。虛擬機器需要裝petalinux,自動化程度相對高。(2)手動移植,需安裝SDK移植環境或者petalinux的環境,兩者貌似是一樣的。實際上,rootfs是可以隨便用哪個的。比如,可以混搭手動移植的uboot\kernel,而使用petalinux的rootfs。或者使用petalinux的image.ub,而使用debian等三方rootfs。看需要使用。手動移植可以更熟悉定製方面的內容,當然更為繁瑣。
  • 建立BSP:
首先我們從建立底層硬體平臺開始,其定義了底層的裝置樹相關內容、PL端功能等。這裡使用了網口0、SD卡、UART1,根據原理圖分配管腳即可,網口和SD卡的管腳使用fast,設定好DDR資訊。(1)配置ZYNQ:(2)正常綜合編譯生成bit匯出BSP到資料夾。(3)開啟SDK檢視一下是否匯入成功。
  • SD卡分割槽:本次移植u-boot、kernel、rootfs都在SD上。
SD卡分割槽:https://blog.csdn.net/lulugay/article/details/83240981分兩個區即可,BOOT分割槽和RootFS分割槽,前面的分割槽用於儲存u-boot和核心和PL端的bit,後一個分割槽用於儲存根檔案系統。(1)在ubuntu中安裝gparted。使用圖形化介面簡化操作,可直接在命令列中開啟。

(2)切換到sd卡,可根據容量確認。右鍵刪除分割槽。新建BOOT分割槽:最起始保留4MB空間,這裡分512M,檔案格式fat32,標籤設定為BOOT。剩下的全部分為RootFS分割槽。至此,分割槽完成。
下述會講述petalinux的移植方式和手動移植的方式。一、petalinux移植對於初學者,自然,petalinux是一種更為簡便的方式,敲幾個命令即可得到控制檯的歡喜,而手動移植的坑還蠻多的。(1)匯出前述bsp到虛擬機器:(2)隨便哪個位置新建個目錄,並把sdk資料夾放入。這裡新建個demo_linux資料夾。(3)source下petalinux的環境(可放在bashrc中自動source,避免手動敲)。路徑根據petalinux的安裝路徑進行選擇。
source /home/kingstacker/petalinux2018.3/settings.sh
(4)新建一個petalinux專案:這裡新建了個demo1_linux工程,路徑下會自動新建demo1_linux資料夾,模板使用zynq,zynq7系列應該都是這個。
petalinux-create -t project -n demo1_linux --template zynq
(5)cd到這個工程下面:
cd demo1_linux/
(6)匯入上層的SDK資料夾內容:會自動彈出配置視窗。
petalinux-config --get-hw-description=/home/kingstacker/demo_linux/project_1.sdk
(7)配置使用哪個串列埠進行列印。這裡我使用的是PS端的串列埠1,波特率115200,跟ZYNQ配置時保持一致即可。在Subsystem AUTO Hardware Settings選項下的Serial Settings設定。(8)設定bootargs,用於列印資訊的串列埠指定,指定核心啟動位置。注意:我這裡使用了自動生成頭,不使用自動的沒得實驗成功。在DTGSetting選項卡下第三行修改如下:鍵入bootargs:我這裡使用了PS端的uart1(在裝置樹中被alias到了serial0),核心要從SD卡的第二個分割槽啟動,分割槽格式為ext4。
console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait
在ImagePackagingConfiguration中設定根檔案系統型別,這裡為SD卡。
切換到save儲存主項配置,然後按兩次ESC退出。
根據需要配置u-boot\kernel\rootfs內容,這裡不配置使用預設,直接執行build即可。
petalinux-config -c u-boot
petalinux-config -c kernel
petalinux-config -c rootfs
(9)編譯工程,打把遊戲回來再看:
petalinux-build
(10)切換到image目錄下的linux目錄,執行語句生成BOOT.BIN檔案。
petalinux-package --boot --format BIN --fsbl zynq_fsbl.elf --fpga system.bit --u-boot
(11)複製BOOT.BIN和image.ub檔案到SD卡的BOOT分割槽。我這裡BOOT路徑如下:
cp BOOT.BIN /media/kingstacker/BOOT/
cp image.ub /media/kingstacker/BOOT/
(12)解壓檔案系統到SD卡的RootFS分割槽。
sudo tar xvf rootfs.tar.gz -C /media/kingstacker/RootFS/
至此,完成了所有內容,把SD卡放到板子上,切換板子啟動模式為SD卡啟動,連線CRT顯示串列埠列印資訊。
其他:QEMU模擬:對於petalinux編譯的系統,其提供了模擬工具,在上板之前就可以知道Uboot和Kernel是否可以啟動。(1)在工程目錄下執行下述打包命令:
petalinux-package --prebuilt
(2)進行第三階段模擬:
petalinux-boot --qemu --prebuilt 3
可以看到在等待檔案系統,則表示成功。也可以單獨模擬uboot、kernel:
petalinux-boot --qemu --u-boot
petalinux-boot --qemu --kernel
還有一些高階用法這裡不表。
二、手動移植linux:
(1)獲取u-boot\kernel、devicetree。
  • 下載xilinx的u-boot、kernel:
git clone https://github.com/Xilinx/u-boot-xlnx.git
git clone https://github.com/Xilinx/linux-xlnx.git
git checkout 檢出想使用的版本,git tag檢視所有可用的版本。u-boot 2018.3貌似沒得zynq_zc702_defconfig這個配置檔案,可檢出到2018.1拷貝一份。確保含有device tree檔案,沒有就要下載並匯入到SDK的倉庫中:
git clone https://github.com/Xilinx/device-tree-xlnx
(2)裝置樹編譯:
  • 工程匯入SDK生成裝置樹:就是新建個裝置樹工程。

  • 裝置樹資訊匯入linux中生成dtb檔案:
匯入bsp資訊:右鍵命令列中執行:首先source下SDK的settings.sh環境,sourcepetalinux的sh檔案也是一樣的:歸集dts檔案到一個檔案中:
cpp -nostdinc -I include -I arch  -undef -x assembler-with-cpp  system-top.dts system-top.dts.preprocessed
編譯裝置樹,生成dtb:
dtc -I dts -O dtb -i . -o devicetree.dtb system-top.dts.preprocessed
可以看到資料夾下生成了dtb檔案:
(3)編譯uboot:2018.3沒得zc702,所以這裡檢出了2018.1的版本。這裡可以使用zc702的defconfig檔案,其在xil_source/u-boot-xlnx/configs路徑下。
CONFIG_ARM=y
CONFIG_SYS_CONFIG_NAME="zynq_zc70x"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x800
CONFIG_IDENT_STRING=" Xilinx Zynq ZC702"
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_EEPROM=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_DFU=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_FPGA_LOADBP=y
CONFIG_CMD_FPGA_LOADFS=y
CONFIG_CMD_FPGA_LOADMK=y
CONFIG_CMD_FPGA_LOADP=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_EMBED=y
#CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_DM_GPIO=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_BAR=y
CONFIG_SF_DUAL_FLASH=y
CONFIG_SPI_FLASH_ISSI=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_REALTEK=y
CONFIG_PHY_XILINX=y
CONFIG_ZYNQ_GEM=y
CONFIG_DEBUG_UART_ZYNQ=y
CONFIG_DEBUG_UART_BASE=0xe0001000
CONFIG_DEBUG_UART_CLOCK=50000000
CONFIG_ZYNQ_SERIAL=y
CONFIG_ZYNQ_QSPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_ULPI_VIEWPORT=y
CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Xilinx"
CONFIG_USB_GADGET_VENDOR_NUM=0x03fd
CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
因為是SD卡啟動則並修改下述:關掉清除中間編譯:
make distclean
使用配置檔案:
make CROSS_COMPILE=arm-linux-gnueabihf- zynq_zc702_defconfig
通過下述指令可在介面中uboot進行進一步修改配置:改defconfig檔案也可以
make CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
工具編譯:
make CROSS_COMPILE=arm-linux-gnueabihf- tools
編譯u-boot:
make CROSS_COMPILE=arm-linux-gnueabihf-

最後把編譯生成的u-boot字尾改成.elf。
(4)生成FSBL檔案併合成BOOT.BIN:
  • 在SDK中先生新建fsbl工程成FSBL,在src的h檔案中新增debug屬性,可以在控制檯中列印FSBL階段的啟動資訊:
#define FSBL_DEBUG_INFO

SDK中合成BOOT.BIN檔案:uboot.elf、fsbl.elf、bit。複製BOOT.BIN到SD卡的BOOT分割槽。上電確認BOOT.BIN是否可以正常啟動。(5)核心編譯:切換到linux-xlnx目錄。注意:錯誤的解決:

解決 "mkimage" command not found - U-Boot images will not be built

sudo apt-get install u-boot-tools
或者#export PATH=${YOUR_UBOOT_DIR}/tools:$PATH //編譯核心如果要生成uImage,則需要用到mkimage工具,該工具在u-boot/tools下有提供或者直接複製mkimage到/bin目錄即可,生成uimage會用到。清除老的編譯檔案:
#make distclean
配置:
#make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_mz7x_defconfig  
根據需要對核心進行圖形化介面的配置:暫時預設就好
#make ARCH=arm menuconfig
編譯工具:
#make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare scripts  
編譯核心生成uimage:
#make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage  
(6)定製檔案系統:
  • 檔案系統:
這裡檔案系統使用debian,也可用別的,無所謂。安裝arm環境和debootstrap:
sudo apt-get install binfmt-support qemu qemu-user-static debootstrap
debian提取:
sudo debootstrap --arch=armhf --foreign stretch rootfs http://cdn.debian.net/debian
拷貝到bin路徑:
cp /usr/bin/qemu-arm-static {{剛剛rootfs目錄}}/usr/bin
在rootfs資料夾的上層執行:
DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot rootfs debootstrap/debootstrap --second-stage
進入rootfs:
chroot rootfs
新增源到list:
echo deb http://ftp.cn.debian.org/debian/ stretch main > /etc/apt/sources.list
更新:
apt-get update
按需安裝相關包:
apt-get install vim sudo net-tools

debian9啟動後網口預設沒有自動掛載,開發者可以指定rc.local(注意給許可權777)檔案中自動執行指令碼,使用指令碼配置網口,指令碼注意給許可權chmod +x xx.sh。而debian9預設不帶rc.local。解決方法:https://www.cnblogs.com/flymeng/p/7901062.html比如我這裡新建/etc/rc.local檔案:放入了sh_boot.sh檔案。
#!/bin/sh -e
#
#rc.local

#sh in there
/home/sh_boot.sh
#sh end 
exit 0
EOF
給許可權:chmod 777 /etc/rc.local在home路徑放入sh檔案,即可。(注意別放在普通使用者資料夾下,否則無法上電就執行了)配置網口0使用,根據需要修改。
echo "Welcome to use,powerd by kingstacker"
echo "config the eth......."

ifconfig eth0 192.168.0.110 netmask 255.255.255.0 up

echo "config finish."
給許可權:chmod 777 /home/sh_boot.sh命令列執行exit退出。
  • 打包rootfs備份:
資料夾壓縮:切換到rootfs路徑,執行:
tar -zcvf debian9_rootfs.tar.gz ./

資料夾解壓到SD卡的rootfs:
tar zxvf debian9_rootfs.tar.gz -C /media/kingstacker/RootFS

debian9rootfs檔案堅果雲分享:
https://www.jianguoyun.com/p/DdhhnukQ15CBCBjvgrcD 
普通使用者登入及密碼:kingstackersu登入密碼:123123

(7)複製相關檔案到SD卡的BOOT分割槽,並新增uEnv.txt檔案:
  • SD卡BOOT分割槽內容如下:bin檔案、裝置樹、txt、核心映象。
uEnv.txt:其指定了核心傳參。表示uart速率115200,使用ttyPS0。根目錄為SD卡的第二個分割槽。
bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait
load_image=fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image}
uenvcmd=echo Copying Linux from SD to RAM... && mmcinfo &&  run load_image && bootm ${kernel_load_address} - ${devicetree_load_address}

而SD卡的RootFS分割槽儲存了根檔案系統:
至此,移植結束,插到板子上,享受勞動成果吧。
以上。