Table of Contents

Yocto Project Customization Guide for TQ Systems Modules

Introduction

This guide provides instructions on how to customize U-Boot and the Linux kernel within the Yocto Project build system. It also covers creating patches and simple BitBake recipes. This is essential for adapting the system to specific hardware or software requirements for your TQ modules.

We assume you have a working Yocto Project build environment set up and are familiar with basic BitBake commands. For TQ-specific layers, please refer to our official repositories:

Prerequisites

Required Tools and Setup

Before you begin, ensure you have:

  • A configured Yocto Project build environment for your target TQ module.
  • The `devtool` utility, which is part of Yocto Project (often included in `poky/scripts` and added to `PATH` when sourcing the build environment script like `oe-init-build-env`).
  • Your TQ-specific meta-layer (e.g., `meta-tq`) added to your `bblayers.conf` file.

Source your build environment:

source poky/oe-init-build-env <build-directory>

1. Customizing U-Boot

Modifying U-Boot

U-Boot (Das U-Boot Universal Boot Loader) is often the first piece of software that runs on your embedded device. Customizations might include changing boot commands, enabling/disabling drivers, or adjusting hardware initialization.

1.1. Setting up the U-Boot Source for Development

To modify U-Boot, use `devtool` to extract and prepare the source code. Replace `u-boot-tq` (or the specific U-Boot recipe name for your platform, often found in `meta-tq`) if it differs. You can find the recipe name by looking into your machine configuration file or by searching in your layers.

devtool modify u-boot-tq

This command will:

  • Fetch the U-Boot source code.
  • Unpack it into your `<build-directory>/workspace/sources/u-boot-tq`.
  • Create a new Git repository there for your changes.
  • Create an append file (`.bbappend`) in your workspace layer to point the build system to this local source.

1.2. Making Changes to U-Boot

Navigate to the U-Boot source directory:

cd <build-directory>/workspace/sources/u-boot-tq

You can now make your changes. Common modifications include:

  • Environment Variables: Edit files like `include/configs/<your-board-name>.h` or `env/common.c`.
  • Board Configuration: Modify `configs/<your-board-defconfig>` or related board files in `board/tq/<your-board>/`.
  • Device Tree: For U-Boot specific device tree files (if used), these are typically in `arch/<arch>/dts/`.

After making your changes, commit them using Git:

git add <changed-files>
git commit -m "My U-Boot customization: <brief description>"

1.3. Building and Testing U-Boot

Build U-Boot with your changes:

bitbake u-boot-tq

Or, if you want to build only U-Boot and deploy it to your image for faster testing (this might skip some image generation steps):

devtool build u-boot-tq

Then, deploy the image containing your U-Boot to your target hardware and test thoroughly. The resulting U-Boot binary (e.g., `u-boot.imx`, `u-boot.bin`, `u-boot.img` depending on the platform) will be in `<build-directory>/tmp/deploy/images/<your-machine>/`.

1.4. Creating a Patch for U-Boot

Once you are satisfied with your changes, create a patch. Ensure you are in the U-Boot source directory (`<build-directory>/workspace/sources/u-boot-tq`).

If you have one commit:

git format-patch -1 -o <path-to-your-meta-layer>/recipes-bsp/u-boot/files/

If you have multiple commits, you might want to squash them or create multiple patches:

git format-patch HEAD~N -o <path-to-your-meta-layer>/recipes-bsp/u-boot/files/

(Replace `N` with the number of commits).

Name your patch descriptively, e.g., `0001-my-custom-u-boot-feature.patch`.

1.5. Updating the U-Boot Recipe

Create or edit the U-Boot append file (`.bbappend`) in your custom layer. This is typically located at `<your-meta-layer>/recipes-bsp/u-boot/u-boot-tq_%.bbappend` or a similar path.

Add your patch to `SRC_URI`:

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 
SRC_URI += " \
    file://0001-my-custom-u-boot-feature.patch \
"

2. Customizing the Linux Kernel

Modifying the Linux Kernel

Kernel customization allows you to change device drivers, enable kernel features, modify the device tree, and more.

2.1. Setting up the Kernel Source for Development

Use `devtool` to prepare the kernel source. The recipe name is usually `virtual/kernel`.

devtool modify virtual/kernel

This command works similarly to the U-Boot one:

  • Fetches the kernel source code.
  • Unpacks it into `<build-directory>/workspace/sources/linux`. (The directory name might vary, e.g., `linux-imx`, `linux-yocto`).
  • Creates a Git repository for your changes.
  • Creates an append file in your workspace layer.

2.2. Making Changes to the Kernel

Navigate to the kernel source directory:

cd <build-directory>/workspace/sources/linux

Common kernel modifications:

  • Kernel Configuration:

