Modify Device Tree

After completing your board design, usually you need to provide corresponding device tree blobs so that the kernel can recognize your new hardware. For Genio EVK boards, device tree binaries (.dtb/dtbo) are stored in a firmware partition, formatted as the FAT32 filesystem.

To generate necessary assets from your device tree blobs used for flashing, there are two methods to achieve this:

  • Using IOT Yocto to generate firmware partition image. This is the standard and recommended way.

  • Modifying the existing firmware partition image. Useful for those who are impatient.

The overall process can be summarized to following steps:

  • Create your board dts based on Genio EVK boards.

  • Build and compile the board dts into dtb files with Ubuntu Linux kernel.

  • Deploy the dtb files to the FIRMWARE partition of bootloader.

  • Modify bootloader (U-Boot) to load your dtb files during boot.

The following sections will describe both methods in detail.

Compile Board DTS with Ubuntu Linux Kernel

To build your board dts into dtb binary, follow the steps below:

1. First, follow the steps in Modify Ubuntu Linux Kernel to set up an Ubuntu kernel build environment, and fetch the Ubuntu kernel source code.

Note

Be sure to use the same kernel tag as the kernel version used in the board image

  1. Add your device tree files to Ubuntu kernel source tree. Assume your dts is named customBoard.dts:

$ cd jammy
$ cp customBoard.dts arch/arm64/boot/dts/mediatek/
  1. Modify the Makefile:

$ vim arch/arm64/boot/dts/mediatek/Makefile

and add the following line at the bottom of the file:

dtb-$(CONFIG_ARCH_MEDIATEK) += customBoard.dtb
  1. Then simply build the kernel using the same steps in Modify Ubuntu Linux Kernel.

Set the cross-compilation environment variables if you would like to build on a non-ARM64 platform:

export ARCH=arm64
export $(dpkg-architecture -aarm64)
export CROSS_COMPILE=aarch64-linux-gnu-

and build the kernel with the following commands:

fakeroot debian/rules clean
fakeroot debian/rules binary

The building system will produce Debian packages in the upper-level directory. For example,

$ cd ..
$ ls -1 *.deb
linux-buildinfo-5.15.0-1003-mtk_5.15.0-1003.4_arm64.deb
linux-headers-5.15.0-1003-mtk_5.15.0-1003.4_arm64.deb
linux-image-5.15.0-1003-mtk_5.15.0-1003.4_arm64.deb
linux-modules-5.15.0-1003-mtk_5.15.0-1003.4_arm64.deb

Locate the .deb package named modules. In the example above, it should be linux-modules-5.15.0-1003-mtk_5.15.0-1003.4_arm64.deb.

Then extract the linux-modules-*.deb file into a directory. In the example below we use modules:

mkdir modules
dpkg -x linux-modules-5.15.0-1017-mtk_5.15.0-1017.19_arm64.deb modules
cd modules
ls lib/firmware/5.15.0-1017-mtk/device-tree/mediatek/customBoard.dtb

The lib/firmware/5.15.0-1017-mtk/device-tree/mediatek/customBoard.dtb is the device tree binary you need.

In the following sections, we will package this customBoard.dtb file into the boot firmware archives.

Using IOT Yocto to Create Boot Assets

The overall boot firmwares generation process using IOT Yocto can be depicted in following diagram:

../_images/dtb_modify_yocto.png

Step 1: Downloading Ubuntu disk image tarball

Visit https://ubuntu.com/download/mediatek-genio to download and extract the Ubuntu disk image.

Step 2: Building custom device tree blobs

Please refer to Compile Board DTS with Ubuntu Linux Kernel.

Step 3: Adding custom device tree blobs to IOT Yocto source

To add device tree blobs, an IOT Yocto source tree is needed. To download IOT Yocto source, please visit IOT Yocto documentation for more details.

Supposed that we have downloaded IOT Yocto source tree, please create a new folder files under the source tree and copy all custom device tree blobs to the folder:

mkdir <YOCTO>/src/meta-rity/meta/recipes-core/board-assets/files
cp <YOUR_DTB_FILES> <YOCTO>/src/meta-rity/meta/recipes-core/board-assets/files

And create a new file firmware-part.bbappend with following content:

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

SRC_URI = " \
    file://customBoard.dtb \
    file://device1.dtbo \
    file://device2.dtbo \
"

Step 4: Building board assets

Please run following commands to initialize building environment:

cd <YOCTO>
TEMPLATECONF=$PWD/src/meta-rity/meta/conf source src/poky/oe-init-build-env

And modify the content of building configuration file build/conf/local.conf to add following settings:

