44

I have a bug in a Linux kernel module that causes the stock Ubuntu 14.04 kernel to oops (crash).

That is why I want to edit/patch the source of only that single kernel module to add some extra debug output. The kernel module in question is mvsas and not necessary to boot. For that reason I don't see any need to update any initrd images.

I have read a lot of information (as shown below) and find the setup and build process confusion. I need two recipes:

  1. to setup/configure the build environment once
  2. steps to do after editing any source file of this kernel module (.c and .h) and converting that edit into a new kernel module (.ko)

The sources that have been used are:

2

1 Answer 1

45

The recipe to build a custom module might need to be split in three sections.

Setup once

$ cd ~
$ apt-get source linux-source-3.13.0 

I am too lazy to copy the mvsas specific driver source files; just copy them all to your current working directory. If apt-get results in an error message about missing source URIs then see note #4 at the bottom.

$ cd linux-3.13.0
$ make oldconfig
$ make prepare
$ make scripts

This will prepare some files necessary to build a kernel module.

Each kernel version

$ apt-get install linux-headers-$(uname -r)

This will install headers and the Ubuntu kernel configuration file for that kernel version in /lib/modules.

$ cd ~/linux-3.13.0
$ cp -v /usr/src/linux-headers-$(uname -r)/Module.symvers .

This to prevent the message "no symbol version for module_layout" when loading the module with insmod or modprobe.

$ mv -v /lib/modules/$(uname -r)/kernel/drivers/scsi/mvsas/mvsas.ko /lib/modules/$(uname -r)/kernel/drivers/scsi/mvsas/mvsas.ko.backup

This will rename the original (Ubuntu build) kernel module to make sure that the custom patched one will load.

Each edit

$ cd ~/linux-3.13.0/drivers/scsi/mvsas
$ nano mv_sas.h
$ nano mv_sas.c

These are for the edits.

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

This will compile and build the kernel module .ko file using the kernel configuration from your stock Ubuntu distribution as stored in /lib/modules/$(uname -r)/.

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

This will install the kernel module in /lib/modules/$(uname -r)/extra/, not overwriting the distribution module in case you didn't rename the distribution kernel module file. In this mvsas case it will also run depmod.

$ lsmod | grep mvsas

If this results in any output, the mvsas module needs unloading with (modprobe -r mvsas) first.

$ sudo modprobe -v mvsas

This should load the new kernel module.

Check the output to verify that /lib/modules/.../extra/mvsas.ko is being loaded.

Modprobe error: could not insert

In some cases you might experience a modprobe: ERROR: could not insert 'xyz': Unknown symbol in module, or unknown parameter (see dmesg) while in the verbose modprobe output you see that insmod is trying to load the module from the kernel default location. For example:

# insmod /lib/modules/3.17.0-031700rc7-generic/kernel/drivers/scsi/pm8001/pm80xx.ko
modprobe: ERROR: could not insert 'pm80xx': Unknown symbol in module, or unknown parameter (see dmesg)

In that case you need to manually run depmod and try to load the module again:

# depmod
# sudo modprobe -v mvsas

Notes

  1. It may be the case that the resulting .ko module files are much (for example 20 times) larger in size than the original module files as distributed by Ubuntu; in that case the make prepare step could have created a Linux developers debugging kernel configuration file and you are building from the source directory. Your -C param might not function as expected.
  2. I have seen guides with other commands like make modules_prepare and make M=scripts/mod but I don't think these are necessary for this case.
  3. You can use the Linux developers debug config by replacing -C /lib/modules/$(uname -r)/build with -C /usr/src/linux-headers-$(uname -r)
  4. In a default setup, apt-get source linux-sources will return error E: You must put some 'source' URIs in your sources.list. To fix this issue you can modify file /etc/apt/sources.list by uncommenting (removing the leading # from) the first deb-src line. Example for Ubuntu 17.10: deb-src http://ie.archive.ubuntu.com/ubuntu/ artful main restricted. run sudo apt-get update, and then the command will deliver sources for you. See also this question where a GUI method for doing this is described too.
11
  • I got error: /bin/sh: arm-none-linux -gnueabi-gcc: not found
    – Dr.jacky
    Sep 16, 2015 at 10:20
  • $(uname-r) is apparently wrong... You need to call the shell built-in: $(shell uname -r) Nov 21, 2015 at 8:35
  • 2
    @AlbusDumbledore I also see cases where $(shell uname -r) doesn't work. Why is $(uname -r) so apparently wrong?
    – Pro Backup
    Apr 8, 2016 at 9:55
  • I had to also call echo "search extra built-in" | sudo tee /etc/depmod.d/00-extra.conf so that depmod sees the newly updated file in .../extra. Aug 31, 2016 at 13:11
  • 1
    What to do with module signing error, how to avoid it? ``` INSTALL /home/envek/linux-4.10.0/drivers/hwmon/dell-smm-hwmon.ko At main.c:158: - SSL error:02001002:system library:fopen:No such file or directory: bss_file.c:175 - SSL error:2006D080:BIO routines:BIO_new_file:no such file: bss_file.c:178 sign-file: certs/signing_key.pem: No such file or directory ```
    – Envek
    May 27, 2017 at 21:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .