Project

General

Profile

Customizing the yocto build

Objective

This page provides instructions on creating a custom Yocto meta-layer to integrate new software or modify existing configurations for your embedded system development.

These instructions were written and tested using the SDK 09.01 release but should be accurate for most yocto builds built around TI's oe-layersetup tool.

By the end of this guide, you will be able to:
  • Understand the purpose and structure of Yocto Project meta-layers.
  • Utilize the bitbake-layers script to create a new meta-layer.
  • Define the basic directory structure for your custom layer.
  • Integrate your layer into the Yocto Project build system.
  • Create a custom Yocto image based on your layer.

Prerequisites

  • Familiarity with the Yocto Project and its build system.
  • A working Yocto development environment setup and a successful build.
    Run through the steps at Building a Yocto Filesystem
  • Create an empty meta-customer hosted git repo. How this can be done will vary greatly depending on your work environment and whether you use GitLab/GitHub/Gitorious or a bare-bones git server

Note: Throughout this guide, we'll use "meta-customer" as a placeholder for the actual name you choose for your custom layer. Replace "meta-customer" with your desired layer name whenever necessary. Also we'll use "mitysom-am62x-boardname" as a placeholder for your board or project name.

Note: For the AM62Ax replace am62x with am62ax

Folder Structure

This is the final folder structure of the meta-customer layer we will make for reference:

tree meta-customer/
meta-customer/
├── 62x-build.sh
├── 62x-setup.sh
├── conf
│   ├── layer.conf
│   └── machine
│       ├── mitysom-am62x-boardname.conf
│       └── mitysom-am62x-boardname-k3r5.conf
├── configs
│   └── processor-sdk-09.02.01.10-cl-config.txt
├── COPYING.MIT
├── README
├── recipes-core
│   └── images
│       └── mitysom-am62x-boardname-base-image.bb
├── recipes-customer
│   └── fbfill
│       └── fbfill-test_git.bb
├── recipes-example
│   └── example
│       └── example_0.1.bb
├── recipes-kernel
│   └── linux
│       ├── linux-cl-ti
│       │   ├── ads1015.cfg
│       │   └── k3-am62x-mitysom-boardname.dts
│       └── linux-cl-ti_6.1.bbappend
└── recipes-tisdk
    └── tisdk-uenv
        ├── tisdk-uenv
        │   └── uEnv.txt
        └── tisdk-uenv.bbappend

15 directories, 16 files

Steps

Enter the docker poky image and source the yocto environment

Before we delve into creating a custom Yocto Project meta-layer and image, it's crucial to set up your development environment. Here's how to enter the Docker container with the Yocto Project development tools and source the necessary environment variables:

  • Navigate to the oe-layersetup directory and start the docker poky container. This will put you at a bash prompt inside the docker.
    cd oe-layersetup
    ./docker-poky.sh
    
  • Change directory to the build directory and source the yocto project environment
    cd build/
    source conf/setenv
    
  • Set the target machine so we don't have to specify it before each command
    export MACHINE=mitysom-am62x
    

Note: The poky docker image doesn't have any text editors installed so any config and source file changes will need to be done outside the docker container.

Create a New Layer:

Yocto uses a layer system to allow adding new recipes and modifying existing ones. By isolating your modifications and additional software packages within a dedicated meta-layer, you enhance the maintainability and organization of your Yocto Project. This becomes especially crucial when working on complex projects with numerous customizations.

  • Run bitbake-layers create-layer ../sources/meta-customer to generate the base directory structure for your layer.
    This will create a meta-customer directory in the oe-layersetup/sources directory alongside all the other meta-layers needed for the build.
  • Run bitbake-layers add-layer ../sources/meta-customer to temporarily add the new layer to the build/conf/bblayers.conf file. Since this file is auto-generated by the oe-layertool-setup.sh, be careful not to rerun the tool until we create a copy of the oe-layersetup config file later to make this permanent.
  • Edit @sources/meta-customer/conf/layer.conf and ensure the BBFILE_PRIORITY line is set to 20. Also ensure the LAYERDEPENDS line is set to "core mitysom".
    Currently, the highest priority layer is meta-edgeai which is 13. We want to make sure this our custom layer has the highest priority.

