Raspberry Pi kernel missing in rootfs

589 views
Skip to first unread message

Daniel Hofer

unread,
Mar 1, 2022, 5:49:18 AM3/1/22
to swup...@googlegroups.com
Hi, I successfully got basic dual-copy updating working on a Raspberry Pi 4 thanks to SWUpdate!
However, I am still struggling to understand how to safely update the kernel.

I basically got it working by taking the examples for the Raspberry Pi 3 from meta-swupdate-boards and renaming the folders from raspberrypi3 to raspberrypi4. At this point the boot fails with the following error and some follow-up error messages:
Failed to load 'boot/uImage'

I could fix this by changing a line in the file boot.cmd.in:
- load mmc 0:${rpipart} ${kernel_addr_r} boot/@@KERNEL_IMAGETYPE@@
+ fatload mmc 0:1 ${kernel_addr_r} @@KERNEL_IMAGETYPE@@

The initial line in boot.cmd.in suggests that the kernel is included in the rootfs partition, but not in my case apparently.
I did not find anything in meta-swupdate-boards that would put the kernel into rootfs and I am not sure how to proceed.

By default meta-raspberrypi  seems to put the kernel onto the /boot partition and disables putting the kernel onto rootfs, which can be seen by the following line in rpi-base.inc:
# The kernel image is installed into the FAT32 boot partition and does not need
# to also be installed into the rootfs.
RDEPENDS:${KERNEL_PACKAGE_NAME}-base = ""

Here is my base image recipe:
DESCRIPTION = "SWU base image"
SECTION = ""
LICENSE="CLOSED"

WKS_FILE = "swu-raspberrypi.wks"
IMAGE_FSTYPES += "wic wic.gz ext4.gz"

IMAGE_FEATURES += "splash debug-tweaks ssh-server-openssh tools-debug tools-profile"

# connman - provides network connectivity.
# parted - provides disk partitioning utility.
# libubootenv-bin - provides fw_printenv and fw_setenv needed for experimenting
IMAGE_INSTALL:append = " \
    swupdate \
    packagegroup-core-boot \
    packagegroup-core-full-cmdline \
    openssh connman connman-client \
    parted \
    binutils \
    chrony \
    libubootenv-bin \
    "

# this did not work
#RDEPENDS:${KERNEL_PACKAGE_NAME}-base = "${KERNEL_PACKAGE_NAME}-image (= ${EXTENDPKGV})"
# TODO maybe try to copy uImage to rootfs partition? but how and where when /boot it already occupied?

export IMAGE_BASENAME = "swu-base-image"

inherit core-image

My question is: How was the original boot.cmd.in intended to work with Raspberry Pi regarding the kernel location? I don't think the step from Pi 3 to Pi 4 changed anything relevant here, but maybe I am missing something.

Best regards,
Daniel

Daniel Hofer

unread,
Mar 1, 2022, 6:26:27 AM3/1/22
to swupdate
I just realized that the reason could be that I am using the honister branches.
I cannot use dunfell because I need the new libcamera camera stack from the current Raspberry Pi Debian Bullseye port.

However, I think the new Yocto LTS version is released next month and then this issue might be relevant for others as well.

Thanks,
Daniel

Stefano Babic

unread,
Mar 1, 2022, 7:13:14 AM3/1/22
to Daniel Hofer, swup...@googlegroups.com
Hi Daniel,

On 01.03.22 11:49, Daniel Hofer wrote:
> Hi, I successfully got basic dual-copy updating working on a Raspberry
> Pi 4 thanks to SWUpdate!
> However, I am still struggling to understand how to safely update the
> kernel.
>

Please think about that recipes in meta-swupdate-boards are just
*examples* and there is some work if you want to have it in production.

In your use case, this depends how RPI[3|4] is working. The closed
source bootloader is generating the DT for kernel, and if something
changed (bootloader files, DTBO, etc.), kernel does not boot. It is a
different issue as what you are reporting, but this will happen, too.