DISTRO_FEATURES += "prebuilt-dtb"
MACHINE_DTB = "customBoard.dtb"
DTB_PATH = "/FIRMWARE/your-vendor/customBoard/"

# Enable building proprietary software if you have access to MediaTek proprietary
# repositories.
#NDA_BUILD = "1"

Now please run following command to build board assets:

DISTRO=rity-demo MACHINE=<genio board name> bitbake board-assets

Where <genio board name> is the name of a Genio EVK board, such as genio-700-evk.

Note

The value of <genio board name> must be one of the machine names defined in IOT Yocto. You can choose the name of a Genio EVK board on which your custom board is based.

If building process completes, a tarball board-assets.tar.gz will be created under <YOCTO>/build/tmp/deploy/images/<genio board name> folder.

Step 5: Flashing board assets

Before flashing board assets, we need to put built assets under the extracted folder of Ubuntu image tarball (refer to Step 1: Downloading Ubuntu disk image tarball), so that the flashing tool can recognize and load necessary files correctly.

Please run the following commands to copy board assets:

cd <YOUR_PATH> && tar zxf board-assets.tar.gz
cp <YOUR_PATH>/board-assets/firmware.vfat <UBUNTU>
cp <YOUR_PATH>/board-assets/u-boot-initial-env <UBUNTU>

Note the file firmware.vfat is a partition image containing your custom device tree blobs.

Now we’re ready to flash our custom device tree blobs:

cd <UBUNTU>
genio-flash firmware:firmware.vfat mmc0boot1

Modifying FIRMWARE Partition Content Manually

If you already have a firmware.vfat file (no matter it’s downloaded or built), in addition to using IOT Yocto, you can also modify the content of firmware.vfat to add the device tree blobs for your custom board.

Note

This method is intended solely for development purposes. We strongly advise using IOT Yocto to construct board assets.

The overall board assets manual modification process can be depicted in following diagram:

../_images/dtb_modify_manual.png

Step 1: Building custom device tree blobs

Please refer to Compile Board DTS with Ubuntu Linux Kernel.

Step 2: Modifying firmware.vfat

To modify firmware.vfat, we need to mount the file as a loop device:

sudo mkdir -p /mnt/firmware
sudo mount -o loop firmware.vfat /mnt/firmware

And copy your compiled DTB file, e.g. customBoard.dtb, to the subfolder under the /mnt/firmware folder:

sudo mkdir -p /mnt/firmware/FIRMWARE/your-vendor/customBoard/
sudo cp customBoard.dtb /mnt/firmware/FIRMWARE/your-vendor/customBoard/
sudo cp device1.dtbo /mnt/firmware/FIRMWARE/your-vendor/customBoard/
sudo cp device2.dtbo /mnt/firmware/FIRMWARE/your-vendor/customBoard/

And then unmount to ensure changes are written to the file:

sudo umount /mnt/firmware

Finally, integrate the resulting firmware.vfat into your boot assets.

Step 3: Adjust Boot Script

In most cases, you might add new device tree binaries or adding new overlay(.dtbo) files. Therefore it is necessary to update the bootloader’s initialization script to load the device tree files you want, and pass the device tree to Linux kernel for correct hardware device detection and driver probing.

In U-Boot, the device tree files being loaded during boot flow is determined by a set of environment variables. To change the device tree files being used, you can simply update the u-boot-initial-env file in the boot assets.

For example, to allow U-Boot to load your custom device tree files, please edit u-boot-initial-env and change following settings:

dtb_path=/FIRMWARE/your-vendor/customBoard/
fdtfile=customBoard.dtb
list_dtbo= device1.dtbo device2.dtbo
boot_conf=#conf-customBoard.dtb#conf-device1.dtbo#conf-device2.dtbo

Note we modify the dtb_path with the folder path you’ve added in Step 2: Modifying firmware.vfat. Additionally, we update fdtfile with the custom device tree file, and include custom device tree overlays in both list_dtbo and boot_conf.

Step 4: Flashing board assets

You can use genio-flash to update the firmware partition on the EVK during development:

genio-flash firmware:firmware.vfat

If you want to apply this firmware during production, you might want to combine this partition with other partitions to produce a full-disk image.

Please refer to Combine Partition Images into Full-Disk Image to do so.

If you modified boot scripts in Step 3: Adjust Boot Script, you also need to update the mmc0boot1 partition to update these U-Boot environment variables on the board during development:

genio-flash mmc0boot1

Check Device Tree

After updating firmware partition and booting into the Linux kernel, you can use dtc tool to convert the dtb binary loaded by the Linux kernel back into a plain-text format for inspection:

dtc -I fs /proc/device-tree

You can check the device tree nodes to confirm if your modifications to the device tree have been successfully applied or not.