We now have a custom layer with an autogenerated example recipe which can be built to test that the layer is set up.

  • Run bitbake example and you should see at the end of the build the following:
    NOTE: Executing Tasks
    ***********************************************
    *                                             *
    *  Example recipe created by bitbake-layers   *
    *                                             *
    ***********************************************
    
  • Now that the meta-layer is created and tested, let's make sure to create a git repo and check in all the files so we can track any changes we make.
    cd ../sources/meta-customer
    git init
    git add *
    git commit -m 'Initial creation of meta-customer'
    
  • Add the hosted git repo you created in the Prerequisites to your local git repo and push the initial commit
    git remote add origin <git_url>
    git push origin master --set-upstream
    

Creating custom oe-layersetup config file

For simplicity, we are going to create a copy of the config file and store it in the newly created meta-customer along with a copy of the setup and build scripts. This allows us to avoid having to branch and make another copy of the oe-layersetup repo and keeps everything related to your setup within your meta-customer layer. However, this does put us into a sort of chicken-and-egg problem when first checking out the project for builds as we will need to check out the meta-customer repo to get the config and setup scripts needed to check out the rest of the repos, however, this shouldn't be a big issue.

Note: This guide provides a basic method. If you have a preferred way to manage your custom configuration, feel free to use it!

  • Copy the 62x-setup.sh, 62x-build.sh scripts to sources/meta-customer
  • Copy the appropriate processor sdk config to sources/meta-customer/configs. Currently, that would be configs/processor-sdk/processor-sdk-09.02.01.10-cl-config.txt
  • Edit sources/meta-customer/62x-setup.sh and update the processor sdk path to point to sources/meta-customer/configs/processor-sdk-09.02.01.10-config.txt
  • Edit sources/meta-customer/62x-build.sh and for now comment out all the bitbake commands that aren't tisdk-base-image to shorten the build. We will update this later to build a custom image.
  • Edit sources/meta-customer/configs/processor-sdk-09.02.01.10-cl-config.txt and add your meta-customer layer to the end of the layers list
    Ex:
    ...
    meta-mitysom,https://support.criticallink.com/git/meta-mitysom.git,kirkstone,HEAD,layers=
    meta-customer,https://.../meta-customer.git,master,HEAD,layers=
    
  • From within the docker, you should be able to run sources/meta-customer/62x-setup.sh and sources/meta-customer/62x-build.sh
  • Commit changes to git repo

Add custom machine config

A custom machine config will allow you to specify a custom device tree and device tree prefix, among other possible machine specific configurations.

To create a custom machine config:
  • Create a machine folder in your layer conf folder.
  • Within that folder create a mitysom-am62x-boardname.conf (meta-customer/conf/machine/mitysom-am62x-boardname.conf).
  • Paste in this basic template:
    #@TYPE: Machine
    #@NAME: mitysom-am62x-boardname
    #@DESCRIPTION: Machine configuration for mitysom-am62x-boardname boards
    
    # Include mitysom-am62x.conf to inherit it's defaults
    require conf/machine/mitysom-am62x.conf
    
    # Mitysom has a lot of recipes that depend on the mitysom-am62x flag, to ensure we use those, we append a mitysom-am62x identity
    SOC_FAMILY:append = ":mitysom-am62x" 
    
    MACHINE_DISPLAYNAME = "MitySOM-AM62x-Boardname" 
    
    # Include all device tree files that begin with the below PREFIX
    KERNEL_DEVICETREE_PREFIX = " \
        ti/k3-am62x-mitysom \
    " 
    
    KERNEL_DEVICETREE ?= " \
        ti/k3-am62x-mitysom-boardname.dtb \
    " 
    
  • You will also need to create a mitysom-am62x-boardname-k3r5.conf in the same location from the following template:
    #@TYPE: Machine
    #@NAME: mitysom-am62x-boardname
    #@DESCRIPTION: Machine configuration for mitysom-am62x-boardname boards
    
    # Include mitysom-am62x.conf to inherit it's defaults
    require conf/machine/mitysom-am62x-k3r5.conf
    
    # Mitysom has a lot of recipes that depend on the mitysom-am62x flag, to ensure we use those, we append a mitysom-am62x identity
    SOC_FAMILY:append = ":mitysom-am62x-k3r5" 
    
  • Finally point your build script to the new board (currently 62x-build.sh, line 18):
    export MACHINE=mitysom-am62x-boardname
    

