Author Topic: Mismatch between the Linux kernel version and the kernel-headers in Raspberry Pi  (Read 2100 times)

0 Members and 1 Guest are viewing this topic.

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6720
  • Country: ro
The question is, how do I install the correct version of kernel-headers for whatever uname -r kernel would be running on a random Raspberry Pi?




Long story is, I want to compile some loadable kernel module for the currently running version of the Linux kernel.  To install the Linux headers, there is an apt package in the Raspberry Pi repositories, named raspberrypi-kernel-headers.

However, raspberrypi-kernel-headers is for an older kernel version (from a year ago) than the running kernel.  Yet, the package wrongly installs as if it were for the currently running kernel version.  :scared:

As a result, all kind of weird errors might appear during a compilation.  Even worst, for some modules the compilation might succeed without errors, yet the loading and running of the compiled driver will throw all kind of strange errors at runtime.  :o

Took me a day to figure out that sudo apt install raspberrypi-kernel-headers installed a wrong version of headers for the currently running kernel.  :horse:

Currently running Raspberry OS (based on Debian 12 Bookworm) is from a fresh SD card imaged with '2024-03-15-raspios-bookworm-armhf-lite.img.xz'.

Code: [Select]
        uname -a
            Linux rpi 6.6.20+rpt-rpi-v6 #1 Raspbian 1:6.6.20-1+rpt1 (2024-03-07) armv6l GNU/Linux
           
        uname -r
            6.6.20+rpt-rpi-v6

        apt policy raspberrypi-kernel-headers
            raspberrypi-kernel-headers:
              Installed: (none)
              Candidate: 1:1.20230405-1
              Version table:
                 1:1.20230405-1 500
                    500 http://archive.raspberrypi.com/debian bookworm/main armhf Packages

Kernel and headers from the apt repository 1.20230405-1 corresponds to kernel version 6.1.21+ from a year ago, while the current running version is 6.6.20+rpt-rpi-v6.

I've learned that for Raspberry Pi the kernel is seen as firmware update, and there is a dedicated tool for that, named rpi-update.  When run without arguments, with sudo rpi-update, it downloads and installs the latest kernel for Raspberry Pi (from the github repository), and at the next boot the newest kernel will be in effect.  When an argument is given, it will download and install from the location specified as an argument.  The argument can be a git commit ID, or the URL of a git tag asset from github.  For example:

Code: [Select]
sudo rpi-update https://github.com/raspberrypi/firmware/archive/refs/tags/1.20230405.tar.gz
sudo reboot

will downgrade the currently running kernel 6.6.20+rpt-rpi-v6 to the 6.1.21+ kernel from last year.


So far (as a workaround) I've used rpi-update to downgrade the current kernel 6.6.20+rpt-rpi-v6 to 6.1.21+ from last year, because the today kernel-headers from the apt repos are also for 6.1.21+.  So, I've downgraded the kernel to a version from a year ago, then install the current 'sudo apt install raspberrypi-kernel-headers' from today apt repositories, which for some reason I don't understand, happens to contain the kernel-header for the 6.1.21+ from a year ago.  :-//

Now, my own loadable module compiles and runs without errors, but with the last year kernel.  This is only a hack.  I would like to use a more recent kernel and be able to compile for that one.  Preferably the one that came with the current Raspberry OS Bookworm, kernel 6.6.20+rpt-rpi-v6.[/s]

How do I install the correct version of kernel-headers for whatever uname -r kernel would be running on a random Raspberry Pi?[/s]



Later edit:
-------------
After digging for a few more days, turns out many of the above was because of my misunderstanding.  Too hard to correct, so will just strikeout the text, my bad, sorry.  Also, for either Bullseye or Bookworm Raspberry OS lite I've tried, the kernel headers are already included when flashing the stock image on the SD card, no additional headers installs needed.  For Bookworm, the kernel sources, too, (not only the headers) seems to be included in the stock SD card image.
« Last Edit: April 11, 2024, 09:30:17 am by RoGeorge »
 

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6720
  • Country: ro
Found a tool rpi-source that does exactly that:  searches and install from github the Raspberry Pi kernel sources and headers corresponding to the (uname -r) running version of the kernel.
https://github.com/RPi-Distro/rpi-source

