How do I properly compile a kernel module?

I need to compile a specific kernel module to solve a compatibility problem for a device managed by an older driver. The module I need to compile is i2c-hid-of-elan.

Normally you compile the entire kernel, not just one module.

Edit: If you know what you are doing, you can build the module “out of tree”. See Barry’s reply below.

There is some documentation for doing that on Fedora Linux, but I have not tried to use it in ages, so I cannot speak to how up-to-date the documentation is.

1 Like

In the process of researching the subject, I ended up on the same page, but the kernel compiled by the Fedora project meets most of my needs - very well, by the way - in fact, I’m not sure if the module in question would solve the problem, I’d have to test it. Compiling the kernel with the custom modules would be time consuming, and I don’t have enough computing resources to do it in time. In any case, if it is the solution, it would add more complexity to the system upgrade process.

1 Like

When building an out of tree module it’s normal to just build the module against your kernel. I have only built the full kernel after I have debugged a kernel module that I have built by it’s self.

This is what all those DKMS and AKMODS builds do.

2 Likes

True. I misspoke. I was trying to remember how I did it when I took courses on kernel development many years ago. We (as students) would iterate on make clean, make bzimage, make modules, sudo make install, and sudo make modules_install (just going from memory). The first compile took a while, but then if you skip the make clean, make would typically only recompile the changes and it was (reasonably) fast. ccache also helped.

I’ve never tried to compile an out of tree module without using DKMS or AKMODS.

I strongly recommend using dkms or akmods if you’re going to do this. Otherwise, you’re going to need to recompile the module for every kernel update.

1 Like

So… what would be the most appropriate approach using akmods and dkms? Should I download the module manually, via git or somehow via the repositories? Although I’ve looked, I haven’t found any very reliable or explicit sources.

That module depends on a certain feature:

It might be difficult to build with DKMS or akmods.
You should follow the instructions linked in the first reply:
How do I properly compile a kernel module? - #2 by glb

When you reach the make menuconfig step, enable this:

2 Likes

I followed the instructions. Correct me if I have misunderstood, but all the kernel modules were compiled, I tried to check each step manually, I used all the threads available, and after 3 hours the kernel was compiled, after the installation, when I tried to shutdown to run the new kernel, my user was prevented from doing so. I decided to undo the installation. The compiled kernel takes up 28.8 GiB of the disc.

I’ve never had that problem. However, I think there are some akmods (e.g. Nvidia) that will start a build process in the background whenever you install a new kernel. Is it possible that your shutdown was inhibited due to a akmod build that was running in the background?

No. Akmods does not inhibit shutdown.
It is a recurring issue here that people reboot before the nvidia driver as built.

Here’s how I usually go about building kernel modules for quick testing.
Note that this will probably not work if you have Secure Boot enabled, as the modules will not be signed properly. Disable Secure Boot for testing purposes or configure signing accordingly to make it work.

  1. sudo dnf install kernel-devel
  2. Download a copy of the kernel sources. Either from git or from kernel.org. It’s usually best to choose a version that either matches or is very close to the version you are running. You can also download the source RPM for the actual Fedora kernel.
  3. Within the kernel sources folder navigate to the path of the driver you want to build:
    cd drivers/hid/i2c-hid
  4. Build the driver:
    make -C /lib/modules/`uname -r`/build M=`pwd` CONFIG_I2C_HID_OF_ELAN=m modules
    Note that you manually have to set CONFIG_I2C_HID_OF_ELAN=m as this driver is not enabled in the default config of the Fedora Kernel.
  5. Install the driver:
    sudo make -C /lib/modules/`uname -r`/build M=`pwd` CONFIG_I2C_HID_OF_ELAN=m modules_install
    Note that this will also install additional modules that the module you built depends on or that the default configuration builds as well.
  6. Check that the driver is available:
    modinfo i2c-hid-of-elan
    This should show you information for a kernel module that resides in the update subdirectory in your kernel module path.
  7. Load the new driver:
    modprobe i2c-hid-of-elan
1 Like

Should depmod be run as well?

It runs automatically upon modules_install.

Only if you remove the updates directory manually later (to remove the out-of-tree modules) you’d have to re-run depmod yourself.

1 Like

You’re right. CONFIG_I2C_HID_OF_ELAN=m is the default. I missed that.

It’s enabled by default on aarch64, which I assumed @arthur-valada was using because Fedora doesn’t support OF on x86_64.
If the driver was to be of any use to @arthur-valada it would have to be on a system that already boots using OF.

If @arthur-valada is indeed trying to use the aforementioned driver on an x86 machine I am sensing we might be looking at an XY Problem (Excuse the less-than-gracious writing style on that page. I’m not meaning to be rude about it. But it most succinctly summarizes what an XY problem is).