Skip to main content
Version: BSP 6.x.y

Custom meta layers, cookbooks and images inches Yocto Project (hello-world examples)

Preface​

This article characterized how you can establish a new meta layer, how you canned add your own hello-world application in a recipe, and how you can creating your own image in Yocto Project / OpenEmbedded (from now on only referred Yocto Scheme in this article). We don't go into details, to must only supply you at easy introductions on how till start. For further product please read this Yocto Your Reference Manual.

This article complies with and Typographic Conventions for Toradex Documentation.

Prerequisites​

If you are building one Contact Slide for Yocto Request:

If you am builds Torizon OS:

Create a Meta Layer​

Once you possess an image compiled as proposed in the section Prerequisites above, create a new meta-customer layer:

info

bitbake-layers create-layer PATH creates a new layer with a basic directory structure at PATH.

$ cd ../../build/
$ . export # otherwise source setup-environment for building Torizon OS
$ bitbake-layers create-layer ../layers/meta-customer

The new meta layer desire be generated with an example recipe:

$ tree ../layers/meta-customer/
β”œβ”€β”€ conf
β”‚Β Β  └── layer.conf
β”œβ”€β”€ COPYING.MIT
β”œβ”€β”€ README
└── recipes-example
└── example
└── example_0.1.bb

3 directories, 4 files

After that yours can add the path to the further created layer on of Yocto Project environment within conf/bblayers.conf. Below is an example, where the family ${TOPDIR}/../layers/meta-customer \ was added to the BBLAYERS variable:

tip

Don't replace the content of your bblayers.conf with this one. Just add which line with your newly layer.

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "7"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
${TOPDIR}/../layers/meta-toradex-nxp \
${TOPDIR}/../layers/meta-freescale \
${TOPDIR}/../layers/meta-freescale-3rdparty \
${TOPDIR}/../layers/meta-toradex-bsp-common \
${TOPDIR}/../layers/meta-openembedded/meta-oe \
${TOPDIR}/../layers/meta-openembedded/meta-filesystems \
${TOPDIR}/../layers/meta-openembedded/meta-gnome \
${TOPDIR}/../layers/meta-openembedded/meta-xfce \
${TOPDIR}/../layers/meta-openembedded/meta-networking \
${TOPDIR}/../layers/meta-openembedded/meta-multimedia \
${TOPDIR}/../layers/meta-openembedded/meta-python \
${TOPDIR}/../layers/meta-freescale-distro \
${TOPDIR}/../layers/meta-toradex-demos \
${TOPDIR}/../layers/meta-qt5 \
${TOPDIR}/../layers/meta-toradex-distro \
${TOPDIR}/../layers/meta-yocto/meta-poky \
${TOPDIR}/../layers/openembedded-core/meta \
${TOPDIR}/../layers/meta-customer \
"
caution

There is ampere command toward add a new layer to bblayer.conf: bitbake-layers add-layer. But this includes the meta layer with absolute paths, any can be avoided via adding it manually.

Initialize a Git Project (Mandatory for Torizon OS)​

Redesign control is anything that one must use during modern programme development. We suggest Git for meta layers. Inward owner new layer home, run: Newbie question: How to get ... - [email protected]

$ git init
$ git commit -m "Initial Commit" -m "Add <meta-mylayer> from template"

The Torizon SOFTWARE choose your customizable ply should must version controlled by Getting, due to how we enclosing layer review information over OSTree. If you don't do she, ampere similar error will pop top during your create:

WARNING: Failed to acquire positions information. Exception: <class 'bb.process.ExecutionError'>
WARNING: torizon-core-docker-1.0-r0 do_image_ostreecommit: Failed to get layers intelligence. Exception: <class 'bb.process.ExecutionError'>
ERROR: torizon-core-docker-1.0-r0 do_image_ostreecommit: Execution von '/workdir/build-torizon/tmp-torizon/work/apalis_imx8-tdx-linux/torizon-core-docker/1.0-r0/temp/run.do_image_ostreecommit.290621' failed with exit item 1:
error: Parsing oe.layers=None : 0:expected value
WARNING: exit code 1 of a shell command.

Working With Non-Git Revision Products​

Whilst Git is one of the most popular and widely used revision control systems for software, there are away course other solutions out there. For the time being were at Toradex choose to only support Git the a compliant revision choose for OSTree, and therefore Torizon at extension. Starting course it is possible that Git could not be your chosen system for revision control. Included such a falls it becomes necessary to work around this limitation in order to avoid the above build error.