Seems to be working, but I still get some strange warnings (when compiling and/or running my LKM driver sources) with any kernel from Bookworm RPi OS, stock or latest.  However, my LKM driver sources compile and also also run just fine with the stock kernel from Bullseye (6.1.21+), no matter that I using that kernel with Bookworm of with Bullseye.

Might be some other issue and/or bugs/incompatibility specific to kernel 6.6 and not present in 6.1, but that's another topic.

The above rpi-source can bypass the apt repository, and retrieve the proper kernel sources and headers straight from github.  Very useful tool, thanks to the author(s)!  :-+

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6720
  • Country: ro
After more reading, found out that there is a major change between version 6.1.y (from Bullseye) and 6.6.y of the Raspberry Pi Linux kernel.  https://forums.raspberrypi.com/viewtopic.php?t=361116

The support for GPIO sysfs has been deprecated in the favor of ioctl.  This breaks compatibility with all the former GPIO handling code and drivers written in the past 10 years or so of Raspberry Pi.  :-\

From this year onward (Raspberry Pi Linux kernel >= 6.6), the access to GPIO ports, PWM, etc. must be made using ioctl gpiod (libgpiod).

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4011
  • Country: ua
for current kernel version you can install it with:
Code: [Select]
sudo apt install linux-headers-rpi-v8
where v8 is your kernel type, in this case v8 is for aarch64, for 32 bit v7l.

if you're installed another kernel, then there is no kernel headers, and you're needs to get source code of your installed kernel and build kernel headers manually.

You can restore current kernel version with this:
Code: [Select]
sudo apt install --reinstall raspi-firmware
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4011
  • Country: ua
The support for GPIO sysfs has been deprecated in the favor of ioctl.  This breaks compatibility with all the former GPIO handling code and drivers written in the past 10 years or so of Raspberry Pi.  :-\

just use
Code: [Select]
gpio_desc = gpiod_get(&pdev->dev, "mypin", GPIOD_ASIS);
irqNumber = gpiod_to_irq(gpio_desc);


and replace gpio_unexport(gpioPin) with
Code: [Select]
gpiod_put(gpio_desc);
also may need to add pin description to dts file


There is also minor changes in headers for drivers, use class_create(CLASS_NAME); instead of class_create(THIS_MODULE, CLASS_NAME);
« Last Edit: April 09, 2024, 08:21:26 am by radiolistener »
 
The following users thanked this post: RoGeorge

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6720
  • Country: ro
Thanks for the hints, that was very useful.  Have a lot of question, but I need to read and practice a little more with the old gpio access style before asking.  I don't have a good enough understanding of how it all works.

The workshop I am following is for the old style of gpio access (as it was in Raspberry OS Bullseye).  I've tried to modify a very simple working example to the new gpiod style, and it didn't work.  ;D

Since I'm not a programmer, I find a little difficult to instantiate the documentation pages https://www.kernel.org/doc/html/latest/driver-api/gpio/index.html into code examples for the current gpiod.  For now I am still learning, don't have yet the full picture of how the device tree, the driver and the kernel interact together.
« Last Edit: April 11, 2024, 10:29:26 am by RoGeorge »
 

Offline Perkele

  • Regular Contributor
  • *
  • Posts: 59
  • Country: ie
I was using gpiod with C++ wrapper, it was OK after working around a couple of issues.

If you're going to use libgpiod to access the GPIO pins, there was a "feature" a couple of years ago where "event_wait()" function would not detect an already active event when you call the function.
In other words - configure the pin to generate an event on state change, and if pin is already active when you call the function, you can't detect that state change.

On top of that, event timestamps on Raspbian were...weird. They did not contain values that I would expect, and I have seen this only with Raspberry Pi.
To work around it I just used CLOCK_MONOTONIC or CLOCK_BOOTTIME as time source for my own timestamps.
 

Online DiTBho

  • Super Contributor
  • ***
  • Posts: 4230
  • Country: gb
On top of that, event timestamps on Raspbian were...weird. They did not contain values that I would expect, and I have seen this only with Raspberry Pi.
To work around it I just used CLOCK_MONOTONIC or CLOCK_BOOTTIME as time source for my own timestamps.

Yeah, timestamps on Raspbian is weird, but the whole rpi is weird, and the people who use it for mission critical NAS are weird too.
But hey? you say it in a Youtube comment, and guess what the title of the next Jeff's video? Again RPI-NAS, this time with 2K euro SSDs
So ... I am not surprised if they continue to do strange things, and the distribution developers continue to support erratically  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf