Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:

share|improve this question
up vote 14 down vote accepted

The recipe to build a custom module might need to be split in thee 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.

$ 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 any output, the mvsas module needs unloading $ modprobe -r mvsas first.

$ 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
# modprobe -v mvsas

Notes

1. In case the resulting .ko module files that 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)

share|improve this answer
    
I got error: /bin/sh: arm-none-linux -gnueabi-gcc: not found – Mr.Hyde Sep 16 '15 at 10:20
    
$(uname-r) is apparently wrong... You need to call the shell built-in: $(shell uname -r) – Albus Dumbledore Nov 21 '15 at 8:35
1  
@AlbusDumbledore I also see cases where $(shell uname -r) doesn't work. Why is $(uname -r) so apparently wrong? – Pro Backup Apr 8 at 9:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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