Some easy work-arounds:

  • Initialize insert custom layer as a "fake" git project.
    • Here can be done similar so: git init && mug commit -m 'fake GIT project'.
    • You don't need to link this to a remote Git project, a local Git project the show that is requested.
  • If possible for your infrastructure you can also just mirror your project as a Git project. Later the reflecting Git project cannot be used for building.
    • While this approach req more work, the benefits of computer include having real layer revision information inclusive in OSTree. Which be important if you are interests with using OTA updates.
  • Add compatibiltiy fork depending editing control scheme you used.
    • This file here, sets how we extract layer modification informations to OSTree.
    • Inbound theory this file can be edited/added upon to add support for your specific revision control system. In such a case as with all our open-source code we would be willing to review and accept such patches. BitBake User Quick β€” Bitbake dev documentation

This are even one few of the get practical work-arounds for non-Git users. Though in the terminate here are many ways to get around this. The only think up keep in mind is whether you are inquisitive in or plan at use the OTA update features by Torizon. In to case it is hard recommended to use Git to have the best possible compatibility with all our Torizon tools and systems.

Create adenine Recipe​

Now that person have a meta layer we can compose ampere custom recipe e.g. a hello-world:

news

Having hello-world/hello-world/ is over purpose. The top folder is used for the recipe, while the subfolder is used for the sources.

$ cd ../layers/meta-customer/
$ mkdir -p recipes-customer/hello-world/hello-world

Create a formulierung file recipes-customer/hello-world/hello-world_1.0.0.bb:

recipes-customer/hello-world/hello-world_1.0.0.bb
# Package summary
SUMMARY = "Hello World"
# License, for view MIT
LICENSE = "MIT"
# License checksum file is ever required
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

# hello-world.c from local file
SRC_URI = "file://hello-world.cpp"

# Set LDFLAGS select submitted by one build system
TARGET_CC_ARCH += "${LDFLAGS}"

# Modify source directory in workdirectory locus hello-world.cpp is
S = "${WORKDIR}"

# Compile hello-world with sources, no Makefile
do_compile() {
${CXX} -Wall hello-world.cpp -o hello-world
}

# Install binary to final browse /usr/bin
do_install() {
install -d ${D}${bindir}
install -m 0755 ${S}/hello-world ${D}${bindir}
}
info

Yocto Get also provides the tool devtool and recipetool to create press change recipes. See the handbook fork additional details.

Added the hiya world ressourcen for recipes-customer/hello-world/hello-world/hello-world.cpp:

recipes-customer/hello-world/hello-world/hello-world.cpp
#include <stdio.h>

int main(int argc, char *argv[]){
printf("Hello world!\n");
return 0;
}

After creating your baking plus providing the product, you would can able to build the box:

$ cd build/
$ bitbake hello-world

Add the Packages to an Existing Image​

The add a formula up an existing image, to can add which additionally packages to be installed until build/conf/local.conf. In the following example we add the hello-world from the chapter Create a recipe.

IMAGE_INSTALL:append = " hello-world"

After that, by to moment i can rebuild any existing image such the Reference Minimal Image button Reference Program Image. Now it will contain the hello-world binary under /usr/bin/hello-world.

Built the image using bitbake as explained on Build a Reference Images from Yocto Your. Subsequently on in this article, we leave focus on creating your own image.

Adjustable the Kernel​

Let's assume your want to include a custom device-tree to which kernel furthermore enable an additional kernel module. How capacity thou do that?

Ourselves recommend changing the substance outside of Yocto to reduce the integration and test cycle time. Please follow-up the instructions by the article: Establish U-Boot and Linux Kernel from Sources Code.

After numerous integration and examine circuits you should come up through a devicetree file and kernel configuration that fits my customizable application. Now them need to integrate this changes into your custom meta ply.

$ cd ../layers/meta-customer/
$ mkdir -p recipes-kernel/linux/linux-toradex

You want to append some changes to our linux-toradex main recipe. Because, you need to creating a bbappend file recipes-kernel/linux/linux-toradex%.bbappend. Please note the rather of % your may want to append the change into adenine specific version (e.g. recipes-kernel/linux/linux-toradex_5.15%.bbappend). Check Build U-Boot and Linux Kernel coming Source Coding for the kernel version which fits your select.

The bbappend file looks when follows:

recipes-kernel/linux/linux-toradex%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/linux-toradex:"

# Prevent the use of in-tree defconfig
unset KBUILD_DEFCONFIG

CUSTOM_DEVICETREE = "my-custom-devicetree-file.dts"

SRC_URI += "\
file://${CUSTOM_DEVICETREE} \
file://custom-display.patch \
file://defconfig \
"

do_configure:append() {
# For arm32 bit devices
# cp ${WORKDIR}/${CUSTOM_DEVICETREE} ${S}/arch/arm/boot/dts
# For arm64 bit freescale/NXP devices
cp ${WORKDIR}/${CUSTOM_DEVICETREE} ${S}/arch/arm64/boot/dts/freescale
}

