Skip to content

Upgrading LOKI Kernel Version

Joseph Nobes edited this page Aug 28, 2024 · 1 revision

LOKI - Upgrading Kernel Versions in PetaLinux Projects

Summary

By default, the PetaLinux toolchain will build a certain kernel version that is packaged with the tools. For the 2020-1 tools, this is kernel 5.4. There is provision to change the kernel from the one packaged with the toolchain to either a different local project, or to a remote repository. The basics of this are reasonably easy to include, but expect to have to fix some compatibility issues.

Words of Warning - and Alternative Methods

Note that the user is typically not encouraged to attempt to alter the kernel included, as the recipes provided by the Xilinx layers will be assuming a set version, and following an upgrade you may run into hard to track down errors. Also note that a successful build does not necessarily mean you have been successful; there can be changes that allow an image to boot, but alter behaviour slightly (bus numbering, for example). Be very careful to test an updated image.

Also note that the kernel used by default is not mainline Linux, but linux-xlnx.

Also note that any changes to the kernel may affect the applicability of any patches applied to the kernel recipe in the user recipe layers.

Developers interested in updating the kernel source, might instead be able to achieve the same results with kernel patching, which allows you to edit kernel source code directly, and generate patch files that are then part of the normal user recipe layer, and therefore far easier to manage. Changing the kernel source is a last resort.

General Process

  1. Select a new source with petalinux-config
  2. Configure the chosen source (e.g. repository, branch, checksum etc) with petalinux-config
  3. Attempt a re-build, and correct any issues

Selecting the Source

With the toolchain version for the project sourced, run petalinux-config with no arguments. Navigate to Linux Components Selection -> linux-kernel and choose:

  • linux-xlnx for the default built-in kernel
  • remote to specify a repository
  • ext-local-src to choose another local directory where kernel source is located

Configuring a Remote Repository

