Skip to main content

Getting started

Getting started with Embedded Linux and Yocto project - building for vexpress-a9 target complete with u-boot bootloader and sdcard emulation

2021

Getting started

CodenameYocto Project VersionRelease DateCurrent VersionSupport LevelPoky VersionBitBake branch
Kirkstone3.5April 2022Future - Long Term Support (until Apr. 2024)27.0
Honister3.4October 20213.4.2 (February 2022)Support for 7 months (until May 2022)26.01.52
Hardknott3.3April 20213.3.4 (Nov 2021)Stable - Support for 11 (was 7) months (until Mar. 2022)25.01.50
Gatesgarth3.2Oct 20203.2.4 (May 2021)EOL24.01.48
Dunfell3.1April 20203.1.14 (February 2022)Long Term Support (until Apr. 2024)23.01.46
  • build-appliance-image: An example virtual machine that contains all the pieces required to run builds using the build system as well as the build system itself. You can boot and run the image using either the VMware Player or VMware Workstation. For more information on this image, see the Build Appliance page on the Yocto Project website.
  • core-image-base: A console-only image that fully supports the target device hardware.
  • core-image-full-cmdline: A console-only image with more full-featured Linux system functionality installed.
  • core-image-lsb: An image that conforms to the Linux Standard Base (LSB) specification. This image requires a distribution configuration that enables LSB compliance (e.g. poky-lsb). If you build core-image-lsb without that configuration, the image will not be LSB-compliant.
  • core-image-lsb-dev: A core-image-lsb image that is suitable for development work using the host. The image includes headers and libraries you can use in a host development environment. This image requires a distribution configuration that enables LSB compliance (e.g. poky-lsb). If you build core-image-lsb-dev without that configuration, the image will not be LSB-compliant.
  • core-image-lsb-sdk: A core-image-lsb that includes everything in the cross-toolchain but also includes development headers and libraries to form a complete standalone SDK. This image requires a distribution configuration that enables LSB compliance (e.g. poky-lsb). If you build core-image-lsb-sdk without that configuration, the image will not be LSB-compliant. This image is suitable for development using the target.
  • core-image-minimal: A small image just capable of allowing a device to boot.
  • core-image-minimal-dev: A core-image-minimal image suitable for development work using the host. The image includes headers and libraries you can use in a host development environment.
  • core-image-minimal-initramfs: A core-image-minimal image that has the Minimal RAM-based Initial Root Filesystem (initramfs) as part of the kernel, which allows the system to find the first “init” program more efficiently. See the PACKAGE_INSTALL variable for additional information helpful when working with initramfs images.
  • core-image-minimal-mtdutils: A core-image-minimal image that has support for the Minimal MTD Utilities, which let the user interact with the MTD subsystem in the kernel to perform operations on flash devices.
  • core-image-rt: A core-image-minimal image plus a real-time test suite and tools appropriate for real-time use.
  • core-image-rt-sdk: A core-image-rt image that includes everything in the cross-toolchain. The image also includes development headers and libraries to form a complete stand-alone SDK and is suitable for development using the target.
  • core-image-sato: An image with Sato support, a mobile environment and visual style that works well with mobile devices. The image supports X11 with a Sato theme and applications such as a terminal, editor, file manager, media player, and so forth.
  • core-image-sato-dev: A core-image-sato image suitable for development using the host. The image includes libraries needed to build applications on the device itself, testing and profiling tools, and debug symbols. This image was formerly core-image-sdk.
  • core-image-sato-sdk: A core-image-sato image that includes everything in the cross-toolchain. The image also includes development headers and libraries to form a complete standalone SDK and is suitable for development using the target.
  • core-image-testmaster: A “controller” image designed to be used for automated runtime testing. Provides a “known good” image that is deployed to a separate partition so that you can boot into it and use it to deploy a second image to be tested. You can find more information about runtime testing in the “Performing Automated Runtime Testing” section in the Yocto Project Development Tasks Manual.
  • core-image-testmaster-initramfs: A RAM-based Initial Root Filesystem (initramfs) image tailored for use with the core-image-testmaster image.
  • core-image-weston: A very basic Wayland image with a terminal. This image provides the Wayland protocol libraries and the reference Weston compositor. For more information, see the “Using Wayland and Weston” section in the Yocto Project Development Tasks Manual.
  • core-image-x11: A very basic X11 image with a terminal.

