Xilinx有個工具叫PetaLinux
,它可以一鍵生成uboot、Linux、根文件系統(tǒng)。但是按照慣例我們還是自己敲命令一個個來吧。
Xilinx有個wiki講述如何一步步做Linux from scratch
。有些步驟是多余的,比如編譯設(shè)備樹的工具鏈。鑒于我們的EBAZ4205是塊野生的板子,需要稍微做一些配置。
安裝vivado、SDK時候順便安裝了arm-linux-gnueabihf-
以及其他Xilinx自家的工具鏈,不妨將其export到PATH:
# gccexport PATH=/某某某/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/:$PATH# bootgen etc.export PATH=/某某某/SDK/2017.4/bin:$PATH
所有工作開始之前,還要export ARCH
和CROSS_COMPILE
兩個環(huán)境變量:
export ARCH=armexport CROSS_COMPILE=arm-linux-gnueabihf-
uboot只需要極少量的配置,就基本上works out of the box了?,F(xiàn)在我們先用tftp
來啟動內(nèi)核。各部分的地址如下:
文件名 | 啟動地址 | |
---|---|---|
設(shè)備樹 | zynq-zc702.dtb | 0 |
內(nèi)核 | uImage | 0x8000 |
文件系統(tǒng) | uramdisk.image.gz | 0x01000000 |
從https://github.com/Xilinx/u-boot-xlnx上下載Xilinx家的uboot,當然也可以選擇去下載release版本的。
arch/arm/dts/zynq-zc702.dts的memory
節(jié)點,內(nèi)存大小改為256MB
@@ -21,7 +21,7 @@ memory@0 { device_type = "memory";- reg = <0x0 0x40000000>;+ reg = <0x0 0x10000000>; }; chosen {
直接用zynq_zc702_defconfig
:
make zynq_zc702_defconfig
CONFIG_ENV_IS_IN_SPI_FLASH
,不然啟動時候會卡死在SPI flash初始化部分。這時候就用默認的環(huán)境變量。CONFIG_NAND
、CONFIG_NAND_ZYNQ
,以開啟nand命令。定制環(huán)境變量,改include/configs/zynq-common.h
,主要是來配置啟動參數(shù)。
serverip
set serverip xxx.xxx.xxx.xxxdhcptftpboot 0 zynq-zc702.dtbtftpboot 8000 uImagetftpboot 1000000 uramdisk.image.gzbootm 8000 1000000 0
然后make,生成了u-boot
可執(zhí)行文件。
我們寫一個boot.bif
,引用之前建的helloworld工程中的FSBL
和bitstream
:
the_ROM_image:{ [bootloader]/某某某/fsbl.elf /某某某/ebaz4205_wrapper.bit /某某某/u-boot.elf}
利用vivado安裝的工具bootgen
,通過上述配置文件來生成BOOT.bin
。u-boot
需要重命名為u-boot.elf
,不然bootgen不認為它是ELF文件,就當它是bin文件來處理了。。。
mv u-boot u-boot.elfbootgen -image boot.bif -o i BOOT.bin -w
內(nèi)核很大程度上也是work out of the box了,改改設(shè)備樹就好。
從https://github.com/Xilinx/linux-xlnx上下載Xilinx家的內(nèi)核。目前版本是4.19.0,還是挺新的。
首先還是得將內(nèi)存大小改對:
memory@0 { device_type = "memory";- reg = <0x0 0x40000000>;+ reg = <0x0 0x10000000>; };
因為我們的野生板子外設(shè)很少,必須將不用的外設(shè)disabled
掉,不然引腳配置會打架。
&can0 {- status = "okay";+ status = "disabled";... &i2c0 {- status = "okay";+ status = "disabled"; &qspi { u-boot,dm-pre-reloc;- status = "okay";+ status = "disabled"; &usb0 {- status = "okay";+ status = "disabled";
串口的引腳要改對:
@@ -368,12 +382,12 @@ }; conf-rx {- pins = "MIO49";+ pins = "MIO25"; bias-high-impedance; }; conf-tx {- pins = "MIO48";+ pins = "MIO24"; bias-disable; }; };
網(wǎng)口通過EMIO
引出,因此gem0
的引腳聲明應(yīng)該刪掉,否則會跟串口引腳打架,導致啟動到一半串口沒輸出了。。并且ethernet_phy
節(jié)點的reg
參數(shù)應(yīng)改為0,不然會枚舉不到那個網(wǎng)卡:
&gem0 { status = "okay"; phy-mode = "rgmii-id"; phy-handle = <ðernet_phy>;- pinctrl-names = "default";- pinctrl-0 = <&pinctrl_gem0_default>;- phy-reset-gpio = <&gpio0 11 0>;- phy-reset-active-low;- ethernet_phy: ethernet-phy@7 {- reg = <7>;+ ethernet_phy: ethernet-phy@0 {+ reg = <0>; device_type = "ethernet-phy"; };};
SDIO接口也在fsbl初始化完成了,所以它的引腳聲明也要刪掉:
&sdhci0 { u-boot,dm-pre-reloc; status = "okay";- pinctrl-names = "default";- pinctrl-0 = <&pinctrl_sdhci0_default>; };
為了用nand flash,需要添加nand
節(jié)點。在阿莫論壇有個帖子,62樓列舉了原板子啟動的log,可以看到它有9個分區(qū):
Creating 9 MTD partitions on "pl35x-nand":0x000000000000-0x000000300000 : "nand-fsbl-uboot"0x000000300000-0x000000800000 : "nand-linux"0x000000800000-0x000000820000 : "nand-device-tree"0x000000820000-0x000001220000 : "nand-rootfs"0x000001220000-0x000002220000 : "nand-jffs2"0x000002220000-0x000002a20000 : "nand-bitstream"0x000002a20000-0x000006a20000 : "nand-allrootfs"0x000006a20000-0x000007e00000 : "nand-release"0x000007e00000-0x000008000000 : "nand-reserve"
所以我們這樣設(shè)置nand0
節(jié)點:
&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>; };};
它的引腳配置pinctrl_nand0_default
如下:
pinctrl_nand0_default: nand0-default { mux { groups = "smc0_nand8_grp"; function = "smc0_nand"; }; conf { groups = "smc0_nand8_grp"; bias-pull-up; }; };
groups的名字是在pinctrl-zynq.c第715行找到的。
由于在zynq-7000.dtsi里,nand0
是smcc
的子節(jié)點,所以還要使能smcc
節(jié)點:
&smcc { status = "okay";};
為了避免pinctrl_gpio0_default
跟pinctrl_nand0_default
引腳打架,前者的引腳都應(yīng)該刪掉:
pinctrl_gpio0_default: gpio0-default { mux { function = "gpio0";- groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",- "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",- "gpio0_13_grp", "gpio0_14_grp";+ groups = ""; }; conf {- groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",- "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",- "gpio0_13_grp", "gpio0_14_grp";+ groups = ""; slew-rate = <0>; io-standard = <1>; }; conf-pull-up {- pins = "MIO9", "MIO10", "MIO11", "MIO12", "MIO13", "MIO14";+ pins = ""; bias-pull-up; }; conf-pull-none {- pins = "MIO7", "MIO8";+ pins = ""; bias-disable; }; };
其他節(jié)點該刪的都要刪掉,比如gpio-keys
、leds
、usb_phy0
等。還有一些pinctrl的節(jié)點,看著礙事也不妨刪掉,比如pinctrl_gem0_default
等。。
其實用xilinx_zynq_defconfig
已經(jīng)足夠,不過如果想要更多的功能,比如ZRAM
壓縮內(nèi)存之類的比較騷的設(shè)施,也可以稍微配置一下。。
記得我們uboot會將內(nèi)核放在32K開始的內(nèi)存地址處。然后編譯設(shè)備樹。
make xilinx_zynq_defconfigmake uImage UIMAGE_LOADADDR=0x8000make dtbs
從Build and Modify a Rootfs上下載人家編譯好的busybox
做的文件系統(tǒng)arm_ramdisk.image.gz
,然后將它打包為uboot能識別的格式:
mkimage -A arm -T ramdisk -C gzip -d arm_ramdisk.image.gz uramdisk.image.gz
裝好tftp server,將uImage
、zynq-zc702.dtb
、uramdisk.image.gz
放進去。將BOOT.bin
丟進格式化為fatfs的SD卡的根目錄里面,然后就可以等它啟動了。
## Booting kernel from Legacy Image at 00008000 ... Image Name: Linux-4.19.0-xilinx Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4322424 Bytes = 4.1 MiB Load Address: 00008000 Entry Point: 00008000 Verifying Checksum ... OK## Loading init Ramdisk from Legacy Image at 01000000 ... Image Name: Image Type: ARM Linux RAMDisk Image (gzip compressed) Data Size: 5309954 Bytes = 5.1 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK## Flattened Device Tree blob at 00000000 Booting using the fdt blob at 0x000000 Loading Kernel Image ... OK Loading Ramdisk to 0e5f3000, end 0eb03602 ... OK Loading Device Tree to 0e5ec000, end 0e5f27a6 ... OKStarting kernel ...Booting Linux on physical CPU 0x0Linux version 4.19.0-xilinx (hyq@ict) (gcc version 6.2.1 20161114 (Linaro GCC Snapshot 6.2-2016.11))#19 SMP PREEMPT Wed Apr 24 21:55:25 CST 2019CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d....VFS: Mounted root (ext4 filesystem) on device 1:0.Starting rcS...++ Mounting filesystemmount: mounting /dev/mmcblk0p1 on /mnt failed: No such file or directorymount: mounting /dev/mmcblk0 on /mnt failed: No such file or directory++ Setting up mdev++ Starting telnet daemon++ Starting http daemon++ Starting ftp daemon++ Starting ssh daemonrandom: sshd: uninitialized urandom read (32 bytes read)rcS Completezynq>zynq> zynq> zynq> uname -aLinux (none) 4.19.0-xilinx #19 SMP PREEMPT Wed Apr 24 21:55:25 CST 2019 armv7l GNU/Linuxzynq>