19

Following this tutorial to write my first driver.

The Makefile is:

# Makefile – makefile of our first driver

# if KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq (${KERNELRELEASE},)
    obj-m := ofd.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
    KERNEL_SOURCE := /usr/src/linux 3.8
    PWD := $(shell pwd)
default:
    ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules

clean:
    ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif

And the driver code is :

* ofd.c – Our First Driver code */
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>

static int __init ofd_init(void) /* Constructor */
{
    printk(KERN_INFO "Namaskar: ofd registered");
    return 0;
}

static void __exit ofd_exit(void) /* Destructor */
{
    printk(KERN_INFO "Alvida: ofd unregistered");
}

module_init(ofd_init);
module_exit(ofd_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>");
MODULE_DESCRIPTION("Our First Driver");

There is no error during make. But when I use insmod ofd.ko I'm unable to load it. In dmesg it says:

disagrees about version of symbol module_layout

  • uname -r returns '3.8.0-38-generic' and the kernel source also 3.8.
  • modprobe -f ofd.ko also fails

Also:

#56~precise1-Ubuntu SMP Thu Mar 13 16:23:47 UTC 2014
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.4 LTS
Release:    12.04
Codename:   precise

What is happening?

1
  • Some obvious comments. First is the kernel source exactly the same as the Ubuntu kernel? You should be using the Ubuntu kernel source corresponding exactly to your kernel. Upstream will probably not work, since distributions patch their kernels. Second, afaik you can compile against the kernel headers, you don't need the kernel source. The headers should also be available as a binary package. You may also want to take a look at the the Debian Kernel Handbook, which has instructive stuff about kernels etc. on Debian, which also applies to Ubuntu. Commented Apr 20, 2014 at 20:01

1 Answer 1

21

The Linux kernel contains data structures whose layout varies not only from version to version but also depending on the compilation options. As a consequence, when you compile a kernel module, you need to have not only the header files from the kernel source, but also some header files that are generated during the kernel compilation. Merely unpacking the kernel source isn't enough.

With kernels built with the CONFIG_MODVERSIONS, the version number can differ, but the layout of the data structures must be the same. This option is activated in the Ubuntu kernels. With this option, in addition to the headers, modules need to be compiled against the proper Module.symvers file. Ubuntu, like most distributions, includes this file in the same package as the kernel headers resulting from the compilation. The Ubuntu kernel header package is called linux-headers-VERSION-VARIANT, e.g. linux-headers-3.8.0-38-generic.

With kernels built without the CONFIG_MODVERSIONS (which may be the case if you compiled your own kernel), the check when loading a module is a simple version check. You can take the unpacked kernel source, copy the .config that was used during the compilation of your running kernel, and run make modules_prepare. The onus is on you to verify that any patch you've made to the kernel doesn't affect binary compatibility.

1
  • 1
    how does the linux kernel knows that the module have different symbols though? Commented Jul 15, 2021 at 0:14

You must log in to answer this question.

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