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 Antelope DPU through EGSE Host

A bit of background

Running Linux on device like Antelope 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 Antelope DPU boot capabilities to load boot firmware into persistent memory and load Linux kernel and root filesystem from network.

Prerequisites

Provided outputs

Following files (Tutorial files) are associated with this tutorial:

  • Antelope/Zero-to-hero/02 Minimalist Linux distribution/boot-firmware.bin - Boot firmware for Antelope

  • Antelope/Zero-to-hero/02 Minimalist Linux distribution/boot-pins.bin - Boot script for Antelope

  • Antelope/Zero-to-hero/02 Minimalist Linux distribution/antelope-minimal-image-antelope.rootfs.cpio.gz.u-boot - Root filesystem for Antelope

  • Antelope/Zero-to-hero/02 Minimalist Linux distribution/Image - Linux kernel

  • Antelope/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

  1. Create new directory for Yocto project and navigate to it.

    machine:~$ mkdir ~/antelope-linux-1
    machine:~$ cd ~/antelope-linux-1
    machine:~/antelope-linux-1$
    
  2. Clone Poky layer from Yocto project

    machine:~/antelope-linux-1$ git clone -b nanbield https://git.yoctoproject.org/poky sources/poky
    
  3. Create new build configuration

    machine:~/antelope-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 ~/antelope-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 ~/antelope-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:~/antelope-linux-1/build$
    

Add layers Yocto

  1. Clone Xilinx layers:

    machine:~/antelope-linux-1/build$ git clone -b nanbield https://github.com/Xilinx/meta-xilinx.git ../sources/meta-xilinx
    machine:~/antelope-linux-1/build$ git clone -b nanbield https://github.com/Xilinx/meta-xilinx-tools.git ../sources/meta-xilinx-tools
    
  2. Add set of required layers from Xilinx repositories:

    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx/meta-xilinx-core
    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx/meta-xilinx-bsp
    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx/meta-xilinx-standalone
    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-xilinx-tools
    

    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.

  3. Clone KP Labs layers

    machine:~/antelope-linux-1/build$ git clone -b nanbield https://github.com/kplabs-pl/meta-kp-classes.git ../sources/meta-kp-classes
    machine:~/antelope-linux-1/build$ git clone -b nanbield https://github.com/kplabs-pl/meta-kp-antelope.git ../sources/meta-kp-antelope
    
  4. Add set of required layers from KP Labs repositories:

    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-kp-classes
    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-kp-antelope
    

Create layer for customizations Yocto

  1. Create empty layer

    machine:~/antelope-linux-1/build$ bitbake-layers create-layer ../sources/meta-local
    
  2. Add newly created layer to project

    machine:~/antelope-linux-1/build$ bitbake-layers add-layer ../sources/meta-local
    
  3. Verify set of layers enabled in project by opening ~/antelope-linux-1/build/conf/bblayers.conf and 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 ?= " \
    ~/antelope-linux-1/sources/poky/meta \
    ~/antelope-linux-1/sources/poky/meta-poky \
    ~/antelope-linux-1/sources/poky/meta-yocto-bsp \
    ~/antelope-linux-1/sources/meta-xilinx/meta-xilinx-core \
    ~/antelope-linux-1/sources/meta-xilinx/meta-xilinx-bsp \
    ~/antelope-linux-1/sources/meta-xilinx/meta-xilinx-standalone \
    ~/antelope-linux-1/sources/meta-xilinx-tools \
    ~/antelope-linux-1/sources/meta-kp-classes \
    ~/antelope-linux-1/sources/meta-kp-antelope \
    ~/antelope-linux-1/sources/meta-local \
    "
    

Configure project Yocto

  1. Edit ~/antelope-linux-1/build/conf/local.conf and add following lines at the beginning:

    MACHINE = "antelope"
    DISTRO = "kplabs-dpu"
    INHERIT += "rm_work"
    
  2. Create recipe append to set XSA file

    machine:~/antelope-linux-1/build$ recipetool newappend --wildcard-version ../sources/meta-local/ external-hdf
    
  3. Create directory ~/antelope-linux-1/sources/meta-local/recipes-bsp/hdf/external-hdf and copy antelope_minimal.xsa to it.

  4. Edit recipe append ~/antelope-linux-1/sources/meta-local/recipes-bsp/hdf/external-hdf_%.bbappend and set path to XSA file

    FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
    
    HDF_BASE = "file://"
    HDF_PATH = "antelope_minimal.xsa"
    