Installing required packages to run yocto

# Installing required packages to run yocto
sudo apt install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev

# >= 3.4
sudo apt install zstd

Downloading Poky

git clone git://git.yoctoproject.org/poky

cd poky

git branch -a

# LTS 2020
git checkout tags/yocto-3.1.4 -b yocto-3.1.4-local

git checkout tags/yocto-3.1.14 -b yocto-3.1.14-local

# or Stable 2021, kernel >= 5.14, not work (?)
git checkout tags/yocto-3.3.4 -b yocto-3.3.4-local

git checkout tags/yocto-3.4.2 -b yocto-3.4.2-local

git branch

Building sample image for virt target

# Initialize the Build Environment
source oe-init-build-env build-virt

vi conf/local.conf

MACHINE ?= "qemuarm"

# build process took about N hours
bitbake core-image-minimal

# output images in dir:
# /build-virt/tmp/deploy/images/qemuarm/

# Run the image on qemu
runqemu qemuarm nographic

Building for vexpress-a9

# In poky directory clone the layer
git clone https://github.com/OverC/meta-qemuarma9.git

# Run again if `bitbake: command not found`
source oe-init-build-env build-vexpressa9

# If not work
vi ../meta-qemuarma9/conf/layer.conf

LAYERSERIES_COMPAT_qemuarma9 = "dunfell gatesgarth hardknott honister kirkstone"

# >= 3.4
vi ../meta-qemuarma9/conf/machine

require conf/machine/include/arm/armv7a/tune-cortexa9.inc

bitbake-layers add-layer ../meta-qemuarma9/

cat conf/bblayers.conf

BBLAYERS ?= " \
/hdd/poky/meta \
/hdd/poky/meta-poky \
/hdd/poky/meta-yocto-bsp \
/hdd/poky/meta-qemuarma9 \
"

vi conf/local.conf

MACHINE ?= "qemuarma9"

/meta-qemuarma9 ...pes-kernel/linux/linux-yocto-dev.bbappend → recipes-kernel/linux/linux-yocto_%.bbappend

# v5.14/standard/arm-versatile-926ejs

# WR qemuarma9 configuration, not supported in Yocto
KBRANCH_qemuarma9 ?= "v5.4/standard/arm-versatile-926ejs"
KMACHINE_qemuarma9 ?= "qemuarma9"
KERNEL_DEVICETREE_qemuarma9 = "vexpress-v2p-ca9.dtb"
COMPATIBLE_MACHINE_qemuarma9 = "qemuarma9"



# Delete linux-yocto_5.2.bbappend and linux-yocto_4.8.bbappend

# If any error because of fetching, try again & again
bitbake core-image-minimal

# Resize for SD Card
qemu-img resize tmp/deploy/images/qemuarma9/core-image-minimal-qemuarma9-20220222090323.rootfs.ext4 4G

qemu-img resize tmp/deploy/images/qemuarma9/core-image-minimal-qemuarma9-20220226121058.rootfs.ext4 4G

# Reach a `end Kernel panic` of course since we didn't attach a root filesystem.
qemu-system-arm -machine vexpress-a9 -m 256 -kernel tmp/deploy/images/qemuarma9/zImage -dtb tmp/deploy/images/qemuarma9/vexpress-v2p-ca9.dtb -append "console=ttyAMA0" -nographic

Building u-boot

vi ../meta-qemuarma9/conf/machine/qemuarma9.conf

#Include u-boot
EXTRA_IMAGEDEPENDS += "u-boot"
UBOOT_MACHINE = "vexpress_ca9x4_defconfig"

# Include u-boot elf file in the images folder
UBOOT_ELF = "u-boot"

bitbake core-image-minimal

# run qemu with -kernel u-boot.elf:

qemu-system-arm -machine vexpress-a9 -m 256 -kernel tmp/deploy/images/qemuarma9/u-boot.elf -nographic

bdinfo

arch_number = 0x000008e0
boot_params = 0x60002000
# DRAM bank 0 addresses, this is what we will use to load kernel and device tree.
DRAM bank = 0x00000000
-> start = 0x60000000
-> size = 0x10000000