> I basically got it working by taking the examples for the Raspberry Pi 3
> from meta-swupdate-boards and renaming the folders from raspberrypi3 to
> raspberrypi4. At this point the boot fails with the following error and
> some follow-up error messages:
> /Failed to load 'boot/uImage'/
>
> I could fix this by changing a line in the file/boot.cmd.in/:
> - load mmc 0:${rpipart} ${kernel_addr_r} boot/@@KERNEL_IMAGETYPE@@
> + fatload mmc 0:1 ${kernel_addr_r} @@KERNEL_IMAGETYPE@@

This is wrong, you are fixing the kernel to boot just from first
partition. If kernel is upgraded and goes into the second partition, you
are still oading the wrong one. The variable rpipart is used to get
where to load the kernel and to set rootfs, and of course you wil lhave
a mismatch here.

It could be you are hitting the issue I report above, for example if
there is no uImage anymore (but maybe a zImage, or..).

>
> The initial line in /boot.cmd.in/ suggests that the kernel is included
> in the rootfs partition, but not in my case apparently.

It is in the example. The uImage file in the examples is *NOT* kernel,
but it is U-Boot. It looks like you are booting from the closed source
bootloader, but this is not able to work with a dual-copy concept (it
loads always a uImage in the first FAT partition).

> I did not find anything in meta-swupdate-boards that would put the
> kernel into rootfs and I am not sure how to proceed.

To build it you should have in distro or local.conf:

IMAGE_INSTALL:append = " kernel-image kernel-modules"
DISTRO_FEATURES:append = " systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit"
VIRTUAL-RUNTIME_init_manager = "systemd"
VIRTUAL-RUNTIME_initscripts = "systemd-compat-units"
# meta-raspberrypi
RPI_USE_U_BOOT = "1"

>
> By default meta-raspberrypi  seems to put the kernel onto the /boot

Right, but then there is just one kernel without redundancy, and a
power-cut when kernel is updated bricks the board.

> partition and disables putting the kernel onto rootfs, which can be seen
> by the following line in/rpi-base.inc:/
> /
> # The kernel image is installed into the FAT32 boot partition and does
> not need
> # to also be installed into the rootfs.

....if the update is done by replacing the SD-Card

> RDEPENDS:${KERNEL_PACKAGE_NAME}-base =""
> /
> My question is: How was the original/boot.cmd.in/intended to work with
> Raspberry Pi regarding the kernel location?

See above

> I don't think the step from
> Pi 3 to Pi 4 changed anything relevant here, but maybe I am missing
> something.

Best regards,
Stefano Babic


--
=====================================================================
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de
=====================================================================

Daniel Hofer

unread,
Mar 1, 2022, 10:18:17 AM3/1/22
to swupdate
Ok thank you, it now works with the example boot.cmd.in after adding IMAGE_INSTALL:append = " kernel-image kernel-modules".
I already had RPI_USE_U_BOOT = "1" and all the other suggested lines in my local.conf before.

If I understand correctly, what roughly happens now at boot is the following:
  1. After the on-board first and second stage bootloaders, u-boot bootloader (located at boot partition?) is loaded
  2. The boot partition contains the device tree and kernel configuration (config.txt) that are passed to the kernel
  3. The boot.scr, which resulted from boot.cmd.in, tells u-boot to boot the kernel from active rootfs partition in folder boot/uImage
  4. After boot, the boot partition is mounted into /boot and the actual kernel image that was booted is not reachable anymore because it was in the same folder in the rootfs
I understand that further customization is needed for a production system and I would appreciate a little help to work into the right direction.
I would like to be able to add new DT overlays and change kernel configuration (stuff in /boot/config.txt). Do you know if it is possible to make those part of rootfs as well? If it is not, then I guess it would be accomplishable using file updates in boot partition, but this does not sound very safe.

Best regards,
Daniel

Daniel Hofer

unread,
Mar 1, 2022, 10:39:40 AM3/1/22
to swupdate
Please forget what I said about config.txt, I just read that this file is loaded by on-board Raspberry Pi firmware not kernel configuration.
Hmm, I guess then all the hardware related configuration has to be fixed before remote updating is possible.
I only wanted to be able to update hardware configuration for development purposes to update prototypes installed at our customers and successively enable all hardware features of the board (RTC, PWM fan, ...).
I guess I will use single file updates in boot partition during development and then stop updating anything in the boot partition once we reach production.
Reply all
Reply to author
Forward
0 new messages