To change kernel configuration options (`.config`), use `menuconfig`:

  <code bash>
  bitbake virtual/kernel -c menuconfig
  </code>
  Or, using `devtool`:
  <code bash>
  devtool menuconfig virtual/kernel
  </code>
  Save your changes. This will typically create a `defconfig` file or a configuration fragment.
  • Device Tree Files (.dts, .dtsi):

These are usually located in `arch/<your-arch>/boot/dts/`. For TQ modules, you might find them under a vendor-specific path (e.g., `arch/arm64/boot/dts/freescale/` for NXP i.MX based modules or `arch/arm64/boot/dts/st/` for STM32MP1 based modules). Edit the relevant device tree source file for your board.

  • Driver Code: Modify existing drivers or add new ones in the `drivers/` directory.

Commit your changes using Git:

git add <changed-files-or-defconfig>
git commit -m "My kernel customization: <brief description>"

2.3. Building and Testing the Kernel

Build the kernel with your changes:

bitbake virtual/kernel

Or:

devtool build virtual/kernel

The kernel image (e.g., `zImage`, `uImage`, `Image`) and device tree blobs (`.dtb`) will be in `<build-directory>/tmp/deploy/images/<your-machine>/`. Deploy and test on your hardware.

2.4. Creating a Kernel Patch

In the kernel source directory (`<build-directory>/workspace/sources/linux`):

  • For code changes (drivers, dts):
    git format-patch HEAD~N -o <path-to-your-meta-layer>/recipes-kernel/linux/files/
 
  (Replace `N` with the number of commits). Name it descriptively, e.g., `0001-my-kernel-driver-fix.patch`.
  • For kernel configuration changes:

After running `menuconfig` and saving, `devtool` often helps manage configuration fragments. Alternatively, you can generate a configuration fragment:

  <code bash>
  bitbake virtual/kernel -c savedefconfig
  </code>
  This will create a `defconfig` file in `<build-directory>/tmp/work/<your-machine>-poky-linux-gnueabi/linux-yocto/<kernel-version>/linux-<your-machine>-standard-build/`. Rename this to something like `my_custom_config.cfg` and copy it to your layer: `<path-to-your-meta-layer>/recipes-kernel/linux/files/`.

2.5. Updating the Kernel Recipe

Create or edit the kernel append file (`.bbappend`) in your layer. This is often `<your-meta-layer>/recipes-kernel/linux/linux-yocto_%.bbappend` or specific to the kernel version/type (e.g., `linux-imx_%.bbappend`).

Add your patch(es) and/or configuration fragment to `SRC_URI`:

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 
SRC_URI += " \
    file://0001-my-kernel-driver-fix.patch \
    file://my_custom_config.cfg \
"

3. Creating Patches and Simple Recipes

Patches and Basic Recipes

3.1. General Patch Creation

The process described for U-Boot and Kernel (using `git format-patch`) is the standard way to create patches for any software component modified via `devtool modify <recipe-name>`.

Key steps:

1. `devtool modify <recipe-name>`
2. Make changes in `<build-directory>/workspace/sources/<recipe-name>`
3. Commit changes with `git`.
4. Generate patch(es) with `git format-patch`.
5. Copy patch(es) to your layer, typically under `<your-meta-layer>/<category>/<recipe-name>/files/`.
6. Add `file://<patch-name>.patch` to `SRC_URI` in the recipe's `.bbappend` file.
7. `devtool reset <recipe-name>`

3.2. Creating a Simple Recipe

Let's say you want to add a custom script or a small, pre-compiled binary to your image.

3.2.1. Recipe File Structure

Create a directory structure in your meta-layer:

<your-meta-layer>/
  recipes-custom/
    my-custom-app/
      files/
        my_script.sh  # Your script or binary
      my-custom-app_0.1.bb # Your recipe file

3.2.2. Example: Recipe for a Shell Script

1. Create your script: `<your-meta-layer>/recipes-custom/my-custom-app/files/my_script.sh`

#!/bin/sh
echo "Hello from TQ Custom App!"

Make sure it's executable: `chmod +x my_script.sh`.

2. Create the recipe file: `<your-meta-layer>/recipes-custom/my-custom-app/my-custom-app_0.1.bb`

SUMMARY = "My Custom Application"
DESCRIPTION = "A simple shell script example for TQ."
LICENSE = "MIT" # Or your preferred license
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 
# Point to the files directory within this recipe
SRC_URI = "file://my_script.sh"
 
# Source directory (where files from SRC_URI are unpacked)
S = "${WORKDIR}"
 
# Installation: Copy the script to /usr/bin in the target image
do_install() {
    install -d ${D}${bindir}
    install -m 0755 ${S}/my_script.sh ${D}${bindir}/
}
 
# If you have other files, like service files for systemd:
# SRC_URI += " file://my-custom-app.service"
# FILES_${PN} += "${systemd_system_unitdir}/my-custom-app.service"
# SYSTEMD_SERVICE_${PN} = "my-custom-app.service" (if it's a systemd service)