Add your custom kernel device tree to the kernel recipe

In this step, we will create a bbappend file to modify the kernel recipe and add your custom device tree file for your baseboard. We will also add a kernel config fragment to enable the ADS1015 driver as an example. As an example, we are going to download the devkits device tree, rename it, and have it built by the kernel.

  • Download the devkit device tree k3-am62x-mitysom-devkit.dts
  • Create the Linux recipe directory. mkdir -p sources/meta-customer/recipes-kernel/linux/linux-cl-ti
  • Copy the device tree
    cp ~/Downloads/k3-am62x-mitysom-devkit.dts sources/meta-customer/recipes-kernel/linux/linux-cl-ti/k3-am62x-mitysom-boardname.dts
    
  • Make a small change to the device tree. In this case, we will add a "fake" clock. We will use this later to verify we booted the correct device tree.
    #include "k3-am62x-mitysom-som.dtsi" 
    
     / {
    +       test_clock: clk-1 {
    +               #clock-cells = <0>;
    +               compatible = "fixed-clock";
    +               clock-frequency = <24576000>;
    +       };
    +
            vcc_12v: vcc_12v {
                    compatible = "regulator-fixed";
                    regulator-name = "vcc_12v";
    
  • Create the cfg fragment file sources/meta-customer/recipes-kernel/linux/linux-cl-ti/ads1015.cfg
    CONFIG_TI_ADS1015=y
    
  • Create the file sources/meta-customer/recipes-kernel/linux/linux-cl-ti_6.1.bbappend with the following source:
    # This will ensure the recipe can find the files you added in the linux-cl-ti directory relative to this bbappend file
    FILESEXTRAPATHS:append := "${THISDIR}/${PN}:" 
    
    # Copy the device tree file into kernel source dir
    SRC_URI:append:mitysom-am62x-boardname = " file://k3-am62x-mitysom-boardname.dts;subdir=git/arch/arm64/boot/dts/ti" 
    # Copies config fragment into $WORKDIR
    SRC_URI:append:mitysom-am62x-boardname = " file://ads1015.cfg" 
    
    KERNEL_CONFIG_FRAGMENTS:append:mitysom-am62x-boardname = " ${WORKDIR}/ads1015.cfg" 
    
    # Add device tree file to Makefile
    do_configure:append:mitysom-am62x-boardname(){
     echo 'dtb-$(CONFIG_ARCH_K3) += k3-am62x-mitysom-boardname.dtb' >> ${S}/arch/arm64/boot/dts/ti/Makefile
     echo 'DTC_FLAGS_k3-am62x-mitysom-boardname += -@' >>  ${S}/arch/arm64/boot/dts/ti/Makefile
    }
    
    # Uncomment if you want to lock down to a specific kernel commit
    #SRCREV:mitysom-am62x-boardname = "6ef35a5b2581fdc753e148556d3a602c7f7d9390" 
    
    # Add mitysom-am62x-boardname to package revision to indicate it has been changed
    PR:append:mitysom-am62x-boardname = "_mitysom-am62x-boardname_0" 
    
  • Build the linux-cl-ti recipe to verify we made no typos and our changes took effect
    bitbake linux-cl-ti
    
  • Inspect the created package file and verify the _mitysom-am62x-boardname_0 got added to the end. We will verify the config changes when we boot the full image in a later section.
    ls /work/build/deploy-ti/images/mitysom-am62x-boardname/ | grep dtb
    k3-am62x-mitysom-boardname--6.1.83+git0+94e12b0ea8-r0b_mitysom-am62x-boardname_0.1-mitysom-am62x-boardname-20240621143044.dtb
    
  • If you have any issues:
    • Verify oe-layersetup/build/arago-tmp-default-glibc/work-shared/mitysom-am62x-boardname/kernel-source/arch/arm64/boot/dts/ti/Makefile has been modified to append lines similar to those listed below. If this is wrong double check the configure section of the bbappend.
      dtb-$(CONFIG_ARCH_K3) += k3-am62x-mitysom-boardname.dtb
      DTC_FLAGS_k3-am62x-mitysom-boardname += -@
      
    • Verify the k3-am62x-mitysom-boardname.dts file has been copied to oe-layersetup/build/arago-tmp-default-glibc/work-shared/mitysom-am62x-boardname/kernel-source/arch/arm64/boot/dts/ti folder. If the file does not appear double check the paths in the bbappend.

Update uEnv.txt to select the device tree

To get u-boot to load the k3-am62x-mitysom-boardname.dtb file instead of the default file name, we can set the correct u-boot environment variables in the uEnv.txt file which gets read at boot. TI provides a recipe sources/meta-arago/meta-arago-distro/recipes-tisdk/tisdk-uenv/tisdk-uenv.bb which provides an empty default uEnv.txt file. We are going to bbappend this recipe to provide our own custom uEnv.txt

  • Create the tisdk-uenv recipe directory. mkdir -p sources/meta-customer/recipes-tisdk/tisdk-uenv/tisdk-uenv
  • Create the file sources/meta-customer/recipes-tisdk/tisdk-uenv/tisdk-uenv/uEnv.txt with the following source:
    # This uEnv.txt file can contain additional environment settings that you
    # want to set in U-Boot at boot time.  This can be simple variables such
    # as the serverip or custom variables.  The format of this file is:
    #    variable=value
    # NOTE: This file will be evaluated after the bootcmd is run and the
    #       bootcmd must be set to load this file if it exists (this is the
    #       default on all newer U-Boot images.  This also means that some
    #       variables such as bootdelay cannot be changed by this file since
    #       it is not evaluated until the bootcmd is run.
    default_device_tree=ti/k3-am62x-mitysom-boardname.dtb
    name_overlays=
    # Add additional arguments to the kernel bootargs
    # Disable audit subsystem to reduce annoying messages on boot
    optargs=audit=0
    
  • Create the file sources/meta-customer/recipes-tisdk/tisdk-uenv/tisdk-uenv.bbappend with the following source:
    # Load the uEnv.txt file from this path instead of the original recipe path
    FILESEXTRAPATHS:prepend:mitysom-am62x-boardname := "${THISDIR}/${PN}:" 
    
    # Add mitysom-am62x-boardname to package revision to indicate it has been changed
    PR:append:mitysom-am62x-boardname = "_mitysom-am62x-boardname_0" 
    
  • Build the tisdk-uenv recipe to verify we made no typos and our changes took effect
    bitbake tisdk-uenv
    
  • Inspect the created package file and verify the _mitysom-am62x-boardname_0 got added to the end. Note in this example there are several layers which are bbappending this recipe and ours got added last.
    ls arago-tmp-default-glibc/deploy/ipk/mitysom-am62x-boardname/tisdk*
    arago-tmp-default-glibc/deploy/ipk/mitysom-am62x-boardname/tisdk-uenv_1.0-r3_tisdk_1_edgeai_0.0_mitysom-am62x-boardname.ipk
    

Create a Custom Image

The filesystem image for your custom board is unlikely to want everything that TI has installed in the tisdk-default-image. To build an image with just the packages required, we are going to create a custom image starting from the tisdk-base-image. If the tisdk base image is still too large, you could start from yocto's core-image or core-image-minimal, though we won't cover that here.

  • Copy tisdk-base-image.bb to meta-customer to create mitysom-am62x-boardname-base-image.bb
    mkdir -p sources/meta-customer/recipes-core/images/
    cp sources/meta-arago/meta-arago-distro/recipes-core/images/tisdk-base-image.bb sources/meta-customer/recipes-core/images/mitysom-am62x-boardname-base-image.bb
    
  • Edit sources/meta-customer/recipes-core/images/mitysom-am62x-boardname-base-image.bb
    • Add path to the arago-image.inc line. require recipes-core/images/arago-image.inc
      require searches the other meta-layers but needs the path to be relative to the top of the meta-layer when the file isn't directly next to the recipe file...
    • Remove the ti-test line and add any packages you will need. Example: Add resize-rootfs which expands the sdcard rootfs partition on first boot to fill the sdcard.
      You can look at meta-arago/meta-arago-distro/recipes-core/images/tisdk-default-image.bb to understand what stuff you might want.
      Note: TI groups a lot of packages into packagegroups which can be found at meta-arago/meta-arago-distro/recipes-core/packagegroups/
    • If you would like an image that runs weston, it may be easier to start with tisdk-default-image and remove things, but doing it this way you are more likely to end up with extra packages than the original approach.
  • Edit sources/meta-customer/62x-build.sh to build mitysom-am62x-boardname-base-image
  • Run the build and see your new image get built. Your image output should be located at build/deploy-ti/images/mitysom-am62x-boardname/

Note: You can look at the .manifest files to easily compare two built filesystem images, to determine what packages were included or missed.

Add a recipe to build your application using recipetool

If your application uses autotools or cmake then the yocto recipe should be pretty simple. In this example, we will create a recipe to build the fbfill tool hosted on our site.

Please read: https://docs.yoctoproject.org/dev-manual/new-recipe.html#writing-a-new-recipe

  • Create a recipes directory to contain your recipes
    mkdir -p sources/meta-customer/recipes-customer/fbfill
    
  • Create the recipe.
    cd build
    recipetool create -o ../sources/meta-customer/recipes-customer/fbfill/fbfill-test_git.bb https://git.criticallink.com/git/fbfill.git
    

    Note: The meta-mitysom layer already has a fbfill recipe, so we name this one fbfill-test to avoid confusion. FYI, Yocto will handle duplicate named recipes by picking the one with the later version number.
  • Build the recipe
    bitbake fbfill-test
    
  • Check in your new recipe into the meta-customer layer
    cd ../sources/meta-customer
    git add recipes-customer/fbfill
    git commit -m 'Add fbfill-test recipe'
    

Checking out your yocto build from scratch

  • Checkout oe-layersetup
    git clone https://support.criticallink.com/git/oe-layersetup.git
    cd oe-layersetup
    
  • Checkout meta-customer
    mkdir sources
    cd sources
    git clone <git_url>
    
  • Run the setup script to setup other meta-layers
    cd ..
    ./docker-poky.sh ./sources/meta-customer/62x-setup.sh
    
  • Run the build
    ./docker-poky.sh ./sources/meta-customer/62x-build.sh
    

Booting the image

Flash an SD card with the mitysom-am62x-boardname-base-image (found in build/deploy-ti/images/mitysom-am62x-boardname). Boot into the am62x som and login with root through the serial console.

Verify the kernel config took place:

zcat /proc/config.gz | grep CONFIG_TI_ADS1015
CONFIG_TI_ADS1015=y

Verify the device tree test clock was added:

find /sys/firmware/devicetree/base/ | grep clk-1     
/sys/firmware/devicetree/base/clk-1

Verify the uEnv.txt was transferred over:

cat /run/media/boot-mmcblk1p1/uEnv.txt

References

Go to top
Add picture from clipboard (Maximum size: 1 GB)