Exit: Ctrl+A, X

Prepare SD Card image

pushd ../meta-qemuarma9/

mkdir wic
touch wic/qemuarma9-yocto.wks
vi wic/qemuarma9-yocto.wks

part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=ext4 --label boot --align 2 --use-uuid
part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root --align 2 --use-uuid

# 3rd
part /mnt --fixed-size 100M --ondisk mmcblk0 --fstype=ext4 --label storage --align 131072 --use-uuid

# /mnt/p3 will not mount because dictionary not exit.
# Can mount manually after make dictionary.
# mount -t ext4 /dev/mmcblk0p3 p3

# ???
part /p3 --size 100M --ondisk mmcblk0 --fstype=ext4 --label storage --align 1024 --use-uuid
part /mnt --ondisk mmcblk --fstype=ext4 --label rootfs2 --align 4096 --fixed-size=800M
part /opt --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/opt --ondisk sda --fstype=ext4 --label opt --align 8192

vi conf/machine/qemuarma9.conf

# Wic configuration
IMAGE_FSTYPES += "wic"
WKS_FILE ?= "qemuarma9-yocto.wks"

# Files that will be included in boot partition
IMAGE_BOOT_FILES ?= "zImage vexpress-v2p-ca9.dtb"
# for OTA
IMAGE_BOOT_FILES ?= "zImage;kernel_a zImage;kernel_b vexpress-v2p-ca9.dtb;dtb_a vexpress-v2p-ca9.dtb;dtb_b uboot.env"

# Remove unneeded configurations from the original bsp:

# Set image size for MMC disk
#IMAGE_ROOTFS_EXTRA_SPACE = "0"
#IMAGE_ROOTFS_SIZE = "3801088"
#INITRAMFS_MAXSIZE = "3801088"
#IMAGE_ROOTFS_ALIGNMENT = "1"

# Include u-boot elf file in the images folder
UBOOT_ELF = "u-boot"
UBOOT_ENTRYPOINT = "0x60100000"
UBOOT_LOADADDRESS = "0x60100000"

vi conf/machine/qemuarma9.inc

#ROOT_FLASH_SIZE = "280"

popd

bitbake core-image-minimal

fdisk -l tmp/deploy/images/qemuarma9/core-image-minimal-qemuarma9.wic

Run this in the output images directory. You will now have the file sd.img ready to be used as the emulated SD Card.

pushd tmp/deploy/images/qemuarma9
touch mksd.sh
vi mksd.sh

#!/bin/sh

file="sd.img"

if [ -f "$file" ] ; then
read -p "An sd.img file already exists. Are you sure you want to delete it and create a new one? (y/n) " input
if [ "$input" != "y" ]; then
exit
fi

echo "Removing old sd.img"
rm "$file"
fi

echo "Creating empty sd.img file"
dd if=/dev/zero of=sd.img bs=1M count=1000

echo "Copying content from wic file"
dd if=core-image-minimal-qemuarma9.wic of=sd.img conv=notrunc
echo "Resize rootfs partition to take the whole sd.img size"
parted -s sd.img resizepart 2 100% # Not work with > 2 part

chmod 777 mksd.sh
./mksd.sh

# Resize for SD Card manually, for part > 2
qemu-img resize sd.img 1G

fdisk -l sd.img

popd

Booting Linux from SD Card

qemu-system-arm -machine vexpress-a9 -m 256 -kernel tmp/deploy/images/qemuarma9/zImage -dtb tmp/deploy/images/qemuarma9/vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0 root=/dev/mmcblk0" -sd tmp/deploy/images/qemuarma9/core-image-minimal-qemuarma9.ext4

qemu-system-arm -machine vexpress-a9 -m 256 -kernel tmp/deploy/images/qemuarma9/u-boot.elf -nographic -sd tmp/deploy/images/qemuarma9/sd.img

# uboot to load the image
ext4load mmc 0:1 0x60100000 zImage
ext4load mmc 0:1 0x62000000 vexpress-v2p-ca9.dtb
setenv bootargs console=ttyAMA0 root=/dev/mmcblk0p2
bootz 0x60100000 - 0x62000000

Editing u-boot configuration to correctly autoboot

pushd ../meta-qemuarma9/

