Posted on 30 Apr 2019 By Noah Hütter
In this post I will show you how to compile and install a vanilla Linux kernel and root file system on Zynq SoC.
Disclaimer: This code is largely copied from https://github.com/pavel-demin/red-pitaya-notes, licensed under MIT license.
DO NOT WORK ON A SHARED FOLDER INSIDE VIRTUALBOX It will get messy, because the Linux kernel build uses a case sensitive file system, which Mac does not provide.
zynq-sandbox repository from github if you have not done so already.
git clone https://github.com/noah95/zynq-sandbox
sudo ln -s /usr/bin/make /usr/bin/gmake
Install some tools:
sudo apt install curl u-boot-tools libncurses-dev
Change to the Linux directory.
For educational build purposes, the Makefile was extended to build each component seperately. This guide will go through all components and briefly explain what they are needed for.
This generates the source code and binary for the first level bootloader that is executed after power on. After project creation, the fsbl is compiled and the binary written.
rm -r build/*.fsbl make fsbl
The devicetree files from Xilinx are downloaded and a device tree project created from the hardware definition files.
From these two sources, a set of
dts (device tree sources) files are generated.
Finally the makefile applies a patch to some output files.
The patch file is generates by this command:
diff -rupN pcw.dtsi pcw.dtsi.new > devicetree.patch rm -r build/*.tree make dts
Now it is time to pull a vanilla Linux kernel, uncompress the sources, apply some patches, copy some config and finally build the kernel. Issue the following command and go for a walk:
rm -r build/linux* make uimage
or if the sources are already downloaded and you don’t want to clean before build:
make -C build/linux-4.14 ARCH=arm xilinx_zynq_defconfig make -C build/linux-4.14 ARCH=arm CFLAGS="-O2 -march=armv7-a \ -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard" \ -j 4 \ CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage modules
The bootloader is build from source pulled from Xilinxed repositoriers. Before build, some config files are copied and patches applied.
rm -r build/u-boot* make uboot
Using the device tree sources generated previously, the devicetree compiler is used to generate the devicetree blob.
rm -r build/devicetree* make dtb
Now the three binaries can be tied to a single binary image.
rm -r build/boot.bin make bootbin
For u-boot to know what linux version to load we have to generate a uEnv.txt file. This is done by running the following command:
rm -r build/uEnv.txt make uenv
Create two partitions on a SD-Card:
Copy the following files on the boot partition:
Connect a serial console and power up the board. Hit a key to interrupt u-boot automatic boot process. To check if the uImage and devicetree are correct issue the following commands:
mmcinfo fatload mmc 0 0x2080000 uImage fatload mmc 0 0x2000000 devicetree.dtb iminfo 0x2000000 iminfo 0x2080000 setenv bootargs console=ttyPS0,115200 root=/dev/mmcblk0p2 ro rootfstype=ext4 earlyprintk rootwait bootm 0x2080000 - 0x2000000
At this point the kernel should start but fail with a kernel panic because no
init was found.
For that we next generate the rootfs.
First we try the smallest rootf available: Busybox. To download, untar and build, run:
To modify busybox and build manually:
cd build/busybox-* make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig make -j4 ARCH=arm INSTALL_PATH=build/ install
Now copy the installed busybox and some install scripts to the root partition of the SD-card.
We should now be able bring up the network!
ifconfig eth0 up udhcpc -i eth0 -p /var/run/dhcpClient-eth0.pid ifconfig eth0 192.168.0.87 netmask 255.255.255.0 route add default gw 192.168.0.1 ping 126.96.36.199