This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] AM6x: Using a custom device tree file for booting the Linux Kernel with TI's Yocto SDK v9.x

Part Number: AM625
Other Parts Discussed in Thread: SK-AM62, , SK-AM62B

Overview

It is a common need wanting to incorporate a custom Linux device tree file into the boot process of Yocto-generated filesystem images. This FAQ introduces a simple and basic approach in the context of TI's Yocto SDK v9.x and the SK-AM62 board of how to add a new device tree file called k3-am625-custom.dts to the Linux kernel tree which will then be build as part of the Yocto build process and incorporated into various output images (such as SD card images). For the boot process to work properly this also requires a modification to U-Boot changing the default device tree file that's used which is shown as well. The same approach applies to other AM6x devices.

Kernel Source & Yocto-related Changes

In order to demonstrate the addition of a new device tree file to the Kernel the existing arch/arm64/boot/dts/ti/k3-am625-sk.dts source file was cloned into a new file called arch/arm64/boot/dts/ti/k3-am625-custom.dts with the only change being made updating the machine-identifying device tree property as model = "Texas Instruments AM625 CUSTOM". This has the advantage that we can easily trace this change throughout the build process as well as check it during Linux runtime. In an actual real-world application of course there would be additional modifications to various peripheral nodes, etc. Then, this newly-added device tree file was added to the respective Kernel arch/arm64/boot/dts/ti/Makefile to become part of the Kernel build process. The Kernel changes were then turned into a patch, and added to the recipes-kernel/linux/linux-ti-staging_%.bbappend recipe of the meta-tisdk distribution layer. In an actual application the user should have their own layer to carry such modifications.

Note that we also update the am62xx-evm machine configuration at conf/machine/am62xx-evm.conf (meta-ti/meta-ti-bsp layer) to tailor the Kernel fit image creation process and optimize the overall build.

U-Boot Source & Yocto-related Changes

For U-Boot to use our new customized device tree file we need to change the default_device_tree environmental variable, as it is used both in direct DTB loading scenarios (when boot_fit=0), or during DTB selection when the FIT-image boot process is used (when boot_fit=1). This environmental variable is set as part of the board/ti/am62x/am62x.env file so we need to update that file to have default_device_tree to get assigned a new value of k3-am625-custom.dtb. Similar to the Kernel Yocto recipe changes discussed earlier also here we make the change by adding a patch to the corresponding recipe located at recipes-bsp/u-boot/u-boot-ti-staging_%.bbappend of the meta-tisdk layer.

Patching to the Yocto Tree

As part of this FAQ two patches are provided:

0001-ti-demo-Add-custom-k3-am625-custom-board.dts-file-fo.patch

0001-conf-machine-am62xx-evm-Use-custom-k3-am625-custom.d.patch

After downloading, apply them to your Yocto tree as follows (assuming the patches have been downloaded to the ~/tmp folder):

a0797059@dasso:~/tisdk/am62xx-evm/sources (dev)
$ git -C meta-tisdk am --whitespace=nowarn ~/tmp/0001-ti-demo-Add-custom-k3-am625-custom-board.dts-file-fo.patch
Applying: ti: demo: Add custom k3-am625-custom-board.dts file for SK-AM62 use

a0797059@dasso:~/tisdk/am62xx-evm/sources (dev)
$ git -C meta-ti am --whitespace=nowarn ~/tmp/0001-conf-machine-am62xx-evm-Use-custom-k3-am625-custom.d.patch
Applying: conf: machine: am62xx-evm: Use custom 'k3-am625-custom.dtb' DTS file

Testing the Changes

After building the tisdk-base-image (it was chosen over the tisdk-default-image for this proof of concept as it builds quicker due to its much smaller size and it being sufficient enough for what we need here) and programming the generated WIC image to an SD card and booting it on an SK-AM62B EVM, we can observe the impact of the updated device tree file as below. By default this boot will use the standalone device tree blob from the boot media located in the rootfs at /boot/dtb/ti/k3-am625-custom.dtb. Note the updated "Machine model: Texas Instruments AM625 CUSTOM" string early in the Kernel log, and also how this is reflected when reading the model device tree property during Linux runtime:

<...snip...>
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc1 is current device
SD/MMC found on device 1
Failed to load 'boot.scr'
574 bytes read in 17 ms (32.2 KiB/s)
Loaded env from uEnv.txt
Importing environment from mmc1 ...
## Error: "main_cpsw0_qsgmii_phyinit" not defined
19376640 bytes read in 220 ms (84 MiB/s)
59550 bytes read in 19 ms (3 MiB/s)
Working FDT set to 88000000
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
Working FDT set to 88000000
   Loading Device Tree to 000000008feee000, end 000000008fffffff ... OK
