Customizing Guide¶
Note
There is no need at all to modify any existing files in the Yocto source directory to customize the BSP for your own hardware. Instead, you should create a separate layer for your customizations where you can augment or override the original recipes.
This guide provides step-by-step instructions for customizing your Ka-Ro Board Support Package (BSP). You will learn how to:
Create and set up a custom Yocto layer
Customize U-Boot (
u-boot-karorecipe) including bootloader configuration, device trees, and environmentCustomize the Linux kernel (
linux-karorecipe) and device treesCreate custom images and extend them using WIC
Use devtool for efficient development workflows
For comprehensive information beyond this guide, refer to the official Yocto Project Documentation. The Yocto Development Manual and Board Support Package (BSP) Guide are particularly relevant for advanced customizations.
Hint
All commands listed below are examples and must be adapted to your specific use case.
Getting Started: Creating Your Custom Layer¶
Before making any customizations, create a dedicated layer for your changes. This keeps your modifications separate from the BSP source and makes updates easier.
Note
Create your own DISTRO configuration based on one of the
provided DISTRO configurations from our BSP layer. Prefix your DISTRO
name with a unique identifier (e.g., mycompany-mydistro) and name your
layer directory accordingly (e.g., meta-mycompany).
Layer Structure:
Your custom layer directory should have the following structure:
${BSPDIR}/sources/meta-mycompany/
├── conf/
│ └── layer.conf # Layer configuration (required)
├── COPYING.MIT # License file (recommended)
├── README # Layer description (recommended)
└── recipes-.../ # Your custom recipes and modifications
Setting Up Your Layer:
Create your layer directory structure
Create a minimal
conf/layer.conffile:1# We have a conf and classes directory, add to BBPATH 2BBPATH .= ":${LAYERDIR}" 3 4# We have recipes-* directories, add to BBFILES 5BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend" 6 7BBFILE_COLLECTIONS += "mycompany" 8BBFILE_PATTERN_my-layer = "^${LAYERDIR}/" 9BBFILE_PRIORITY_my-layer = "10"
Add your layer to
conf/bblayers.conf:1BBLAYERS += " \ 2 ${BUILDDIR}/../sources/meta-mycompany \ 3"
For more details on layer creation, see the Yocto documentation on Creating Your Own Layer.
Customizing a Recipe¶
The devtool command provides a streamlined workflow for modifying recipes, their source code,
and configuration. This is particularly useful during development and testing.
Basic devtool workflow:
Modify a recipe to create a workspace:
devtool modify <recipe>This extracts the recipe’s source and creates a workspace directory (default:
${BUILDDIR}/workspace/).Make your changes in the workspace (source code, configuration files, etc.)
Build and Test your changes:
devtool build <recipe>Apply changes to your layer:
devtool update-recipe <recipe> <layer>This applies your workspace changes to the specified layer, creating the necessary patches and/or bbappend files.
Close the workspace:
devtool reset <recipe>This closes the workspace, discarding any uncommitted changes.
For more information, see the Yocto documentation on devtool.
Creating your own baseboard settings¶
It will most probably be desirable to add your own baseboard
setting to the yocto environment. The following steps are necessary to
achieve this (replace ‘mybaseboard’ in the subsequent statements with your
own boardname):
Register your baseboard by extending the
KARO_BASEBOARDSvariable in your machine configuration. Create a machine configuration file in your layer that requires our module’s configuration, for example:meta-mycompany/ └── conf/ └── machine/ └── module-mycompany.confwith the following content:
1require module.conf 2 3KARO_BASEBOARDS += "mybaseboard" 4 5KARO_DTB_OVERLAYS[mybaseboard] = " \ 6 ... \ 7"
Select your baseboard by adding
KARO_BASEBOARD = "mybaseboard"
to your conf/local.conf
For more details on how to add your own baseboard setting, see Adding overlays for a custom baseboard.
Customizing U-Boot (u-boot-karo)¶
Our BSP uses the u-boot-karo recipe for U-Boot. You can customize various aspects including
configuration, device tree blobs (DTBs), and the default environment.
Creating a U-Boot bbappend File:
To customize U-Boot, create a .bbappend file in your custom layer. The file should
be placed in a directory structure that mirrors the original recipe location:
meta-mycompany/
└── recipes-bsp/
└── u-boot/
└── u-boot-karo_%.bbappend
The % wildcard allows the bbappend to match any version of the u-boot-karo recipe.
Basic bbappend Example:
1FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:
This allows you to override or add files that U-Boot uses.
Modifications:
U-Boot can be customized by using devtool to open a workspace where you can modify
source code and configuration with automatic patch generation (see devtool workflow above).
Note
Configuration changes applied through devtool may require manual adjustments to match your
machine’s specific configuration requirements.
The u-boot-karo recipe contains special tasks that allow you to change configuration, device tree files, and environment files directly without opening a devtool workspace. These customizations are organized in subdirectories under your recipe directory:
meta-mycompany/
└── recipes-bsp/
└── u-boot/
├── u-boot-karo/
│ ├── cfg/ # Configuration fragments
| ├── defconfigs/ # Defconfig files
│ ├── dts/ # Device tree source files
│ └── env/ # Environment files
└── u-boot-karo_%.bbappend
To ensure your custom files are found, add the following to your bbappend file:
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/env:${THISDIR}/${PN}/cfg:${THISDIR}/${PN}/defconfigs:"
Note
The dts directory is intentionally omitted in FILESEXTRAPATHS because the U-Boot source
expects device tree files in a specific location.
The following subchapters explain how to use these directories.
Customizing U-Boot Configuration¶
The u-boot-karo recipe supports changing configuration directly through bbappend files without modifying the source. Place your configuration files in the appropriate subdirectories:
Adding a custom config fragments:
Add configuration fragments to the
cfg/directory:meta-mycompany/ └── recipes-bsp/ └── u-boot/ └── u-boot-karo/ └── cfg/ └── some-feature.cfgThe fragment file contains only the configuration options you want to add or change:
1CONFIG_MY_FEATURE=y 2CONFIG_ANOTHER_OPTION=n
Add your feature in your bbappend file:
UBOOT_FEATURES:append = " some-feature"
The fragment file is automatically picked up by the u-boot-karo recipe through the UBOOT_FEATURES variable.
Note
The U-Boot configuration can also be altered by adding a defconfig. For more insight and options, look into the u-boot-karo recipe in our layer and our BSP documentation.
Adding a Custom Device Tree Blob (DTB)¶
The u-boot-karo recipe supports adding custom device tree blobs directly through bbappend files
without modifying the source. Device tree selection is controlled by the KARO_BASEBOARD variable.
This requires you to register your own baseboard (see Register your baseboard above).
Note
Check the u-boot-karo recipe in our BSP layer for naming requirements and examples
specific to your module.
Create your device tree source file (e.g.
mybaseboard.dts) in thedts/directory of your layer:meta-mycompany/ └── recipes-bsp/ └── u-boot/ └── u-boot-karo/ └── dts/ └── mybaseboard.dtsAdd the file to your bbappend:
SRC_URI += "file://dts/mybaseboard.dts;subdir=git/arch/arm"
Select your baseboard by setting
KARO_BASEBOARDto “mybaseboard”. The u-boot-karo recipe will automatically pick up and compile your device tree.
For more details on device trees, refer to the Yocto Device Tree Manual.
Customizing the U-Boot Default Environment¶
The u-boot-karo recipe supports customizing the default environment directly through bbappend files
without modifying the sources. Environment file selection is controlled by the KARO_BASEBOARD variable.
This requires you to register your own baseboard (see Register your baseboard above).
Note
Check the u-boot-karo recipe in our BSP layer for naming requirements and examples
specific to your module.
Create your environment file based on the default envrionment file of our module for your specific module and baseboard in the
env/directory:meta-mycompany/ └── recipes-bsp/ └── u-boot/ └── u-boot-karo/ └── env/ └── module-mybaseboard.envSelect your baseboard by setting
KARO_BASEBOARDto “mybaseboard”. The u-boot-karo recipe will automatically pick up and use your envrionment file.
For information on U-Boot environment syntax, see the U-Boot Environment documentation.
Customizing the Linux Kernel (linux-karo)¶
Our BSP uses the linux-karo recipe for the Linux kernel. You can customize it in various ways,
from configuration changes to adding patches and custom device tree blobs.
Creating a Linux bbappend File:
To customize Linux, create a .bbappend file in your custom layer. The file should
be placed in a directory structure that mirrors the original recipe location:
meta-mycompany/
└── recipes-kernel/
└── linux/
└── linux-karo_%.bbappend
The % wildcard allows the bbappend to match any version of the linux-karo recipe.
Basic bbappend Example:
1FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:
This allows you to override or add files that the recipe uses.
Modifications:
Linux can be customized by using devtool to open a workspace where you can modify
source code and configuration with automatic patch generation (see devtool workflow above).
Note
Configuration changes applied through devtool may require manual adjustments to match your
machine’s specific configuration requirements.
The linux-karo recipe contains special tasks that allow you to change configuration and device tree files directly without opening a devtool workspace. These customizations are organized in subdirectories under your recipe directory:
meta-mycompany/
└── recipes-kernel/
└── linux/
├── linux-karo/
│ ├── cfg/ # Configuration fragments
| ├── defconfigs/ # Defconfig files
│ └── dts/ # Device tree source files
└── linux-karo_%.bbappend
To ensure your custom files are found, add the following to your bbappend file:
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}/cfg:${THISDIR}/${PN}/defconfigs:"
Note
The dts directory is intentionally omitted in FILESEXTRAPATHS because the Linux Kernel source
expects device tree files in a specific location.
The following subchapters explain how to use these directories.
Customizing Linux Kernel Configuration¶
The linux-karo recipe supports changing configuration directly through bbappend files without modifying the source. Place your configuration files in the appropriate subdirectories:
Adding a custom defconfig:
meta-mycompany/ └── recipes-kernel/ └── linux/ └── linux-karo/ └── defconfigs/ └── my-custom-defconfigSelect your custom defconfig file in your bbappend file:
# Use your custom defconfig for your machine KBUILD_DEFCONFIG = "my-custom-defconfig"
The defconfig file is automatically picked up and used by the linux-karo recipe.
Note
The custom defconfig can also be augmented by config fragments from the BSP layer
selectable via the KERNEL_FEATURES variable. For more insight and options,
look into the linux-karo recipe in our layer and our BSP documentation.
Adding a Custom Device Tree Blobs (DTB)¶
The linux-karo recipe supports adding custom device trees directly through bbappend files without
modifying the source. Device tree selection is controlled by the KARO_BASEBOARD variable.
This requires you to register your own baseboard (see Register your baseboard above).
Note
Check the linux-karo recipe in our BSP layer for naming requirements and examples
specific to your module.
Create your device tree source file in the appropriate directory:
meta-mycompany/ └── recipes-kernel/ └── linux/ └── linux-karo/ └── dts/ └── <vendor>/ └── <soc-family>-<machine>-mybaseboard.dtsAdd the file to your bbappend file:
# Add the device tree source SRC_URI:append = " \ file://dts/<vendor>/<soc-family>-<machine>-mybaseboard.dts;subdir=git/${KERNEL_OUTPUT_DIR} \ "Select your baseboard by setting
KARO_BASEBOARDto “mybaseboard”. The linux-karo recipe will automatically pick up and compile your device tree.
For more details on device trees, refer to the Yocto Device Tree Manual.
Creating Custom Images¶
Our BSP mainly provides two image recipes: karo-image-minimal and karo-image-weston. Each uses WIC as the only IMAGE_FSTYPE, producing partitioned disk images with boot, rootfs, and userfs (/usr/local) by default.
For more details on WIC, refer to the Yocto WIC Guide.
Basic Custom Image¶
To extend karo-image-minimal:
Create your own mycompany-image-minimal.bb in your layer (e.g. under recipes-mycompany/images/):
SUMMARY = "My custom image"
LICENSE = "MIT"
require recipes-karo/images/karo-image-minimal.bb
IMAGE_INSTALL:append = " python3-pip htop"
Build with bitbake mycompany-image-minimal.
Custom Partition Layout¶
Default WKS structure:
part /boot --source karo-rootfs --rootfs-dir=${IMAGE_ROOTFS}/boot \
--ondisk mmcblk0 --fstype=ext4 --label boot --use-label \
--fsoptions noauto --active --align 1024 --fixed-size ${BOOTFS_PARTITION_SIZE}k
part / --source karo-rootfs --ondisk mmcblk0 --fstype=ext4 \
--label rootfs --use-label --align 1024 \
--fixed-size ${ROOTFS_PARTITION_SIZE}k --exclude-path boot/ usr/local/
part /usr/local --source karo-rootfs --rootfs-dir=${IMAGE_ROOTFS}/usr/local \
--ondisk mmcblk0 --fstype=ext4 --label userfs --use-label \
--fsoptions noauto --align 1024 --fixed-size ${USERFS_PARTITION_SIZE}k
bootloader --ptable gpt
To add a partition (e.g., /config):
Create your own WKS file based on our default WKS structure
Add or remove partitions at your discretion
Include/exclude paths from the main partition (rootfs) with
--exclude-pathSet
WKS_FILEin your image recipe
Example WKS addition:
part /config --source karo-rootfs --rootfs-dir=${IMAGE_ROOTFS}/config \
--ondisk mmcblk0 --fstype=ext4 --label config --use-label \
--fsoptions noauto --align 1024 --fixed-size 262144k
Partition Export¶
Our image recipe exports partitions which use the karo-rootfs source via WIC_PARTITIONS_EXPORT (default: "boot rootfs userfs"). Set in your recipe or local.conf:
WIC_PARTITIONS_EXPORT = "boot rootfs userfs config"
Output per partition: <image>-<machine>.<partition>.ext4 and <image>-<machine>.<partition>.tar.bz2.