上一篇文章介绍了EBAZ4205如何裸机固化,从NAND启动,并生成了.bit和fsbl.elf文件。本文记录如何生成u-boot & Linux。注意:在这之前需要移动电阻将zynq改为从SD卡启动。
使用vivado/Xilinx SDK生成.bit和fsbl.elf
上一篇文章生成的.bit和fsbl.elf并没有使用到所有的硬件。重新配置ZYNQ后产生FPGA下载文件:.bit和first stage bootloader:fsbl.elf,留着备用。除此之外还会产生 .hdf(.xsa)硬件描述文件。.hdf文件主要用于给petalinux自动生成镜像,本文不使用petalinux的全自动镜像生成功能,而是下载u-boot和linux源码手动编译。
在ubuntu16.04环境编译 u-boot & Linux
-
ubuntu必须是16.04版本,本文使用ubuntu-16.04.4-desktop-amd64.iso
-
安装petalinux依赖
sudo apt-get install tofrodos iproute2 gawk gcc g++ git make net-tools libncurses5-dev \ tftpd zlib1g:i386 libssl-dev flex bison libselinux1 gnupg wget diffstat chrpath socat \ xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential \ libsdl1.2-dev libglib2.0-dev screen pax gzip automake
-
在Xilinx官网下载 petalinux-v2018.3-final-installer.run 。这里统一采用v2018.3版本(petalinux、u-boot-xlnx、linux-xlnx),不同版本不要交叉使用。v2019.1之后的版本不带交叉编译器,需要安装VIVADO。
#安装petalinux到petalinux-v2018.3目录 ./petalinux-v2018.3-final-installer.run ./petalinux-v2018.3
-
下载 xilinx uboot https://github.com/Xilinx/u-boot-xlnx/archive/refs/tags/xilinx-v2018.3.zip
下载 xilinx linux内核 https://github.com/Xilinx/linux-xlnx/archive/refs/tags/xilinx-v2018.3.zip
解压到当前目录,先进入u-boot-xlnx-xilinx-v2018.3目录:
touch run.sh chmod a+x run.sh vi run.sh
添加以下脚本:
#!/bin/bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_ebaz4205_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8 mv u-boot u-boot.elf echo the_ROM_image: \ { \ [bootloader]./fsbl.elf \ ./top_pl.bit \ ./u-boot.elf \ } > boot.bif bootgen -image boot.bif -o i BOOT.bin -w
-
增加ebaz4205配置文件
u-boot支持设备树。添加设备树 zynq-ebaz4205.dts到 ./arch/arm/dts/: 。注意:最新版本的Linux内核已经添加了EBAZ4205的设备树文件,但本次采用的v2018.3版本会出现zynq-7000.dtsi兼容问题遂不采用。文件内容:
// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2011 - 2015 Xilinx * Copyright (C) 2012 National Instruments Corp. */ /dts-v1/; #include "zynq-7000.dtsi" // /include/ "zynq-7000.dtsi" / { model = "Ebang EBAZ4205"; compatible = "ebang,ebaz4205", "xlnx,zynq-7000"; aliases { ethernet0 = &gem0; serial0 = &uart1; mmc0 = &sdhci0; }; memory@0 { device_type = "memory"; reg = <0x0 0x10000000>; }; chosen { bootargs = ""; stdout-path = "serial0:115200n8"; }; gpio-keys { compatible = "gpio-keys"; autorepeat; s2 { label = "s2"; gpios = <&gpio0 20 1>; linux,code = <102>; wakeup-source; autorepeat; }; s3 { label = "s3"; gpios = <&gpio0 32 1>; linux,code = <116>; wakeup-source; autorepeat; }; }; }; &clkc { ps-clk-frequency = <33333333>; }; &gem0 { status = "okay"; phy-mode = "mii"; phy-handle = <&phy>; /* PHY clock */ assigned-clocks = <&clkc 18>; assigned-clock-rates = <25000000>; phy: ethernet-phy@0 { reg = <0>; }; }; &smcc { status = "okay"; }; &nand0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand0_default>; partition@0 { label = "nand-fsbl-uboot"; reg = <0x0 0x300000>; }; partition@1 { label = "nand-linux"; reg = <0x300000 0x500000>; }; partition@2 { label = "nand-device-tree"; reg = <0x800000 0x20000>; }; partition@3 { label = "nand-rootfs"; reg = <0x820000 0xa00000>; }; partition@4 { label = "nand-jffs2"; reg = <0x1220000 0x1000000>; }; partition@5 { label = "nand-bitstream"; reg = <0x2220000 0x800000>; }; partition@6 { label = "nand-allrootfs"; reg = <0x2a20000 0x4000000>; }; partition@7 { label = "nand-release"; reg = <0x6a20000 0x13e0000>; }; partition@8 { label = "nand-reserve"; reg = <0x7e00000 0x200000>; }; }; &pinctrl0 { pinctrl_nand0_default: nand0-default { mux { groups = "smc0_nand8_grp"; function = "smc0_nand"; }; conf { groups = "smc0_nand8_grp"; bias-pull-up; }; }; pinctrl_uart1_default: uart1-default { mux { groups = "uart1_4_grp"; function = "uart1"; }; conf { groups = "uart1_4_grp"; slew-rate = <0>; io-standard = <3>; }; }; }; &sdhci0 { u-boot,dm-pre-reloc; status = "okay"; }; &uart1 { u-boot,dm-pre-reloc; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1_default>; };
-
参考zynq_zc702_defconfig 添加 zynq_ebaz4205_defconfig
cp configs/zynq_zc702_defconfig configs/zynq_ebaz4205_defconfig gedit zynq_ebaz4205_defconfig
删除:
CONFIG_ENV_IS_IN_SPI_FLASH=y.
修改:
CONFIG_SYS_CONFIG_NAME=“zynq_ebaz4205”
CONFIG_IDENT_STRING=" Xilinx Zynq EBAZ4205"
CONFIG_DEFAULT_DEVICE_TREE=“zynq-ebaz4205”
CONFIG_DEBUG_UART_BASE=0xe0001000
增加:
CONFIG_NAND=y
CONFIG_NAND_ZYNQ=y
CONFIG_BOOTDELAY=3
CONFIG_DEFAULT_DEVICE_TREE对应之前新增的设备树名,CONFIG_DEBUG_UART_BASE=0xe0001000说明使用uart1(个人猜测fsbl对fpga配置完成后,uart1 ip就连上了特定的mio/emio,只要告诉uboot,使用uart1的地址而不是uart0)
-
增加头文件
cp include/configs/zynq_zc70x.h include/configs/zynq_ebaz4205.h
增加: #define CONFIG_CPU_FREQ_HZ 666666667
-
gedit arch/arm/mach-zynq/Kconfig 改动点如下:
config SYS_CONFIG_NAME string "Board configuration name" default "zynq_ebaz4205"
-
petalinux工具需要使用bash。
sudo dpkg-reconfigure dash
出现对话框选择no
-
把之前.bit和.elf文件复制到当前目录,名字改为top_pl.bit fsbl.bit
# 设置petalinux编译器环境变量 source ../petalinux-v2018.3/settings.sh ./run.sh
产生BOOT.bin和devicetree.dtb
-
进入linux-xlnx-xilinx-v2018.3目录执行
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8 cp ./arch/arm/zImage ./ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage cp ./arch/arm/uImage ./
产生./arch/arm/zImage
产生./arch/arm/uImage
-
新建 uEnv.txt 定制启动命令
bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait uenvcmd=run linaro_sdboot linaro_sdboot=echo Run uEnv.txt copying Linux from SD to RAM... && \ fatload mmc 0 0x0 ${devicetree_image} && \ fatload mmc 0 0x8000 ${kernel_image} && \ if fatload mmc 0 0x1000000 ${ramdisk_image}; \ then bootm 0x8000 0x1000000 0x0; \ else bootm 0x8000 - 0x0; fi
-
将以下文件放入fat32分区的SD卡就可以启动了,uboot默认识别devicetree.dtb、uImage、uEnv.txt文件名
BOOT.bin devicetree.dtb uImage uEnv.txt
-
进入Linux后会报根文件系统挂载错误。下载一个根文件系统解压到SD卡的ext4分区就可以启动了。
linaro-precise-ubuntu-desktop-20120723-305.tar.gz