Having chosen remote above, the new option directory Linux Components Selection -> Remote linux-kernel settings will have been added.

  • Add the HTTPS repository URL, with [[#Failure to Pull Branch due to SRC_URI checksum - use https and git //|corrections listed below in troubleshooting]]. e.g. git://github.com/Xilinx/linux-xlnx.git;protocol=https under Remote linux-kernel git URL
  • Add the latest commit to the branch you have chosen (or a tag)
  • Add the branch name (see above)
  • Add the MD5 checksum in format: file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46
    • If you don't know this, build without and the error messages will tell you what the new checksum should be.

Configuring a Local External Source

#TODO

Troubleshooting

Note that some of these issues will be very specific to the to/from kernel versions I've tested with.

I would generally recommend looking at the Yocto migration notes, paying attention to changes between versions of Yocto that progress through kernel versions.

See also this list relating kernel versions to Yocto versions.

For example, my build from PetaLinux 2020-1 uses Yocto version 3.0.0 Zeus, which by default ships with kernel 4.19, which was clearly patched by Xilinx to include 5.4. However, I am upgrading to kernel 5.15, which first appears in Yocto 4.0 Kirkstone, which means I should pay attention to any migration notes from Yocto 3.1, 3.2, 3.3, 3.4, and 4.0.

Upgrading Beyond 5.8 - Module.symvers Error (and other kernel.bbclass errors)

The kernel is built into the image using a recipe linux-xlnx_<version>.bb recipe from within the toolchain layers. This recipe inherits from the class kernel.bbclass from the Yocto meta layer.

When upgrading from 5.4 to 5.15 I encountered a build error where a copy of Module.symvers into the kernel image failed due to it not existing. This issue was fixed in later versions of the Yocto layer, but not in the toolchain packaged version. The fix, as discussed here , is to replace the line:

- cp Module.symvers $kerneldir/
+ [ -e Module.symvers ] && cp Module.symvers $kerneldir/

However this is easier said; the file to be patched is kernel.bbclass, which is in the Yocto meta layer. This layer is not included in the LOKI (or any PetaLinux) repository, since it is brought in by the toolchain, and cannot be edited without it just being overwritten on build. Unlike with recipes, class files are not overridden as part of the toolchain by layer priority, so you cannot just copy the class to the user layer and edit it. To make this work, you'd have to edit the bblayers.conf file, and place the user layer first. However, again, this is part of the PetaLinux toolchain as a build artefact and cannot be permanantly modified.

The best solution I have found to this is to copy the updated version of the do_shared_workdir function from the kernel class here into the kernel recipe in the user layer, which will overwrite specifically this function from the inherited version from the toolchain class.

Always Include a Commit / Tag

Just specifying a branch is not enough- it may cause errors with messages that do not refer to branches at all, and are therefore quite confusing. If you have specified a branch, find that branch in the repository and get the last commit hash, and enter it with petalinux-config.

Failure to Pull Branch due to SRC_URI checksum - use https and git://

The fetcher is designed to grab files from URLs, and therefore by default expects a SRC_URI checksum to be provided for the downloaded 'file'. Since this kernel recipe derives from a typical recipe, it is no different, and if it doesn't 'know' that it's supposed to be cloning a repository rather than just downloading the URL target, it won't try.

To invoke the git-specific fetcher, the URL must start with git:// (so replace the https://) part of it. Then, to tell the fetcher to fetch using HTTPS, you should append ;protocol=https.

For example: git://github.com/Xilinx/linux-xlnx.git;protocol=https

Failure to derive PV

PV is the package version, usually determined from the filename. However, when it's been provided by a git URL, you should add the following to the kernel recipe file (for my project, meta-user/recipes-kernel/linux/linux-xlnx/linux-xlnx_%.bbappend):

# your version here
PV = "5.15"

SPI Device Access Errors

In an apparently successful upgrade from kernel version 5.4 to 5.15, I found that target applications failed to run due to changes to the SPI addressing; although devices are listed in the sysfs (below), they do not appear in /dev/ as they do on images built earlier.

root@petalinux-custom:~# ls /sys/bus/spi/devices/
spi0.0  spi1.0  spi1.1  spi1.2  spi2.0  spi2.1  spi2.2

This list of devices matches a previous image (spi0.0 is the QSPI).

Having investigated a little, this seems to be generally an issue with this upgrade. This thread shows people discussing exactly this issue with SPIDev when upgrading from PetaLinux 2019 to 2022.1 (which contained a kernel upgrade to 5.15). As was concluded in this thread, there are some device tree changes required between these versions. As mentioned by another thread, this is because SPIDev does not consider spidev a valid compatible string in the device tree (although this was also the case in 5.4, so I'm not sure why it worked there...).

Fixed by changing the compatible string for every spidev device in the device tree in PetaLinux:

compatible = "rohm,dh2228fv";

This should be backwards compatible with version 5.4 also.

MTD Issues

Another issue encountered after further investigation of an image upgraded from 5.4 to 5.15 was that the MTD (flash) partition automatically mounted for file access (since it's spare) is no longer persistent between boots, and simply appears empty after a reboot.

Looking at /var/log/messages:

petalinux-custom:/home/loki# cat /var/log/messages | grep mtd
Apr 10 04:13:33 petalinux-custom user.err kernel: [    2.997658] mtdoops: mtd device (mtddev=name/number) must be supplied
Apr 10 04:13:33 petalinux-custom user.warn kernel: [    3.656414] mtd: partition "bootscr" doesn't end on an erase/write block -- force read-only

The bootscr partition is the one used for this mount. The message implies a difference in boundaries, potentially mismatch between the boundaries when data was written in vs. the boundaries the kernel now expects.

The partition boundaries can be listed:

petalinux-custom:/home/loki# lsmtd
DEVICE MAJ:MIN NAME    TYPE SIZE 
mtd0    90:0   boot    nor    4M
mtd1    90:2   bootenv nor  256K
mtd2    90:4   kernel  nor  100M
mtd3    90:6   bootscr nor   32K

When compared to the boundaries from a 5.4 image:

petalinux-custom:/home/loki# lsmtd
DEVICE MAJ:MIN NAME    TYPE SIZE 
mtd0    90:0   boot    nor    4M
mtd1    90:2   bootenv nor  256K
mtd2    90:4   kernel  nor  100M
mtd3    90:6   bootscr nor   32K

This is identical.

Comparing the mtdinfo -a output for the partitions, everything is exactly the same except for the eraseblocks, which are 8192 on all partitions for the original image, and 131072 bytes on all partitions for the new image. This actually means that the erase block is greater than the partition size for the bootscr partition we're concerned about.

This could be because I updated only the image.ub, and not all files (so I might actually still be using an old device tree as far as U-Boot is concerned)... After uploading all of the files,