Support your machine (Arm)¶
This page suggests a step-by-step guide of the things to do in order to have Welma booting on your Arm-based machine.
Step 1: Set up your Yocto layer¶
-
Start from the OEM's BSP layers: bootloader, kernel, ...
- Remove dependencies to unnecessary layers, in order to ease
maintenance. Typically:
- for imx-based boards: remove meta-freescale-*, meta-imx
- for arm-based boards: remove meta-arm
- remove the vendor's layers that are not BSP-related: demonstration distro, sdk
- and so on...
- Keep TF-A (or ATF), OP-TEE
- Work in a layer repository named
meta-welma-<vendor>
. Create:conf/layer.conf
(if the layer is a new layer)conf/machine/$MACHINE.conf
conf/templates/$MACHINE/local.conf.sample
conf/templates/$MACHINE/bblayers.conf.sample
- Remove dependencies to unnecessary layers, in order to ease
maintenance. Typically:
-
Define your partition layout (boot, sysro, appro, sysrw)
- Give priority to storing the bootloader on eMMC, in user partition
- Create
files/partitions-$MACHINE.conf
(and haveWELMA_PARTITIONS
point to it, which is already the case with its default value). - Create
wic/$MACHINE.wks.in
, with A/B partitions (and haveWKS_FILE
point to it)- Allocate an extra partition for the bootflags
- In
conf/machine/$MACHINE.conf
, define theBOOTFLAGS_
parameters, that indicate how userspace programs can locate the bootflags. Eg:
Step 2: Have Welma boot to initramfs¶
- U-Boot:
Create the default environment file distro-bootcmd.env
:
/* Machine-specific parameters */
bootmedia=mmc
bootdev=2 /* mmc device number */
bootpart=1 /* partition where 'fitImage' is located */
fit_loadaddr=0x48000000
console=ttymxc1,115200
fdt_module=undefined /* will be populated by u-boot (in board_late_init) */
fit_config_and_fdt_overlays=#conf-overlay-hdmi.dtb#conf-overlay-baseboard-ep5.dtb#conf-overlay-sm2s-imx8plus-mbep5.dtb
evaluate_bootflags=echo Placeholder for evaluate_bootflags;
set_swk1_in_bootargs=echo Placeholder for set_swk1_in_bootargs;
boot_welma=
run evaluate_bootflags;
load ${bootmedia} ${bootdev}:${bootpart} ${fit_loadaddr} fitImage;
setenv bootargs "${bootargs} console=${console}";
run set_swk1_in_bootargs;
bootm ${fit_loadaddr}#conf-${fdt_module}${fit_config_and_fdt_overlays};
distro_bootcmd=run boot_welma;
Have this default environment file integrated in u-boot binary
(CONFIG_ENV_SOURCE_FILE
).
-
Kernel FIT image (
meta-welma/recipes-welma/fitimage/welma-fitimage.bb
): define inconf/machine/$MACHINE.conf
parameters that will be used by this recipe:KERNEL_DEVICETREE
: include dtb and overlays- Find available memory regions in RAM and set load addresses for kernel, fdt, fdt overlays, ramdisk. These addresses will be used in the memory context of U-Boot. Eg:
-
Kernel:
inherit kernel-uboot-deploy
-
Install the bootloader and all partitions on your board.
-
Boot: you should now see your board boot until a kernel panic error, which will be fixed in the next step.
... U-Boot ... ... Hit any key to stop autoboot: ... ... ## Loading kernel from FIT Image at ... ... ## Loading ramdisk from FIT Image at ... ... ## Loading fdt from FIT Image at ... ... Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0000000000 ... ... [ 2.878750] Run /init as init process [ 2.915409] initramfs: Starting [ 3.022323] initramfs: ERROR: no active partition for (sysro / ...). Expect undefined behaviour. [ 3.005157] initramfs: ERROR: no active partition for (boot /boot ...). Expect undefined behaviour. [ 3.044028] initramfs: ERROR: no active partition for (appro /app ...). Expect undefined behaviour. [ 3.183040] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
Step 3: Have U-Boot support A/B partitions¶
-
U-Boot:
-
Add the command
These must be consistent with the partition layout defined at step 1.bootflags
(incmd/bootflags.c
) and have it configured. Eg: -
distro-bootcmd.env
: add bootflags logic:- Recover if a previous bootflags writing was interrupted
- Initialize if no valid bootflags are found
- Roll back if this is the second attempt to boot in test mode
- Select the kernel FIT image partition to boot on
-
/* Machine-specific parameters */
bootflags_default_partitions=0x15 /* partitions number 1:3:5 */
evaluate_bootflags=
bootflags check; /* Recover from a previous interrupted writing */
bootflags read; /* Load bootflags_test_mode
* bootflags_test_count
* bootflags_first_active_partition */
if test $? != 0; then
/* bootflags not present or corrupted, initialize with default */
bootflags init $bootflags_default_partitions;
/* has also updated the values in memory (as bootflags read does) */
fi;
if test $bootflags_test_mode = 1; then
echo "Test mode";
if test $bootflags_test_count -ge 1; then
/* cancel test and back to normal mode */
echo "Revert to normal mode.";
bootflags abort-test;
/* has also updated the values in memory (as bootflags read does) */
else
bootflags increment-test-count;
fi;
else
echo "Normal mode";
fi;
bootpart=${bootflags_first_active_partition}; /* Select boot partition */
Step 4: Minimal working set of facilities¶
At this point you have to make sure:
- The Linux commands
reboot
andreboot -f
get your board to reboot. - Your board has one ethernet interface configured with a static IP address.
Example:
# ip address ... 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 10:e7:7a:e1:93:9a brd ff:ff:ff:ff:ff:ff inet 169.254.0.1/16 brd 169.254.255.255 scope link eth0 valid_lft forever preferred_lft forever [...] inet6 fe80::1/10 scope link valid_lft forever preferred_lft forever [...]
-
Your development image can be reached by SSH. Eg:
For this, you may need to configure the network (routes) of your PC. -
U-Boot can download an image via TFTP and install it on the mass memory of the board. This is needed for Welma's automatic testing. Eg:
STM32MP> setenv ipaddr 192.168.1.20 STM32MP> setenv serverip 192.168.1.12 STM32MP> tftp welma/demo-image-headless-dev-stm32mp15-disco-welma.wic.gz Using ethernet@5800a000 device TFTP from server 192.168.1.12; our IP address is 192.168.1.20 Filename 'welma/demo-image-headless-dev-stm32mp15-disco-welma.wic.gz'. Load address: 0xc2000000 Loading: ################################################################# ################################################################# ######## 4.6 MiB/s done Bytes transferred = 2024248 (1ee338 hex) STM32MP> mmcid=0 STM32MP> gzwrite mmc $mmcid $loadaddr $filesize
-
You have a documented procedure to install the image on the device for the first time (eg: with UUU, dfu-util, fastboot)
Step 5: Watchdog¶
- U-Boot: start the watchdog timer before starting the kernel, with a timeout of 60 s (to give the kernel time to start)
It is also useful to have the wdt
command (CMD_WDT=y
), for testing (see
https://docs.u-boot.org/en/latest/usage/cmd/wdt.html).
-
Linux kernel:
- Activate the driver to support the watchdog device
- Have the kernel ping the watchdog device until a userspace program takes
over (for at most 4 min) and do not stop the watchdog timer when this
userspace program closes
/dev/watchdog
:
-
Userspace:
- Configure systemd to service the watchdog device (
/dev/watchdog0
).
- Configure systemd to service the watchdog device (
Notes:
- If your board has more than one HW watchdog device, make sure to use the same watchdog device in U-Boot and Linux kernel & userspace.
Step 6: Populate the license digest¶
WELMA_LIC_DIGEST_BOOT
: add the recipes of the packages included in the bootloader
Step 7: Support secure boot¶
-
In
conf/templates/$MACHINE/local.conf.sample
, setWELMA_SECURE_BOOT = "1"
-
U-Boot: Provision SWK1 in U-Boot
- Add the command
fdt get hexvalue
(incmd/fdt.c
) distro-bootcmd.env
: add SWK1 public key tobootargs
do_compile:append()
: have SWK1 injected using the scriptinject-pubkey-uboot-dtb
- Add the command
-
U-Boot: Be sure to use the standard U-Boot mechanism for authenticating the kernel FIT image. Some vendor's versions of U-Boot use another specific mechanism (such as HAB on imx-based boards), and you should deactivate that.
-
Kernel:
CONFIG_DM_VERITY=y
-
imx-boot (for machines that have this bootloader):
- In the Yocto build, have it signed and provisioned with development keys,
using
welma-signing-tools
- Have the offsets of the signed blocks collected
- Have
fuse-bootcmd.scr
generated - In
conf/machine/$MACHINE.conf
, setBOOT_SIGNING_MECHANISM = "imx"
- In the Yocto build, have it signed and provisioned with development keys,
using
-
bootloader (other than imx-boot):
- Activate (or write) the code for authenticating each stage until U-Boot
- Create the tools for signing out of Yocto
- Have it signed in the Yocto build with development keys
- Provision the needed public keys as well (in Yocto and out of Yocto)
Step 8: Support secure storage (OP-TEE)¶
This support should be provided the bootloader which must integrate and launch OP-TEE OS.
In Linux, use xtest
(from package optee-test
) to check correct support.
Step 9: Production bootloader¶
Production image should not have an interactive bootloader.
Make sure to apply a minimal u-boot configuration when IMAGE_FEATURES
contains development
.
This minimal configuration should at least include CONFIG_BOOTDELAY=-2
to boot without offering any commandline.