We will create the following folder/files inside meta-qemuarma9 folder:

├── recipes-bsp
│ └── u-boot
│ ├── files
│ │ └── fragment.cfg
│ └── u-boot_%.bbappend

Edit fragment.cfg and add the following lines:

CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0 root=/dev/mmcblk0p2"
CONFIG_BOOTCOMMAND="ext4load mmc 0:1 0x60100000 zImage\; ext4load mmc 0:1 0x62000000 vexpress-v2p-ca9.dtb\; bootz 0x60100000 - 0x62000000"

Edit u-boot_%.bbappend and add these lines:

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += "file://fragment.cfg"

popd

bitbake core-image-minimal

qemu-system-arm -machine vexpress-a9 -m 256 -kernel tmp/deploy/images/qemuarma9/u-boot.elf -nographic -sd tmp/deploy/images/qemuarma9/sd.img

Adding packages to our distro

# poky directory
git clone http://cgit.openembedded.org/meta-openembedded
cd meta-openembedded
git checkout dunfell
cd ..
source oe-init-build-env <build-env-name>
bitbake-layers add-layer ../meta-openembedded/meta-oe

Error “ParseError at /home/dev/service/poky/meta-openembedded/meta-oe/recipes-dbs/postgresql/postgresql.inc:39: Could not inherit file classes/python3targetconfig.bbclass”

vi poky/meta/classes/python3targetconfig.bbclass

inherit python3native

EXTRA_PYTHON_DEPENDS ?= ""
EXTRA_PYTHON_DEPENDS_class-target = "python3"
DEPENDS_append = " ${EXTRA_PYTHON_DEPENDS}"

do_configure_prepend_class-target() {
export _PYTHON_SYSCONFIGDATA_NAME="_sysconfigdata"
}

do_compile_prepend_class-target() {
export _PYTHON_SYSCONFIGDATA_NAME="_sysconfigdata"
}

do_install_prepend_class-target() {
export _PYTHON_SYSCONFIGDATA_NAME="_sysconfigdata"
}

We do this by adding this line into conf/local.conf:

IMAGE_INSTALL_append = " nano"

Now run bitbake and create your sd.img again to add the new package into the sd card.

bitbake core-image-minimal
pushd tmp/deploy/images/qemuarma9/
./mksd.sh
qemu-img resize sd.img 1G
qemu-system-arm -machine vexpress-a9 -m 256 -kernel u-boot.elf -nographic -sd sd.img

SWUpdate

# poky directory
git clone https://github.com/sbabic/meta-swupdate.git

cd meta-swupdate
git checkout dunfell
cd ..
source oe-init-build-env <build-env-name>
bitbake-layers add-layer ../meta-swupdate

# Disable MTD
# → Swupdate Settings → General Configuration
bitbake -c menuconfig swupdate

bitbake swupdate

bitbake linux-yocto -c menuconfig

# meta-oe is must
cat conf/bblayers.conf


git clone https://github.com/sbabic/meta-swupdate-boards.git -b master
source oe-init-build-env build-vexpressa9
bitbake-layers add-layer ../meta-swupdate-boards


vi conf/local.conf
IMAGE_INSTALL:append = " nano swupdate swupdate-www"
# Old bitbake
IMAGE_INSTALL_append = " nano swupdate swupdate-www"

bitbake core-image-minimal

ps | grep swupdate | grep -v grep

288 root 47860 S /usr/bin/swupdate -v -w -r /www -p 8080
309 root 47860 S /usr/bin/swupdate -v -w -r /www -p 8080

systemctl status swupdate.service


df -h /

fdisk -l

# mount multi partitions
sudo apt install kpartx
sudo kpartx -a tmp/deploy/images/qemuarma9/sd.img sdm
sudo mount -o rw -t ext4 /dev/mapper/loop13p3 sdm/
sudo umount /dev/mapper/loop13p3

In meta-qemuarma9/conf/machine/qemuarm9.conf we will update IMAGE_BOOT_FILES variable to this:

IMAGE_BOOT_FILES ?= "zImage;kernel_a zImage;kernel_b vexpress-v2p-ca9.dtb;dtb_a vexpress-v2p-ca9.dtb;dtb_b uboot.env"