Build project Yocto

  1. Build project artifacts:

    machine:~/antelope-linux-1/build$ bitbake antelope-all
    

    Warning

    First build might take a long time to complete. Be patient.

  2. Prepare build artifacts for transfer to EGSE Host

    machine:~/antelope-linux-1/build$ mkdir -p ../egse-host-transfer
    machine:~/antelope-linux-1/build$ cp tmp/deploy/images/antelope/bootbins/boot-firmware.bin ../build/egse-host-transfer/
    machine:~/antelope-linux-1/build$ cp tmp/deploy/images/antelope/u-boot-scripts/boot-script-pins/boot-pins.scr ../build/egse-host-transfer/
    machine:~/antelope-linux-1/build$ cp tmp/deploy/images/antelope/system.dtb ../build/egse-host-transfer/
    machine:~/antelope-linux-1/build$ cp tmp/deploy/images/antelope/Image ../build/egse-host-transfer/
    machine:~/antelope-linux-1/build$ cp tmp/deploy/images/antelope/antelope-minimal-image-antelope.rootfs.cpio.gz.u-boot ../build/egse-host-transfer/
    
  3. Transfer content of ~/antelope-linux-1/egse-host-transfer directory to EGSE Host and place it in /var/tftp/tutorial directory

Booting Linux on DPU EGSE Host

  1. Verify that all necessary artifacts are present on EGSE Host:

    customer@egse-host:~$ ls -lh /var/tftp/tutorial
    total 30158
    -rw-rw-r-- 1 customer customer  22M Jul 10 08:38 Image
    -rw-rw-r-- 1 customer customer 1.6M Jul 10 08:35 boot-firmware.bin
    -rw-rw-r-- 1 customer customer 2.8K Jul 10 08:38 boot-pins.scr
    -rw-rw-r-- 1 customer customer  16M Jul 10 08:39 antelope-minimal-image-antelope.rootfs.cpio.gz.u-boot
    -rw-rw-r-- 1 customer customer  37K Jul 10 08:38 system.dtb
    

    Note

    Exact file size might differ a bit but they should be in the same range (for example antelope-minimal-image-antelope.rootfs.cpio.gz.u-boot shall be about ~15MB)

  2. Power on Antelope

    customer@egse-host:~$ sml power on
    Powering on...Success
    
  3. Power on DPU

    customer@egse-host:~$ sml dpu power on
    Powering on...Success
    
  4. Write boot firmware to DPU boot flash

    customer@egse-host:~$ sml dpu boot-flash write 0 /var/tftp/tutorial/boot-firmware.bin
    Uploading   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 43.1 MB/s
    Erasing     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 383.9 kB/s
    Programming ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 13.1 kB/s
    
  5. Write U-Boot boot script to DPU boot flash

    customer@egse-host:~$ sml dpu boot-flash write 0x4E0000 /var/tftp/tutorial/boot-pins.scr
    Uploading   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ?
    Erasing     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ?
    Programming ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 55.9 MB/s
    
  6. Prepare U-Boot script for booting from network by writing following content to /var/tftp/antelope-boot.cmd

    dhcp ${kernel_addr_r} /tutorial/Image
    dhcp ${ramdisk_addr_r} /tutorial/antelope-minimal-image-antelope.rootfs.cpio.gz.u-boot
    dhcp ${fdt_addr_r} /tutorial/system.dtb
    booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
    
  7. Compile U-Boot script

    customer@egse-host:~$ mkimage -A arm64 -O U-Boot -T script -C none -d /var/tftp/antelope-boot.cmd /var/tftp/antelope-boot.scr
    Image Name:
    Created:      Wed Jul 10 08:50:54 2024
    Image Type:   AArch64 U-Boot Script (uncompressed)
    Data Size:    216 Bytes = #.21 KiB = #.00 MiB
    Load Address: 00000000
    Entry Point:  00000000
    Contents:
        Image 0: 208 Bytes = #.20 KiB = #.00 MiB
    
  8. Open second SSH connection to EGSE Host and start minicom to observe boot process

    customer@egse-host:~$ minicom -D /dev/sml/antelope-dpu-uart
    

    Leave this terminal open and get back to SSH connection used in previous steps.

  9. Release DPU from reset

    customer@egse-host:~$ sml dpu reset off 7
    
  10. DPU boot process should be visible in minicom terminal

    Zynq MP First Stage Boot Loader
    Release 2023.2   Oct 12 2023  -  15:51:06
    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 (Sep 21 2023 - 11:02:37 +0000)
    
    CPU:   ZynqMP
    Silicon: v3
    Chip:  zu4cg
    Board: Xilinx ZynqMP
    DRAM:  2 GiB (effective 8 GiB)
    PMUFW:  v1.1
    PMUFW:  No permission to change config object
    EL Level:       EL2
    Secure Boot:    not authenticated, not encrypted
    Core:  35 devices, 19 uclasses, devicetree: board
    NAND:  4096 MiB
    MMC:
    Loading Environment from SPIFlash... SF: Detected mt25qu512a with page size 256 Bytes, erase size 64 B
    *** Warning - bad CRC, using default environment
    
    In:    serial
    Out:   serial
    Err:   serial
    Bootmode: QSPI_MODE
    Reset reason:   SRST
    Net:
    ZYNQ GEM: ff0e0000, mdio bus ff0e0000, phyaddr 0, interface rgmii-id
    
    Warning: ethernet@ff0e0000 (eth0) using random MAC address - 3a:54:5e:11:4a:f8
    eth0: ethernet@ff0e0000
    scanning bus for devices...
    starting USB...
    No working controllers found
    Hit any key to stop autoboot:  0
    SF: Detected mt25qu512a with page size 256 Bytes, erase size 64 KiB, total 64 MiB
    device 0 offset 0x4e0000, size 0x80000
    SF: 524288 bytes @ 0x4e0000 Read: OK
    QSPI: Trying to boot script at 20000000
    ## Executing script at 20000000
    Antelope: Select boot image with GPIO pins
    gpio: pin 29 (gpio 29) value is 1
    gpio: pin 30 (gpio 30) value is 1
    gpio: pin 31 (gpio 31) value is 1
    Antelope: Selected BOOT image 7
    ethernet@ff0e0000 Waiting for PHY auto negotiation to complete. done
    BOOTP broadcast 1
    BOOTP broadcast 2
    DHCP client bound to address 172.20.200.100 (301 ms)
    Using ethernet@ff0e0000 device
    TFTP from server 172.20.200.1; our IP address is 172.20.200.100
    Filename '/antelope-boot.scr'.
    Load address: 0x10000000
    Loading: #
            90.8 KiB/s
    done
    Bytes transferred = 280 (118 hex)
    ## Executing script at 10000000
    BOOTP broadcast 1
    DHCP client bound to address 172.20.200.100 (48 ms)
    Using ethernet@ff0e0000 device
    TFTP from server 172.20.200.1; our IP address is 172.20.200.100
    Filename '/tutorial/Image'.
    Load address: 0x18000000
    Loading: #################################################################
    ...
             9.8 MiB/s
    done
    Bytes transferred = 22174208 (1525a00 hex)
    BOOTP broadcast 1
    DHCP client bound to address 172.20.200.100 (48 ms)
    Using ethernet@ff0e0000 device
    TFTP from server 172.20.200.1; our IP address is 172.20.200.100
    Filename '/tutorial/antelope-minimal-image-antelope.rootfs.cpio.gz.u-boot'.
    Load address: 0x2100000
    Loading: #################################################################
    ...
            9.9 MiB/s
    done
    Bytes transferred = 16286848 (f88480 hex)
    BOOTP broadcast 1
    DHCP client bound to address 172.20.200.100 (40 ms)
    Using ethernet@ff0e0000 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.1 MiB/s
    done
    Bytes transferred = 37194 (914a hex)
    ## Loading init Ramdisk from Legacy Image at 02100000 ...
    Image Name:   antelope-minimal-image-antelope.
    Created:      2011-04-05  23:00:00 UTC
    Image Type:   AArch64 Linux RAMDisk Image (uncompressed)
    Data Size:    16286784 Bytes = 15.5 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 7ac68000, end 7bbf0440 ... OK
    Loading Device Tree to 000000007ac5b000, end 000000007ac67149 ... OK
    Working FDT set to 7ac5b000
    
    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.23
    [    0.000000] Machine model: xlnx,zynqmp
    ...
    [    3.622749] Run /init as init process
    [    3.639643] systemd[1]: System time is further ahead than 15y after build time, resetting clock to.
    [    3.654546] systemd[1]: systemd 254.4^ running in system mode (-PAM -AUDIT -SELINUX -APPARMOR +IMA)
    [    3.686343] systemd[1]: Detected architecture arm64.
    
    Welcome to KP Labs DPU 1.0!
    
    [    3.700353] systemd[1]: Hostname set to <antelope>.
    [    3.705351] systemd[1]: Initializing machine ID from random generator.
    ...
    KP Labs DPU 1.0 antelope ttyPS0
    
    antelope login:
    
  11. Log in to DPU using root user

    antelope login: root
    root@antelope:~#
    

Summary

In this tutorial you’ve built minimal Linux distribution for Antelope 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.