In my previous project post, I created an updated hardware design for my ZynqberryZero from scratch in Vivado 2022.1 after discovering that my previous 2019.2 version was too out-dated to support my eInk display for a new project idea. This project post covers how to generate an embedded Linux image using PetaLinux 2022.1 for that hardware design. It will include support for network access via a Micro-USB to Ethernet adapter and base requirements to install Adafruit's CircuitPython on.
Create PetaLinux ProjectSource the PetaLinux tools to the environment and create a new project for the Zynq-7000 architecture with the desired project name.
~$ source /tools/Xilinx/PetaLinux/2022.1/settings.sh
~$ petalinux-create --type project --template zynq --name zynqberryzero_os
~$ cd ./zynqberryzero_os
After successfully creating the PetaLinux project, change directories (cd) into it.
System ConfigurationOnce in the PetaLinux project, import the hardware that was exported from the corresponding Vivado project. Remember that you're just specifying the path to the folder the XSA is in, do not include the XSA file itself in the following command (I don't know when I'll finally stop doing this by accident).
~/zynqberryzero_os$ petalinux-config --get-hw-description ../<path to XSA>
Upon importing the hardware, the system configuration editor will also launch. Since the root filesystem will live on an SD card, navigate to Image Packaging Configuration and change Root filesystem type to EXT4 (SD/eMMC/SATA/USB). I also disabled TFTP boot since I don't plan to use it.
Exit the system configuration editor, choosing to save all changes.
Since the ZynqberryZero can only boot from the QSPI, I stole the u-boot-zynq-scr
configuration files for the BSP recipe from the Trenz 2020.1 demo project instead of manually configuring this by hand in the system configuration editor and u-boot configuration editor.
Copy ./zbzerodemo1/os/petalinux/project-spec/meta-user/recipes-bsp/u-boot/u-boot-zynq-scr
and ./zbzerodemo1/os/petalinux/project-spec/meta-user/recipes-bsp/u-boot/u-boot-zynq-scr.bbappend
to ./zynqberryzero_os/project-spec/meta-user/recipes-bsp/u-boot/
Also copy ./zbzerodemo1/os/petalinux/project-spec/meta-user/recipes-bsp/u-boot/files/devtool-fragment.cfg
to ./zynqberryzero_os/project-spec/meta-user/recipes-bsp/u-boot/files
and update u-boot-xlnx_%.bbappend
accordingly to include it in the build.
The syntax for bitbake has changed slightly from version 2020.1 to 2022.1 so there are a few spots in u-boot-zynq-scr.bbappend
that need to be updated. Namely just removing some underscores in favor of colons for function paths (ie: do_configure_prepend()
is now do_configure:prepend()
).
If you missing any spots, the build will fail but the error output will tell you exactly where the syntax needs to be fixed.
Modify KernelNext the kernel needs to be configured to add support for networking and ultimately what Adafruit's CircuitPython will require. Launch the kernel configuration editor:
~/zynqberryzero_os$ petalinux-config -c kernel
In PetaLinux 2022.1 once a kernel modification has been made, the kernel recipe appears in the meta-user
directory of the project (recipes-kernel
).
My hack to streamline kernel configuration is to only use the kernel configuration editor to enable one module, then type out or copy+paste the rest of the modules I want enabled in the auto-generated configuration file: ./meta-user/recipes-kernel/linux/linux-xlnx/user_xxxxx.cfg
.
This beats tracking down every single module needed in the GUI and bouncing around everywhere trying to get everything enabled for the modules I want to even appear.
See the attached config file (usr_zynqberryzero.cfg
) for the modules necessary for networking and CircuitPython.
Note: the QSPI patch from the Trenz 2020.1 demo project is not needed in 2022.1.
Modify Root FilesystemNext, the root filesystem also needs some additional libraries and packages added. Namely networking tools such as net-tools
and the various Python packages CircuitPython requires.
Launch the root filesystem configuration editor:
~/zynqberryzero_os$ petalinux-config -c rootfs
Another hack in PetaLinux I like to use is to take advantage of the package groups which again saves me from digging through all of the menu options in the configuration editor.
The Python package group and the networking package group cover what’s needed perfectly. I also selected a few extra package groups the included some other tools I commonly use. Here’s the full list of PetaLinux Package Groups I enabled:
packagegroup-petalinux
packagegroup-petalinux-audio
packagegroup-petalinux-lmsensors
packagegroup-petalinux-networking-stack
packagegroup-petalinux-openamp
packagegroup-petalinux-opencv
packagegroup-petalinux-python-modules
packagegroup-petalinux-qt
packagegroup-petalinux-self-hosted
packagegroup-petalinux-utils
packagegroup-petalinux-v4lutils
packagegroup-petalinux-x11
You can highlight each package group then select the help
option to see a list of what libraries they include.
I also stole the i2cpick, rpicam, and startup applications from the Trenz 2020.1 demo project as I saw them as being useful in the future. Only the startup application is necessary however.
Of course since applications were added to the app recipe, update./meta-user/conf/user-rootfsconfig accordingly:
Then enable the applications as desired in the root filesystem configuration editor under apps.
I also enabled package management under Image Features for future use as well to be able to use dnf as a package manager to install things. There is no need to set the package-feed-uris or package-feed-archs variables unless using something external to the default PetaLinux ones.
Since there is a custom design in the programmable logic of the Zynq FPGA, the corresponding device tree nodes need to be added to the PetaLinux project in the ./zynqberryzero_os/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
file.
While I did start with the system-user.dtsi
from the Trenz demo project as a reference, I did have to make some modifications to match the hardware design I created in Vivado in my previous post. See my attached system-user.dtsi
below.
Mainly I discovered that the node for the QSPI flash memory no longer worked in 2022.1 like it did in 2020.x and earlier, this caused the read/write bus width to randomly change, thus stopping the FSBL from working properly upon any reboot after it was initially flashed with the Linux boot binary (BOOT.BIN). Tom Curran explains what's happening in detail here in a great write-up on Element14 if anyone is curious about the details here.
Package BOOT.BIN & WICBuild the PetaLinux project, which will take a little while to run for the first time:
~/zynqberryzero_os$ petalinux-build
Create the boot binary (BOOT.BIN) that will be flashed onto the ZynqberryZero’s QSPI flash:
~/zynqberryzero_os$ petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --fpga ./images/linux/system.bit --u-boot
Package the WIC image for the SD card, specifying the boot script, kernel image, and device tree blob be placed in the FAT32 boot partition; and then the root filesystem be extracted from the rootfs.tar.gz file and place on the EXT4 partition of the SD card:
~/zynqberryzero_os$ petalinux-package --wic --bootfiles "boot.scr image.ub system.dtb" --rootfs-file ./images/linux/rootfs.tar.gz
Use a program like balenaEtcher to flash the WIC onto the SD card, and use Vitis to flash the boot binary onto the ZynqberryZero QSPI flash.
WARNING: the ZynqberryZero needs to have the boot binary for the special Zynq FSBL bare-metal application to put it in JTAG mode flashed onto its QSPI from 2020.x or earlier before attempting to flash the boot binary from the PetaLinux 2022.1 project onto it. Something about the QSPI boot and program flash changed between 2020.x and 2021.x that doesn't allow programming if the Zynq isn't already in JTAG boot mode (see Trenz wiki about it here). I did create a workaround for this issue that I outline the process of here.
Boot ZynqberryZeroWith the QSPI flashed, unplug the ZynqberryZero from the host PC and insert the SD card. Plug the USB Ethernet adapter into the MicroUSB port labeled OTG and connect the Ethernet cable to a router or host PC that can share its internet connection to it.
Open your preferred serial application such as Putty or TeraTerm with a baud rate of 115200 and reconnect the ZynqberryZero to the host PC. The login user is petalinux and default password is root, but it will prompt for the password to be changed after the first login.
Verify the network connection by running a command such as ifconfig
:
See my next project post to the details outlining the installation of CircuitPython and testing out my eInk display!
Comments