Working FDT set to 8feee000

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 6.1.80-ti-g2e423244f8c0 (oe-user@oe-host) (aarch64-oe-linux-gcc (GCC) 11.4.0, GNU ld (GNU Binutils) 2.38.20220708) #1 SMP PREEMPT Wed Mar 20 14:43:33 UTC 2024
[    0.000000] Machine model: Texas Instruments AM625 CUSTOM
[    0.000000] earlycon: ns16550a0 at MMIO32 0x0000000002800000 (options '')
[    0.000000] printk: bootconsole [ns16550a0] enabled
[    0.000000] efi: UEFI not found.
<...snip...>
root@am62xx-evm:~# cat /sys/firmware/devicetree/base/model && echo
Texas Instruments AM625 CUSTOM
<...snip...>

In order to demonstrate the loading of the device tree blob from the Kernel FIT image located in the rootfs at /boot/fitImage that is also generated during the Yocto build, we need to specifically enable "FIT Boot" during U-Boot runtime. Note how the boot log changes reflecting now that "FIT Boot" is used, and our custom device tree blob is selected from that container.

<...snip...>
Hit any key to stop autoboot:  0
=> env print boot_fit
boot_fit=0
=> env set boot_fit 1
=> env print boot_fit
boot_fit=1
=> boot
switch to partitions #0, OK
mmc1 is current device
SD/MMC found on device 1
Failed to load 'boot.scr'
574 bytes read in 17 ms (32.2 KiB/s)
Loaded env from uEnv.txt
Importing environment from mmc1 ...
## Error: "main_cpsw0_qsgmii_phyinit" not defined
8274118 bytes read in 105 ms (75.2 MiB/s)
name_fit_config=conf-ti_k3-am625-custom.dtb
## Loading kernel from FIT Image at 90000000 ...
   Using 'conf-ti_k3-am625-custom.dtb' configuration                                                                                                                                                     [115/5233]
   Verifying Hash Integrity ... sha512,rsa4096:custMpk+ OK
   Trying 'kernel-1' kernel subimage
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x900000f4
     Data Size:    8210236 Bytes = 7.8 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x81000000
     Entry Point:  0x81000000
     Hash algo:    sha512
     Hash value:   2ce08502d5754a00eac2355d76158cb235ffb7bb6e0b81a3e97ca36658f125083a5dcd357405d0aaab7c16643c63517bb2d86254db81a2d5254d66816195de09
   Verifying Hash Integrity ... sha512+ OK
## Loading fdt from FIT Image at 90000000 ...
   Using 'conf-ti_k3-am625-custom.dtb' configuration
   Verifying Hash Integrity ... sha512,rsa4096:custMpk+ OK
   Trying 'fdt-ti_k3-am625-custom.dtb' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x907d4968
     Data Size:    59550 Bytes = 58.2 KiB
     Architecture: AArch64
     Load Address: 0x83000000
     Hash algo:    sha512
     Hash value:   00cc0400b9ec37a2426514bd30c7e912cbad62bcdf15812cabfb3d11ffdc54750ea4bbbda6d920a6895151c6e2dee7cf47ee6937ba2b2755f5d26bec6d582812
   Verifying Hash Integrity ... sha512+ OK
   Loading fdt from 0x907d4968 to 0x83000000
   Booting using the fdt blob at 0x83000000
Working FDT set to 83000000
   Uncompressing Kernel Image
   Loading Device Tree to 000000008ffee000, end 000000008ffff89d ... OK
Working FDT set to 8ffee000

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 6.1.80-ti-g2e423244f8c0 (oe-user@oe-host) (aarch64-oe-linux-gcc (GCC) 11.4.0, GNU ld (GNU Binutils) 2.38.20220708) #1 SMP PREEMPT Wed Mar 20 14:43:33 UTC 2024
[    0.000000] Machine model: Texas Instruments AM625 CUSTOM
[    0.000000] earlycon: ns16550a0 at MMIO32 0x0000000002800000 (options '')
[    0.000000] printk: bootconsole [ns16550a0] enabled
[    0.000000] efi: UEFI not found.
<...snip...>
root@am62xx-evm:~# cat /sys/firmware/devicetree/base/model && echo
Texas Instruments AM625 CUSTOM
<...snip...>