part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=ext4 --label boot --align 1024 --use-uuid --extra-space 50 --mkfs-extraopts="-O ^metadata_csum"

part --source rootfs --fstype=ext4 --ondisk mmcblk0 --use-uuid --label root_a --align 1024 --extra-space 300

part --source rootfs --fstype=ext4 --ondisk mmcblk0 --use-uuid --label root_b --align 1024 --extra-space 300



part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=ext4 --label boot --align 1024 --use-uuid --extra-space 5 --mkfs-extraopts="-O ^metadata_csum"

part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root_a --align 1024 --use-uuid --extra-space 3

part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root_b --align 1024 --use-uuid --extra-space 3

part /mnt --fixed-size 100M --ondisk mmcblk0 --fstype=ext4 --label storage --align 2 --use-uuid



Now the output wic file will contain the needed partition scheme.

touch sw-description

mmcblk0 tty tty38 ttyAMA1
mmcblk0p1 tty0 tty39 ttyAMA2
mmcblk0p2 tty1 tty4 ttyAMA3
mmcblk0p3 tty10 tty40 urandom
mmcblk0p4

blkid -s LABEL -o value /dev/mmcblk0p3

fw_env.config

# MTD device name Device offset Env. size Flash sector size
/dev/mtd0 0xc0000 0x2000 0x10000


dmesg

touch gen-swupdate-image.sh


#!/bin/sh

BOARD_DIR=$(dirname $0)

echo $BOARD_DIR
echo $BINARIES_DIR

IMG_FILES="sw-description rootfs.tar.bz2"

for f in ${IMG_FILES} ; do
echo ${f}
done | cpio -ovL -H crc > update.swu


./gen-swupdate-image.sh
cat update.swu | cpio -it

sgdisk -A 4:toggle:2 -A 5:toggle:2 /dev/mmcblk0

swupdate -i /mnt/update.swu -e rootfs,rootfs-2

[ERROR] : SWUPDATE failed [0] ERROR : Configuration file /etc/fw_env.config wrong or corrupted

bitbake virtual/kernel -c menuconfig

> Device Drivers > Memory Technology Device (MTD) support
Enable UBI - Unsorted block images --->


IMAGE_INSTALL_append = " nano swupdate swupdate-www swupdate-progress swupdate-client json-c"

QEMU and RAUC

Install

# ubuntu 22.04
sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint xterm python3-subunit mesa-common-dev zstd liblz4-tool

# ubuntu 20.04
sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev zstd liblz4-tool

Prepare

git clone https://git.yoctoproject.org/poky
pushd poky
# ubuntu 22.04
git checkout tags/yocto-4.0 -b yocto-4.0-local
# ubuntu 20.04
git checkout tags/yocto-3.4.2 -b yocto-3.4.2-local
popd

git clone -b kirkstone https://github.com/rauc/meta-rauc.git

git clone -b kirkstone https://github.com/rauc/meta-rauc-community.git


git clone https://github.com/rauc/rauc-hawkbit-updater.git
pushd rauc-hawkbit-updater
# ubuntu 22.04
git checkout tags/v1.3 -b v1.3-local
# ubuntu 20.04
git checkout tags/v1.1 -b v1.1-local
popd

source poky/oe-init-build-env build-qemux86-64-rauc

bitbake-layers add-layer ../meta-rauc-community/meta-rauc-qemux86
bitbake-layers add-layer ../meta-rauc

# List all of the .bb and .bbappend files used to build a specific package with bitbake.
bitbake-layers show-appends

conf/local.conf

vi conf/local.conf
## Append to the end
DISTRO_FEATURES += "rauc"
CORE_IMAGE_EXTRA_INSTALL += "rauc"
MACHINE_FEATURES:append = " pcbios efi"
EXTRA_IMAGEDEPENDS += "ovmf"
PREFERRED_RPROVIDER_virtual-grub-bootconf = "rauc-qemu-grubconf"
INIT_MANAGER = "systemd"
EXTRA_IMAGE_FEATURES += "ssh-server-openssh"
# For hawkbit
IMAGE_INSTALL:append = " rauc-hawkbit-updater"

# Reusing the sstate-cache and downloads.
# Move 2 dirs outside.
DL_DIR ?= "${TOPDIR}/../downloads"
SSTATE_DIR ?= "${TOPDIR}/../sstate-cache"
pushd ../meta-rauc-community/

