How to use an own device tree and modified kernel config in Yocto?

If you're on a recent Yocto project release, you can make use of recipetool to do most of the legwork on this. You have two options, you can use the existing recipetool commands and a small amount of manual work, or you can use the recipetool plugin in meta-mentor that provides a few kernel-specific commands to do this for you.

Layer setup

First, you'll want to have a layer to store your changes. If you've already created a layer, you can use that, otherwise we can create one and add it to our configuration:

$ yocto-layer create local 1
$ bitbake-layers add-layer meta-local

Option one: Using the recipetool plugin from meta-mentor

Setup

First, clone meta-mentor:

$ git clone https://github.com/MentorEmbedded/meta-mentor

Next, either add meta-mel to your configuration:

$ bitbake-layers add-layer path/to/meta-mentor/meta-mel

Or copy meta-mentor/meta-mel/lib into your own layer:

$ cp -a path/to/meta-mentor/meta-mel/lib meta-local/

Device tree

$ recipetool kernel_add_dts meta-local /path/to/your.dts

Kernel configuration

$ recipetool kernel_add_fragments meta-local /path/to/your.cfg

Or:

$ recipetool kernel_set_defconfig meta-local /path/to/the/defconfig

Option two: Manual

In the below section, clearly in your case, your-machine-name should be sama5d3xek. The '-m your-machine-name' passed to the recipetool commands below makes the changes in the recipe specific to your machine, rather than affecting any machine which uses that recipe. If you know that recipe is only used for your machine, then you could drop that, but it's safest to keep it, as some BSP layers use the same kernel recipe for multiple machines. For example, linux-yocto is used for many.

Device tree

Then, assuming you have a .dts handy you want to use:

$ recipetool appendsrcfile -wm your-machine-name path/to/meta-local virtual/kernel /path/to/your.dts 'arch/${ARCH}/boot/dts/your.dts'

This will create a .bbappend in meta-local and add the .dts to SRC_URI, placing it in the appropriate path in the kernel source tree. The next step is to edit the append it created and add the .dtb for your .dts to the KERNEL_DEVICETREE variable, i.e.:

KERNEL_DEVICETREE += "your.dtb"

If the kernel recipe includes recipes-kernel/linux/linux-dtb.inc, any .dtb files in KERNEL_DEVICETREE will be created from their .dts files by using the kernel's buildsystem. Some kernels do not include linux-dtb.inc, in which case you can do so yourself in the append:

require recipes-kernel/linux/linux-dtb.inc

Kernel configuration

The kernel configuration is slightly more complex, just because how the configuration is done varies slightly between kernel recipes. Some kernel recipes support configuration fragments (which are just a text file with part of a defconfig/.config), whereas others you'd have to override the configuration entirely. The 'linux-yocto' recipe can handle and use fragments, as can a few others.

To see what kernel recipe you're using (the top filename will be the one used):

$ bitbake -e virtual/kernel | grep '^FILE='

If you want to use configuration fragments, you can either manually create a fragment, or generate one:

$ bitbake -c menuconfig virtual/kernel
$ bitbake -c diffconfig virtual/kernel

The 'diffconfig' task will create a fragment with your changes from the menuconfig and print the path to it.

Then you can add it to the kernel (though again, only certain recipes will use it):

$ recipetool appendsrcfile -wWm your-machine-name meta-local virtual/kernel /path/to/your.cfg

To override the entire config, most recipes will obey and use a 'defconfig' source file, so:

$ recipetool appendsrcfile -Wm your-machine-name meta-local virtual/kernel /path/to/the/defconfig

Note: The defconfig is not generated automatic. Replace defconfig with the result of menuconfig('.config').


The devtool can be very handy if you want to generate patches for the linux-yocto kernel. Other kernel might not support devtool.

## create kernel source patch
devtool modify virtual/kernel
# make some changes
cd ~/poky_sdk/workspace/sources/linux-yocto
vi init/calibrate.c
# test before patch
bitbake -C compile virtual/kernel
# create patch
git add .
git commit -m 'some fix'
devtool update-recipe -a ~/meta-mylayer/  linux-yocto
# clean the source
rm -rf workspace/sources/linux-yocto/

see devtool for details


Related to this question, for educational purposes I tried to add a device tree to an x86 architecture (kernel 5.2.20). To enable the device tree compiler, the following additions to the configuration were needed :

CONFIG_COMPILE_TEST=y    
CONFIG_OF=y    
CONFIG_OF_ALL_DTBS=y

Furthermore, to enable device tree support at runtime, this was additionally needed :

CONFIG_OF_UNITTEST=y    

A convenient place to check if your kernel configs are merged without problems is file
kernel-source/.kernel-meta/cfg/merge_config_build.log