-
Notifications
You must be signed in to change notification settings - Fork 0
Upgrading LOKI Kernel Version
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.
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.
- Select a new source with
petalinux-config
- Configure the chosen source (e.g. repository, branch, checksum etc) with
petalinux-config
- Attempt a re-build, and correct any issues
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
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 andgit //
|corrections listed below in troubleshooting]]. e.g.git://github.com/Xilinx/linux-xlnx.git;protocol=https
underRemote linux-kernel git URL
- Add the latest commit to the branch you have chosen (or a tag)
- If using the Xilinx repository (recommended): https://github.com/Xilinx/linux-xlnx/branches/all
- 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.
#TODO
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.
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.
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
.
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
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"
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.
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,