./create-example-keys.sh

cat ../build-qemux86-64-rauc/conf/site.conf

build-qemux86-64-rauc/conf/site.conf reference

RAUC_KEYRING_FILE="build-qemux86-64-rauc/example-ca/ca.cert.pem"
RAUC_KEY_FILE="build-qemux86-64-rauc/example-ca/private/development-1.key.pem"
RAUC_CERT_FILE="build-qemux86-64-rauc/example-ca/development-1.cert.pem"
popd

QEMU System Image

bitbake core-image-minimal

ls -1 tmp/deploy/images/qemux86-64

runqemu nographic slirp ovmf wic core-image-minimal

# Login: root

# show help
rauc -h

# rootfs.1 boot status: bad is correct.
rauc status
=== Slot States ===
[rescue.0] (/dev/sda3, ext4, inactive)
mounted: /rescue

[efi.0] (/dev/sda, boot-gpt-switch, inactive)

o [rootfs.1] (/dev/sda5, ext4, inactive)
bootname: B
boot status: bad

x [rootfs.0] (/dev/sda4, ext4, booted)
bootname: A
mounted: /
boot status: good
# Exit yocto in qemu
shutdown now

# Build rauc OTA package
bitbake qemu-demo-bundle

ls tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb

# check the content of this bundle
bitbake rauc-native -c addto_recipe_sysroot

oe-run-native rauc-native rauc info --keyring="example-ca/ca.cert.pem" tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb

# specify the verification keyring
eval `grep RAUC_KEYRING_FILE conf/site.conf`

oe-run-native rauc-native rauc info --keyring=$RAUC_KEYRING_FILE tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb

RAUC Package

mkdir ../meta-rauc/recipes-support/rauc-hawkbit-updater/files

vi ../meta-rauc/recipes-support/rauc-hawkbit-updater/files/do.sh

After packing the file will store at /etc/do.sh

# The content distinguish package, can input anything.
# Example:
Firmware A
# or
Firmware B

vi ../meta-rauc/recipes-support/rauc-hawkbit-updater/files/config.conf

[client]
# host or IP and optional port
hawkbit_server = domain.net

# true = HTTPS, false = HTTP
ssl = true

# validate ssl certificate (only use if ssl is true)
ssl_verify = false

# Tenant id
tenant_id = DEFAULT

# Target name (controller id)
target_name = dev01

# Security token
auth_token = abcde12345

# Or gateway_token can be used instead of auth_token
#gateway_token = this0is0a0gateway0token0

# Temporay file RAUC bundle should be downloaded to
bundle_download_location = /tmp/bundle.raucb

# time in seconds to wait before retrying
retry_wait = 60

# connection timeout in seconds
connect_timeout = 20

# request timeout in seconds
timeout = 60

# time to be below "low_speed_rate" to trigger the low speed abort
low_speed_time = 0

# average transfer speed to be below during "low_speed_time" seconds
low_speed_rate = 0

# reboot after a successful update
post_update_reboot = false

# debug, info, message, critical, error, fatal
log_level = message

# Every key / value under [device] is sent to HawkBit (target attributes),
# and can be used in target filter.
[device]
mac_address = ff:ff:ff:ff:ff:ff
hw_revision = 2
model = T1

vi ../meta-rauc/recipes-support/rauc-hawkbit-updater/rauc-hawkbit-updater_%.bbappend

The ${D} variable allows the software being built to be installed in a directory other than its real target.

SUMMARY = "The Recipe of Copy Config"

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

SRC_URI += " \
file://do.sh \
file://config.conf \
"

do_install:append() {
echo "--- VAR ---"
echo ${THISDIR}
echo ${D}
echo ${bindir}
echo ${D}${bindir}
echo ${WORK_DIR}
echo ${datadir}
echo ${sysconfdir}
echo "--- EXECUTE ---"
install -m 0644 ${WORKDIR}/do.sh ${D}${sysconfdir}/
install -m 0644 ${WORKDIR}/config.conf ${D}${sysconfdir}/rauc-hawkbit-updater/
}

Generate updater

pushd ../rauc-hawkbit-updater

vi src/hawkbit-client.c

