Debugging a Kernel Module

I have an old Soundgraph iMon input device from the front panel of an HTPC that has buttons for controlling audio/video playback (play, stop, volume, etc) plus a 16 character by two line VFD module and infra red sensor. After following the steps in “Troubleshooting input devices in linux” I determined the device is supported by the Debian/Raspbian imon kernel module and, although the module does recognize the device, the buttons are not generating any input events. The next step is to look at the module source code to figure out why not.

Download Kernel Sources

In order to build a kernel module you have to have kernel sources and the sources must match the kernel version in use. You can find out the current kernel version using uname:

uname -r
4.9.36-v7+

So in this case we need sources for the module that match linux kernel 4.9.36-v7+. On the Raspberry Pi someone has made a handy script to simplify this task. First fetch the script:

sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update

Then run it:

rpi-source

and it should download and install the correct sources. More information about the script and building modules on Raspbian can be found here.

Get The Module’s Source Code

Make a directory for our module’s source code and copy the source (which will have been downloaded with the rest of the kernel sources) into the directory:

mkdir imon
cd imon
cp /lib/modules/$(uname -r)/build/drivers/media/rc/imon.c ./

Create a makefile for the module:

nano Makefile

and add the following:

obj-m := imon.o

Then hit <ctrl>-x to save and quit.

Build the Module

Before monkeying with the source lets just make sure we can build the module using this command which indicates where the kernel sources are and the Makefile we want to use:

sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules

Load Our Module

To load the module we first unload the old module:

sudo rmmod imon

Note: if the module is in use by a service then it may not unload, in which case you will need to identify which services are using it and stop them before attempting to unload the module.

Then load our module which has a debug option that we’ll enable:

sudo insmod imon.ko debug=1

Then check the module was loaded without a problem:

dmesg

If that all worked then we can go ahead and modify the source, then build the module and reload it by repeating the above steps.

Installing Our Module

Once we have the module working the way we want we can install it so that it is automatically used every time the system reboots.

First backup the original module:

sudo mv /lib/modules/$(uname -r)/kernel/drivers/media/rc/imon.ko /lib/modules/$(uname -r)/kernel/drivers/media/rc/imon.ko.bak

Then copy the new module into the correct folder:

sudo cp ./imon.ko /lib/modules/$(uname -r)/kernel/drivers/media/rc/imon.ko

Then enable it:

sudo depmod -a