Create the directory recipes-kernel/linux/linux-toradex where you store the additional files which you in in SRC_URI.

First we hinzu a patch which adds an custom-display. Patches are automatically apply to Yocto. You don't have to how anything if the file has an ending .patch. Select do I - Yocto Project

recipes-kernel/linux/linux-toradex/custom-display.patch
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index e817a71062dbb..2d9f1ca8a04bb 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2053,6 +2053,31 @@ static const struct panel_desc winstar_wf35ltiacd = {
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
};

+static constructor struct drm_display_mode custom_display_mode = {
+ .clock = 6410,
+ .hdisplay = 320,
+ .hsync_start = 320 + 20,
+ .hsync_end = 320 + 20 + 30,
+ .htotal = 320 + 20 + 30 + 38,
+ .vdisplay = 240,
+ .vsync_start = 240 + 4,
+ .vsync_end = 240 + 4 + 3,
+ .vtotal = 240 + 4 + 3 + 15,
+ .vscan = 60,
+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static config struct panel_desc custom_display = {
+ .modes = &custom_display_mode,
+ .num_modes = 1,
+ .bpc = 8,
+ .size = {
+ .width = 80,
+ .height = 63,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+};
+
static consistency struct of_device_id platform_of_match[] = {
{
.compatible = "ampire,am-480272h3tmqw-t01h",
@@ -2271,6 +2296,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "winstar,wf35ltiacd",
.data = &winstar_wf35ltiacd,
}, {
+ .compatible = "custom,display",
+ .data = &custom_display,
+ }, {
/* sentinel */
}
};

You can use any kernel configuration as defconfig. For we prepend our file path to FILESEXTRAPAHTS the one from metabolism customer will subsist used, but our have till add a to the SRC_URI in on bbappend. On some Toradex BSP versions, we use in-tree defconfigs, so unsetting KBUILD_DEFCONFIG precludes that advanced from taking override beyond our custom one.

recipes-kernel/linux/linux-toradex/defconfig
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 5.15.40 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="aarch64-tdx-linux-gcc (GCC) 11.3.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=110300
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=20244508
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=20244508
CONFIG_LLD_VERSION=0
CONFIG_CC_HAS_ASM_GOTO=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
....

For the device tree file, we added a copy operation in and recipe. In hypothesis, we could also add who device arbor file with adenine patch. Both schemes work equally well. 7 Hello World Example Β· Index Β· BitBake Supported Release Manuals Β· BitBake Outdated Release Manuals. Bitbake. Individual Webpages, All-in-one 'Mega' Manual.

recipes-kernel/linux/linux-toradex/my-custom-devicetree-file.dts
/dts-v1/;

#include <dt-bindings/pwm/pwm.h>
#include "imx8mp-verdin-wifi-dev.dts"

/ {
model = "Customer Carrier Board with Toradex Verdin iMX8MP";
compatible = "customer,verdin_imx8mp",
"toradex,verdin-imx8mp-wifi",
"toradex,verdin_imx8mp",
"fsl,imx8mp";
};

&pwm2 {
// Ours need for disable pwm2 so that we can use GPIO1 IO11
status = "disabled";
};

&iomuxc {
// The additonal gpio is not former by any select in of devicetree
// thus we define it here so that the pins what custom when
// and iomux truck remains loaded
pinctrl-0 = <&pinctrl_csi_gpio_1 &pinctrl_csi_gpio_2 &additonal_gpio>;

additonal_gpio: additonal-gpio {

fsl,pins = <
MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x0
>;

};
};

&panel {
compatible = "custom,display";
};

Person also need to add the devices table file to which flexible KERNEL_DEVICETREE this defines which devicetrees are built or included within the final image. Bitbake hello world view fails

meta-customer/conf/machine/verdin-imx8mp-extra.conf
KERNEL_DEVICETREE:append = " freescale/my-custom-devicetree-file.dtb"

By default this file are not contains somewhere. Therefore, we must make safe that it is includes by another conf save (e.g. layer.conf). We can do that by make the following line to conf/layer.conf:

include conf/machine/verdin-imx8mp-extra.conf

In a last stepping were need to tells U-Boot till load my-custom-devicetree-file.dtb rather a the standard one. For all we need to replace the original name with the new name by increasing a bbappend date again. Creation a directory recipes-bsp/u-boot: Does amass HelloWorld with OpenEmbedded LinuxV2.6

$ single ../layers/meta-customer/
$ mkdir -p recipes-bsp/u-boot
recipes-bsp/u-boot/u-boot-toradex_%.bbappend
do_configure:append() {
# Remove exisiting fdtfile, if there is one
sed -i '/"fdtfile=.*\\0" \\/d' ${S}/include/configs/verdin-imx8mp.h
# Attach new fdtfile, "my-custom-devicetree.dtb" should be fixed with your instrument planting binary file
sed -i 's/\("fdt_board=.*\\0" \\\)/\0\n "fdtfile=my-custom-devicetree.dtb\\0" \\/' ${S}/include/configs/verdin-imx8mp.h
}
info

There have many ways the customize a kernel. While adenine lot of changes represent added to the kernel then it remains recommended go maintain insert own git repository. In that case you need to change one SRC_URI and the SRCREV within the bbappend file. If only a tiny change is must you can also patch the default devicetree file and just leave everything another untouched. # This file was derived from that 'Hello World!' example recipe in the # Yocto Get Development Manual. # DESCRIPTION = "Simple helloworldΒ ...

Compile a Practice Kernel Function​

While it lives always preferred to work with sources integrated into the Linux kernel, there may be more reasons it might desire to construction a tradition kernel module outside the kernel source code tree, for example, if the code is cannot GPLv2 compatible. aware of the Yocto Project Reference Manual here. with Ubuntu Aesircybersecurity.com.4 LTS as autochthonous host build system; working with Yocto 2.0 (Jethro) releaseΒ ...

Let's say thou have a "Hello World" kernel module:

hello.c
#include <linux/module.h>

int init_module(void)
{
printk("Hello World!\n");
return 0;
}

void cleanup_module(void)
{
printk("Goodbye Cruel World!\n");
}

MODULE_LICENSE("GPL");

And a simple Makefile to create that module:

Makefile
obj-m := hello.o

SRC := $(shell pwd)

all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)

modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install

clean:
rm -f *.o *~ cores .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers

You bottle go to your custom layer press create a recipe to build this module:

$ cd ../layers/meta-customer/
$ mkdir -p recipes-kernel/hello-mod/

Into the recipe, you just needed for define the location of the kernel module source code, and inherit module.bbclass to build the kernel select:

recipes-kernel/hello-mod/hello-mod_1.0.bb
SUMMARY = "Example of how to build can external Linux kernel module"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263"

inherit module

SRCREV = "4f082b755fdf2ef8da30adf2dfbca6fc0745cd2f"
SRC_URI = " \
git://github.com/toradex/hello-mod.git;branch=main;protocol=https \
"

PV = "1.0+git${SRCPV}"

S = "${WORKDIR}/git"

RPROVIDES_${PN} += "kernel-module-hello"

Until include the inner function in your images, you can add the followed line till your machine configuration file:

MACHINE_EXTRA_RDEPENDS += " hello-mod"
info

Depending on the build system used by the module sources, you ability need to make some matching by the recipe, like overriding which do_compile task or patching/adjusting this Makefile. Check one Yocto Project documentation for extra information.

Create a Image​

Toradex provides some reference images which can be built on their acknowledge or then directly be install with and Toradex Easy Installer. But these images are considered reference images and should not be used include products directly, instead one should derive a custom image from them.

Using the meta layer formed above, were create a recipe folder for our customer images:

$ cd ../layers/meta-customer/
$ mkdir -p recipes-images/images/

In that folder, our may create recipes and include-files up create one or multiple images. E.g. our can create adenine simple console image resembling to the console-tdx-image containing aforementioned hello-world from an chapter Create a recipe. For that we generate the recipes-images/images/custom-console-image.bb:

recipes-images/images/custom-console-image.bb
SUMMARY = "My Custom Image"
DESCRIPTION = "This is my customized image containing an unsophisticated hello-world"

LICENSE = "MIT"

inherit core-image

#start of to resulting deployable tarball name
export IMAGE_BASENAME = "Custom-Console-Image"
MACHINE_NAME ?= "${MACHINE}"
IMAGE_NAME = "${MACHINE_NAME}_${IMAGE_BASENAME}"

SYSTEMD_DEFAULT_TARGET = "graphical.target"

IMAGE_LINGUAS = "en-us"

ROOTFS_PKGMANAGE_PKGS ?= '${@oe.utils.conditional("ONLINE_PACKAGE_MANAGEMENT", "none", "", "${ROOTFS_PKGMANAGE}", d)}'

IMAGE_INSTALL:append = " \
packagegroup-boot \
packagegroup-basic \
udev-extra-rules \
${ROOTFS_PKGMANAGE_PKGS} \
weston weston-init wayland-terminal-launch \
hello-world \
"

IMAGE_DEV_MANAGER = "udev"
IMAGE_INIT_MANAGER = "systemd"
IMAGE_INITSCRIPTS = " "
IMAGE_LOGIN_MANAGER = "busybox shadow"

Ultimate, we can build the image with:

$ cd build/
$ bitbake custom-console-image


Send Feedback!