v1.1, v1.3 must do this if nginx config 301 redirect http to https.

// search "static gboolean rest_request"
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fetch_buffer);
// Add 301 redirect
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
git config --local user.email "[email protected]"
git config --local user.name "Your Name"
git commit -m "Add 301 redirect"
git add src/hawkbit-client.c

# ubuntu 22.04
git archive -o "../rauc-hawkbit-updater-1.3.tar.gz" HEAD --format=tar.gz --prefix=rauc-hawkbit-updater-1.3/
sha256sum ../rauc-hawkbit-updater-1.3.tar.gz

# ubuntu 20.04
git archive -o "../rauc-hawkbit-updater-1.1.tar.gz" HEAD --format=tar.gz --prefix=rauc-hawkbit-updater-1.1/
sha256sum ../rauc-hawkbit-updater-1.1.tar.gz

# Response
# 49a3e91209651863949882b19ed2236eceed380b7ede340edd5e3a9bdc8fea5e ../rauc-hawkbit-updater-1.3.tar.gz

# ubuntu 22.04
mv ../rauc-hawkbit-updater-1.3.tar.gz ../meta-rauc/recipes-support/rauc-hawkbit-updater/files/

# ubuntu 20.04
mv ../rauc-hawkbit-updater-1.1.tar.gz ../meta-rauc/recipes-support/rauc-hawkbit-updater/files/

ubuntu 22.04

vi ../meta-rauc/recipes-support/rauc-hawkbit-updater/rauc-hawkbit-updater_1.3.bb

Replace all.

include rauc-hawkbit-updater.inc

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

# For local
SRC_URI = "file://rauc-hawkbit-updater-1.3.tar.gz"
# sha256sum rauc-hawkbit-updater-1.3.tar.gz
SRC_URI[sha256sum] = "49a3e91209651863949882b19ed2236eceed380b7ede340edd5e3a9bdc8fea5e"

ubuntu 20.04

vi ../meta-rauc/recipes-support/rauc-hawkbit-updater/rauc-hawkbit-updater_1.1.bb

include rauc-hawkbit-updater.inc

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

# For local
SRC_URI = "file://rauc-hawkbit-updater-1.1.tar.gz"
# sha256sum rauc-hawkbit-updater-1.1.tar.gz
SRC_URI[sha256sum] = "b2daaa8a4b035a5393c8318b478c50277a8692b72d86973f459411c8c25d30af"
md5sum LICENSE
# Response
1a6d268fd218675ffea8be556788b780 LICENSE

cp LICENSE ../meta-rauc/recipes-support/rauc-hawkbit-updater/files/

vi ../meta-rauc/recipes-support/rauc-hawkbit-updater/rauc-hawkbit-updater.inc

Mod:

LIC_FILES_CHKSUM = "file://LICENSE;md5=1a6d268fd218675ffea8be556788b780"

Integrate ssl for wget

vi ../poky/meta/recipes-core/busybox/busybox.inc

busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d), 'CONFIG_FEATURE_IFUPDOWN_IPV6', cnf, rem)
busybox_cfg(bb.utils.contains_any('DISTRO_FEATURES', 'bluetooth wifi', True, False, d), 'CONFIG_RFKILL', cnf, rem)
+ busybox_cfg(True, 'CONFIG_FEATURE_WGET_OPENSSL', cnf, rem)
popd
bitbake qemu-demo-bundle

# Rename if make another package.
cp tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb ../qemu-demo-bundle-qemux86-64-a.raucb

Installing The Update from Local

Start QEMU and copy the update package into it with ssh than run RAUC to update.

## Start qemu and keep running at host
bitbake qemu-demo-bundle

# Connect, check ~/.ssh/known_hosts if can not connect
# -P, remote port
scp -P 2222 tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb root@localhost:/data/

# Copy package into qemu
cp tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb qemu-demo-bundle-qemux86-64-fw-a.raucb
# or
cp tmp/deploy/images/qemux86-64/qemu-demo-bundle-qemux86-64.raucb qemu-demo-bundle-qemux86-64-fw-b.raucb

## In qemu guest device

rauc install /data/qemu-demo-bundle-qemux86-64.raucb

reboot

# check the context updated.
cat /etc/do.sh

