Minimalist Linux distribution¶
Goal¶
- In this tutorial you will:
create Linux distribution using Yocto (along with support firmware) based on Vivado project created earlier
boot Linux on Leopard DPU through EGSE Host
A bit of background¶
Running Linux on device like Leopard DPU requires set of artifacts
Boot firmware (in particular first stage bootloader and U-Boot)
Linux kernel
Device tree
Root filesystem
Yocto can build these items automatically. Developers construct project using Yocto from layers coming from Yocto project itself, hardware manufactures and their own. Each layer contributes series of recipes that are describing how to build particular components of Linux distribution. BitBake tool manages all dependencies between recipes and hides build complexity.
After building all required artifacts you can use Leopard DPU boot capabilities to load boot firmware into persistent memory and load Linux kernel and root filesystem from network.
Prerequisites¶
.xsafile with platform configuration from Create minimalist Vivado projectMachine with Linux edition supported by Yocto (https://docs.yoctoproject.org/4.3/ref-manual/system-requirements.html#supported-linux-distributions)
Tools installed on machine:
libtinfo5(required by Xilinx layers)Yocto requirements (https://docs.yoctoproject.org/4.3/ref-manual/system-requirements.html#required-packages-for-the-build-host)
At least 120GB free space for Yocto build
Provided outputs¶
Following files (Tutorial files) are associated with this tutorial:
Leopard/Zero-to-hero/02 Minimalist Linux distribution/boot-common.bin- Boot firmware for LeopardLeopard/Zero-to-hero/02 Minimalist Linux distribution/nominal-image-leopard-dpu.rootfs.cpio.gz.u-boot- Root filesystem for LeopardLeopard/Zero-to-hero/02 Minimalist Linux distribution/Image- Linux kernelLeopard/Zero-to-hero/02 Minimalist Linux distribution/system.dtb- Device tree
Use these files if you want to skip building Yocto distribution by yourself.
Create project Yocto¶
Create new directory for Yocto project and navigate to it.
machine:~$ mkdir ~/leopard-linux-1 machine:~$ cd ~/leopard-linux-1 machine:~/leopard-linux-1$Clone Poky layer from Yocto project
machine:~/leopard-linux-1$ git clone -b nanbield https://git.yoctoproject.org/poky sources/pokyCreate new build configuration
machine:~/leopard-linux-1$ source sources/poky/oe-init-build-env ./build You had no conf/local.conf file. This configuration file has therefore been created for you from ~/leopard-linux-1/sources/poky/meta-poky/conf/templates/default/local.conf.sample You may wish to edit it to, for example, select a different MACHINE (target hardware). You had no conf/bblayers.conf file. This configuration file has therefore been created for you from ~/leopard-linux-1/sources/poky/meta-poky/conf/templates/default/bblayers.conf.sample To add additional metadata layers into your configuration please add entries to conf/bblayers.conf. The Yocto Project has extensive documentation about OE including a reference manual which can be found at: https://docs.yoctoproject.org For more information about OpenEmbedded see the website: https://www.openembedded.org/ ### Shell environment set up for builds. ### You can now run 'bitbake <target>' Common targets are: core-image-minimal core-image-full-cmdline core-image-sato core-image-weston meta-toolchain meta-ide-support You can also run generated qemu images with a command like 'runqemu qemux86-64'. Other commonly useful commands are: - 'devtool' and 'recipetool' handle common recipe tasks - 'bitbake-layers' handles common layer tasks - 'oe-pkgdata-util' handles common target package tasks machine:~/leopard-linux-1/build$
Add layers Yocto¶
Clone Xilinx layers:
machine:~/leopard-linux-1/build$ git clone -b nanbield https://github.com/Xilinx/meta-xilinx.git ../sources/meta-xilinx machine:~/leopard-linux-1/build$ git clone -b nanbield https://github.com/Xilinx/meta-xilinx-tools.git ../sources/meta-xilinx-tools machine:~/leopard-linux-1/build$ git clone -b nanbield https://git.openembedded.org/meta-openembedded/ ../sources/meta-openembeddedAdd set of required layers from Xilinx repositories:
machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx/meta-xilinx-core machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx/meta-xilinx-bsp machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx/meta-xilinx-standalone machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx-tools machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-openembedded/meta-oe/ machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-openembedded/meta-networking/Note
After adding Xilinx layers, BitBake might report warning
The ZynqMP pmu-rom is not enabled (…) To enable this you must add ‘xilinx’ to the LICENSE_FLAGS_ACCEPTED to indicate you accept the software license.
This is for informational purposes only and you can ignore it.
Clone KP Labs layers
machine:~/leopard-linux-1/build$ git clone -b nanbield https://github.com/kplabs-pl/meta-kp-classes.git ../sources/meta-kp-classes machine:~/leopard-linux-1/build$ git clone -b nanbield https://github.com/kplabs-pl/meta-kp-leopard.git ../sources/meta-kp-leopardAdd set of required layers from KP Labs repositories:
machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-kp-classes/ machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-kp-leopard
Create layer for customizations Yocto¶
Create empty layer
machine:~/leopard-linux-1/build$ bitbake-layers create-layer ../sources/meta-localAdd newly created layer to project
machine:~/leopard-linux-1/build$ bitbake-layers add-layer ../sources/meta-localVerify set of layers enabled in project by opening
~/leopard-linux-1/build/conf/bblayers.confand checking its contents:# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf # changes incompatibly POKY_BBLAYERS_CONF_VERSION = "2" BBPATH = "${TOPDIR}" BBFILES ?= "" BBLAYERS ?= " \ ~/leopard-linux-1/sources/poky/meta \ ~/leopard-linux-1/sources/poky/meta-poky \ ~/leopard-linux-1/sources/poky/meta-yocto-bsp \ ~/leopard-linux-1/sources/meta-xilinx/meta-xilinx-core \ ~/leopard-linux-1/sources/meta-xilinx/meta-xilinx-bsp \ ~/leopard-linux-1/sources/meta-xilinx/meta-xilinx-standalone \ ~/leopard-linux-1/sources/meta-xilinx-tools \ ~/leopard-linux-1/sources/meta-openembedded/meta-oe \ ~/leopard-linux-1/sources/meta-openembedded/meta-networking \ ~/leopard-linux-1/sources/meta-kp-classes \ ~/leopard-linux-1/sources/meta-kp-leopard \ ~/leopard-linux-1/sources/meta-local \ "
Configure project Yocto¶
Edit
~/leopard-linux-1/build/conf/local.confand add following lines at the beginning:MACHINE = "leopard-dpu" DISTRO = "kplabs-dpu" INHERIT += "rm_work" PROJECT_NAME = "leopard-dpu-minimal-linux"Create recipe append to set XSA file
machine:~/leopard-linux-1/build$ recipetool newappend --wildcard-version ../sources/meta-local/ external-hdfCreate directory
~/leopard-linux-1/sources/meta-local/recipes-bsp/hdf/external-hdfand copyminimal-leopard.xsato it.Edit recipe append
~/leopard-linux-1/sources/meta-local/recipes-bsp/hdf/external-hdf_%.bbappendand set path XSA fileFILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" HDF_BASE = "file://" HDF_PATH = "leopard-minimal.xsa"
Build project Yocto¶
Build project artifacts:
machine:~/leopard-linux-1/build$ bitbake leopard-allWarning
First build might take a long time to complete. Be patient.
Prepare build artifacts for transfer to EGSE Host
machine:~/leopard-linux-1/build$ mkdir -p ../egse-host-transfer/ machine:~/leopard-linux-1/build$ cp tmp/deploy/images/leopard-dpu/bootbins/boot-common.bin ../egse-host-transfer/ machine:~/leopard-linux-1/build$ cp tmp/deploy/images/leopard-dpu/system.dtb ../egse-host-transfer/ machine:~/leopard-linux-1/build$ cp tmp/deploy/images/leopard-dpu/nominal-image-leopard-dpu.rootfs.cpio.gz.u-boot ../egse-host-transfer/ machine:~/leopard-linux-1/build$ cp tmp/deploy/images/leopard-dpu/Image ../egse-host-transfer/Transfer content of
~/leopard-linux-1/egse-host-transferdirectory to EGSE Host and place it in/var/tftp/tutorialdirectory
Booting Linux on DPU EGSE Host¶
Verify that all necessary artifacts are present on EGSE Host:
customer@egse-host:~$ ls -lh /var/tftp/tutorial total 48M -rw-rw-r-- 1 customer customer 21M Jul 16 07:15 Image -rw-rw-r-- 1 customer customer 1.6M Jul 16 07:15 boot-common.bin -rw-rw-r-- 1 customer customer 41M Jul 16 07:15 nominal-image-leopard-dpu.rootfs.cpio.gz.u-boot -rw-rw-r-- 1 customer customer 39K Jul 16 07:15 system.dtbNote
Exact file size might differ a bit but they should be in the same range (for example
nominal-image-leopard-dpu.rootfs.cpio.gz.u-bootshall be about ~40MB)Ensure that Leopard is powered off
customer@egse-host:~$ sml power off Powering off...SuccessPrepare U-Boot script for booting from network by writing following content to
/var/tftp/leopard-boot.cmddhcp tftpboot ${kernel_addr_r} /tutorial/Image tftpboot ${fdt_addr_r} /tutorial/system.dtb tftpboot ${ramdisk_addr_r} /tutorial/nominal-image-leopard-dpu.rootfs.cpio.gz.u-boot booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}Compile U-Boot script
customer@egse-host:~$ mkimage -A arm64 -O U-Boot -T script -C none -d /var/tftp/leopard-boot.cmd /var/tftp/leopard-boot.scr Image Name: Created: Wed Jan 22 08:31:23 2025 Image Type: AArch64 U-Boot Script (uncompressed) Data Size: 240 Bytes = 0.23 KiB = 0.00 MiB Load Address: 00000000 Entry Point: 00000000 Contents: Image 0: 232 Bytes = 0.23 KiB = 0.00 MiBPower on Leopard
customer@egse-host:~$ sml power on Powering on...SuccessWrite boot firmware to DPU boot flash
customer@egse-host:~$ sml boot-flash write --nor-memory nor1 0 /var/tftp/tutorial/boot-common.bin Uploading ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 48.6 MB/s Erasing ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 553.3 kB/s Programming ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 13.5 kB/sWrite U-Boot boot script to DPU boot flash
customer@egse-host:~$ sml boot-flash write --nor-memory nor1 0x380000 /var/tftp/leopard-boot.scr Uploading ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ? Erasing ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ? Programming ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 30.7 MB/sOpen second SSH connection to EGSE Host and start
minicomto observe boot processcustomer@egse-host:~$ minicom -D /dev/sml/leopard-pn1-uartLeave this terminal open and get back to SSH connection used in previous steps.
Power on Processing Node 1
customer@egse-host:~$ sml pn1 power on --nor-memory nor1 Powering on processing node Node1...SuccessDPU boot process should be visible in
minicomterminalNote
It might take ~20 seconds to get first line of output
Zynq MP First Stage Boot Loader Release 2023.2 Oct 12 2023 - 15:51:06 [SI5338] I2C initialized [SI5338] Clock generator configured successfully [SI5338] done! PMU Firmware 2023.2 Oct 12 2023 15:51:06 PMU_ROM Version: xpbr-v8.1.0-0 NOTICE: BL31: Non secure code at 0x8000000 NOTICE: BL31: v2.8(release):xlnx_rebase_v2.8_2023.2_ksb_sep NOTICE: BL31: Built : 12:21:43, Aug 31 2023 U-Boot 2023.01-build-6a53a3e6bd5cc95fdcb5508b7f15bf76e709a9b2 (Sep 21 2023 - 11:02:37 +0000) CPU: ZynqMP Silicon: v3 Chip: zu9eg Board: Xilinx ZynqMP DRAM: 2 GiB (effective 16 GiB) PMUFW: v1.1 PMUFW: No permission to change config object EL Level: EL2 Secure Boot: not authenticated, not encrypted Core: 46 devices, 27 uclasses, devicetree: board NAND: 4096 MiB MMC: mmc@ff170000: 0 Loading Environment from SPIFlash... SF: Detected s25fl512s with page size 256 Bytes, erase size 256 KiB, total 64 MiB *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial [Leopard] Running on PN1 Bootmode: QSPI_MODE Reset reason: EXTERNAL Net: ZYNQ GEM: ff0d0000, mdio bus ff0d0000, phyaddr 0, interface rgmii-id eth0: ethernet@ff0d0000 scanning bus for devices... SATA link 0 timeout. SATA link 1 timeout. AHCI 0001.0301 32 slots 2 ports 6 Gbps 0x3 impl SATA mode flags: 64bit ncq pm clo only pmp fbss pio slum part ccc apst starting USB... No working controllers found Hit any key to stop autoboot: 0 SF: Detected s25fl512s with page size 256 Bytes, erase size 256 KiB, total 64 MiB device 0 offset 0x380000, size 0x80000 SF: 524288 bytes @ 0x380000 Read: OK QSPI: Trying to boot script at 20000000 ## Executing script at 20000000 BOOTP broadcast 1 DHCP client bound to address 172.20.200.100 (43 ms) Using ethernet@ff0d0000 device TFTP from server 172.20.200.1; our IP address is 172.20.200.100 Filename '/tutorial/Image'. Load address: 0x18000000 Loading: ################################################################# 9.2 MiB/s done Bytes transferred = 21377536 (1463200 hex) Using ethernet@ff0d0000 device TFTP from server 172.20.200.1; our IP address is 172.20.200.100 Filename '/tutorial/system.dtb'. Load address: 0x40000000 Loading: ### 7.5 MiB/s done Bytes transferred = 39069 (989d hex) Using ethernet@ff0d0000 device TFTP from server 172.20.200.1; our IP address is 172.20.200.100 Filename '/tutorial/nominal-image-leopard-dpu.rootfs.cpio.gz.u-boot'. Load address: 0x2100000 Loading: ################################################################# 9.4 MiB/s done Bytes transferred = 42320355 (285c1e3 hex) ## Loading init Ramdisk from Legacy Image at 02100000 ... Image Name: nominal-image-leopard-dpu.rootfs Created: 2011-04-05 23:00:00 UTC Image Type: AArch64 Linux RAMDisk Image (uncompressed) Data Size: 42320291 Bytes = 40.4 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 40000000 Booting using the fdt blob at 0x40000000 Working FDT set to 40000000 Loading Ramdisk to 7935f000, end 7bbbb1a3 ... OK Loading Device Tree to 0000000079352000, end 000000007935e89c ... OK Working FDT set to 79352000 Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034] [ 0.000000] Linux version 6.1.30-xilinx-v2023.2 (oe-user@oe-host) (aarch64-oe-linux-gcc (GCC) 13.2.0, GNU ld (GNU Binutils) 2.41.0.20231213) #1 SMP Fri Sep 22 10:41:01 UTC 2023 ... [ 2.945728] of_cfs_init [ 2.948207] of_cfs_init: OK [ 2.952210] ALSA device list: [ 2.955177] No soundcards found. [ 2.974513] mmc0: SDHCI controller on ff170000.mmc [ff170000.mmc] using ADMA 64-bit [ 2.982998] Freeing unused kernel memory: 2176K [ 2.987664] Run /init as init process [ 3.004971] systemd[1]: System time is further ahead than 15y after build time, resetting clock to build time. [ 3.020050] systemd[1]: systemd 254.4^ running in system mode (-PAM -AUDIT -SELINUX -APPARMOR +IMA -SMACK +SECCOMP -GCRYPT -GNUTLS -OPENSSL +ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE -TPM2 -BZIP2 -LZ4) [ 3.052059] systemd[1]: Detected architecture arm64. Welcome to KP Labs DPU build-6a53a3e (KP Labs DPU)! [ 3.068419] systemd[1]: Hostname set to <leopard-dpu>. [ 3.073672] systemd[1]: Initializing machine ID from random generator. [ 3.362495] systemd[1]: Queued start job for default target Multi-User System. ... KP Labs DPU build-6a53a3e leopard-dpu ttyPS0 leopard-dpu login:Log in to DPU using
rootuserleopard-dpu login: root root@leopard-dpu:~#
Summary¶
In this tutorial you’ve built minimal Linux distribution for Leopard DPU using Yocto and XSA file prepared with platform configuration. After copying build artifacts to EGSE Host you’ve written necessary boot firmware to DPU boot flash. You’ve also prepared U-Boot script for booting from network and observed boot process in minicom terminal. Finally you’ve logged in to DPU and verified that Linux is running.