1

The problem

I am attempting to build a DKMS based module in pi-gen and not having any luck finding raspberrypi-kernel-headers.

I am working in stage3 of the pi-gen build. I have the following steps

00-configure-apt where I add 2 private repositories to the public repositories initially added in stage0.

01-misc-config I add sudo without password capabilities to the default user.

02-install-hd44780-i2c (where the problem is). This step has a single 00-packages file containing:

raspberrypi-kernel-headers
dkms
udev
hd44780-i2c

Which is a bit of overkill since the fist 3 are declared in the 4th's dependency list anyway.

However the problem is that they system responds with:

DKMS: add completed.
Error! echo
Your kernel headers for kernel 5.4.0-58-generic cannot be found at
/lib/modules/5.4.0-58-generic/build or /lib/modules/5.4.0-58-generic/source.
dpkg: error processing package hd44780-i2c (--configure):
 installed hd44780-i2c package post-installation script subprocess returned error exit status 1

Notes:

  • I am running pi-gen in the standard pi-gen Docker image running on Ubuntu 18.04.5 LTS.
  • 5.4.0-58-generic is the version of the system running the build.
  • uname -n in the scripts returns the build system kernel version.
  • I know that the version I want (for this build) is "5.4.79+" and that if I execute find / -name 5.4.79+ -type d in a run-chroot.sh returns /usr/lib/modules/ as the directory. So executing ls -1 /usr/lib/modules/ | head -1 will return a valid kernel version.
  • I can find no other way to determine what kernel pi-gen is installing.

As an attempted fix I added apt-get install raspberrypi-kernel-headers to stage0/00-configure-apt/00-run.sh. The result was that the headers were pulled and installed. However stage 3 can not see them.

After much messing about I added three packages as 00-packages

raspberrypi-kernel-headers
dkms
udev

I then discovered that the kernel being installed could be found in /usr/lib/modules in a run-chroot.sh script so I added 01-run-chroot.sh

#!/bin/sh -e
echo $PWD
find / -name 5.4.79+ -type d

export kernelver=`ls -1 /usr/lib/modules/ | head -1`
export KERNELDIR=/usr/lib/modules/${kernelver}/build

export

The result does show that kernelver is being set as expected and KERNELDIR is set as well.

Finally I created a 02-packages that contains the package to install

hd44780-i2c

I also attempted to add apt install hd44780-i2c to the 01-run-chroot.sh, that yielded the same result.

The makefile for the hd44780-i2c package is:

VERSION=1.0.0

ifneq ($(KERNELRELEASE),)
    obj-m := hd44780-i2c.o
    hd44780-i2c := hd44780-i2c.o

else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)

default:
    echo "START OF DEBUG"
    export
    echo "END OF DEBUG"
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

endif

And the latest output (noted above) appears to show that the else portion of the build Makefile is being executed

What I think I need

I think that I need to be able to get the KERNELDIR variable set in the environment where dkms executes in. But I can't seem to figure out how to do that.

Does anybody have a suggestion for how to resolve this issue?

As an aside, this seems to be a bit "wobbly" -- that is it doesn't smell right. Is there a proper way to create a Debian install that uses dkms to install a kernel module and call that installer from pi-gen?

1

As noted above the problem is to get the proper kernel version into the DKMS build. I solved this by modifying pigen as well as the dkms call in the package being installed.

PIGEN Changes

in pigen/build.sh I added a function to capture the versions

check_kernel_version()
{
    if [ -z "${DKMS_VERSIONS}" ]
    then
        if [ 0 -lt `find ${ROOTFS_DIR}/usr/src -name linux-headers\* -type d | wc -l` ]
        then
            for fn in `cat ${ROOTFS_DIR}/usr/src/linux-headers*/include/config/kernel.release`
            do
                export DKMS_VERSIONS="${DKMS_VERSIONS} -k ${fn}"
            done
        fi
        log "====> Kernel Version: '${KERNEL_VERSION}'"
    fi
}

This function sets a ${DKMS_VERSIONS} environment variable if it is not set and the linux-headers have been installed. It adds all the kernel versions to the DKMS_VERSIONS variable as a series of -k version strings.

I modified the run_sub_stage function so that it calls check_kernel_version at the end of ${i}-packages-nr and ${i}-packages stages. This picks up the versions as soon as the kernel headers are added.

DKMS Project Changes

in the postinst script for the dpgk installation of the DKMS based project add the DKMS_VERSIONS variable to the dkms commands.

        dkms build ${DKMS_VERSIONS} hd44780-i2c/1.0
        dkms autoinstall ${DKMS_VERSIONS}  hd44780-i2c/1.0

This then tells dkms to use the versions specified with the -k option rather than asking the system what kernel it is building on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.