rauc-hawkbit-updater -h

cat /etc/rauc-hawkbit-updater/config.conf

# Run RAUC with config
rauc-hawkbit-updater -r -d -c /etc/rauc-hawkbit-updater/config.conf

# A/B method, must reboot to check file updated.
reboot

Raspberry Pi 3

sudo apt install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev

mkdir my-rpi && cd my-rpi
git clone -b hardknott git://git.yoctoproject.org/poky.git
git clone -b hardknott git://git.yoctoproject.org/meta-raspberrypi

source poky/oe-init-build-env build-rpi

bitbake-layers add-layer ../meta-raspberrypi

# Not generate qemu environment
sed -i 's/^MACHINE.*/MACHINE ?= "raspberrypi3"/g' conf/local.conf
# Generate qemu environment
sed -i 's/^MACHINE.*/MACHINE ?= "qemuarm"/g' conf/local.conf

sed -i '/^#DL_DIR ?= "${TOPDIR}\/downloads"/ a DL_DIR ?= \"${HOME}/service/yocto-downloads"' conf/local.conf
sed -i 's/^PACKAGE_CLASSES.*/PACKAGE_CLASSES ?= "package_ipk"/g' conf/local.conf

echo 'RPI_USE_U_BOOT = "1"' >> conf/local.conf
echo 'ENABLE_UART = "1"' >> conf/local.conf

bitbake core-image-minimal

# all files for deploy
ls tmp/deploy/images/raspberrypi3/

bzip -Dk core-image-minimal-raspberrypi3.wic.bz2
sudo dd if=core-image-minimal-raspberrypi3.wic of=${SD_CARD} bs=40960

# SWUpdate

git clone -b hardknott http://cgit.openembedded.org/meta-openembedded

bitbake-layers add-layer ../meta-openembedded/meta-oe

git clone -b hardknott https://github.com/sbabic/meta-swupdate.git

bitbake-layers add-layer ../meta-swupdate

git clone -b hardknott https://github.com/sbabic/meta-swupdate-boards.git

bitbake-layers add-layer ../meta-swupdate-boards

bitbake-layers show-recipes

bitbake core-image-minimal


# Qemu
qemu-system-arm -M qemuarm -smp 1 -m 256 -kernel tmp/deploy/images/raspberrypi3/uImage -dtb tmp/deploy/images/raspberrypi3/bcm2710-rpi-3-b-plus.dtb -drive file=tmp/deploy/images/raspberrypi3/core-image-minimal-raspberrypi3.ext3,if=sd,format=raw -append "console=ttyAMA0,115200 root=/dev/mmcblk0" -serial stdio -net nic,model=lan9118 -net user

WIC

.wks

example

part /opt --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/opt --ondisk sda --fstype=ext4 --label opt --align 8192
part /mnt/p3 --fixed-size 100M --ondisk mmcblk0 --fstype=ext4 --label storage --align 131072 --use-uuid
sudo mount -t ext4 /dev/mmcblk0p3 p3

example IMX

part u-boot --source rawcopy --sourceparams="file=imx-boot" --ondisk sda --no-table --align ${IMX_BOOT_SEEK}
part /boot --source bootimg-partition --ondisk sda --fstype=vfat --label boot --active --align 8192 --size 64
part / --source rootfs --ondisk sda --fstype=ext4 --label root --exclude-path=home/ --exclude-path=opt/ --align 8192
part /home --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/home --ondisk sda --fstype=ext4 --label home --align 8192
part /opt --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/opt --ondisk sda --fstype=ext4 --label opt --align 8192
bootloader --ptable msdos

Bitbake

# Can fix inode error
bitbake -c clean RECIPIES

# Increase threads
# Edit build/conf/local.conf
PARALLEL_MAKE = "-j x"
BB_NUMBER_THREADS = "y"

Qt

Compatibility matrix between Yocto and Qt6 versions (T = tested, C = compatible, – = not supported)

Yocto \ Qt6.56.46.36.2
4.2 (Mickledore)TT
4.1 (Langdale)TTCC
4.0-LTS (Kirkstone)TTTT
3.4 (Honister)CCTT
3.3 (Hardknott)CCCC
3.2 (Gatesgarth)CCCC
3.1-LTS (Dunfell)TTTT