Compiling Out-Of-Tree Kernel Module Against Any Kernel Source Tree on the Filesystem

Compiling out-of-tree kernel module against any kernel source tree on the filesystem

goal is to have it compile against any source tree

ya you can do it providing a compiled source-code path

just replace make -C /lib/modules/$(shell uname -r)/build M=$PWD modules

with this

make -C <path-to-compiled-src-code> M=$PWD modules

make -C /home/vinay/linux-3.9 M=$PWD modules

try below makefile

Makefile –

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

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

In above you can change KERNEL_SOURCE := /usr/src/linux-->to.--> your sr-code KERNEL_SOURCE := <path to compiled-src-code>

for further info find below liks

while building kernel modules why do we need /lib/modules?

A simple program on linux device driver

How to make a built-in device driver in linux

How can I prepare a Linux source tree so an external module can be compiled against it?

The target you are looking for is modules_prepare. From the doc:

An alternative is to use the "make" target "modules_prepare." This will make sure the kernel contains the information required. The target exists solely as a simple way to prepare a kernel source tree for building external modules.

NOTE: "modules_prepare" will not build Module.symvers even if CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be executed to make module versioning work.

If you run make -j modules_prepare (-j is important to execute everything in parallel) it should run pretty fast.

So what you need is basically something like this:

# Prepare kernel source
cd '/path/to/kernel/source'
make localmodconfig
make -j modules_prepare

# Build your module against it
cd '/path/to/your/module/source'
make -j -C '/path/to/kernel/source' M="$(pwd)" modules

# Clean things up
make -j -C '/path/to/kernel/source' M="$(pwd)" clean
cd '/path/to/kernel/source'
make distclean

The last cleaning up step is needed if you are in a bisect run before proceeding to the next bisection step, otherwise you may leave behind unwanted object files that might make other builds fail.

while building kernel modules why do we need /lib/modules?

while building kernel modules why do we need /lib/modules?

Its not a compulsory to give above option i.e /lib/modules The main intention is to get configured source-code directory .

You can set to directly configured source-code or u can provide above i.e /lib/modules/ which having softlink for built source-code.

KDIR,

you can either set full kernel source directory (configured and compiled) or just kernel headers directory (minimum needed).
Two solutions

1)Full kernel sources

2)Only kernel headers (linux-headers-* packages in
Debian/Ubuntu distributions)

where in both case The sources or headers must be configured.Many macros or functions depend on the configuration

-C option calls the kernel Makefile, passing the module
directory in the M variable ,the kernel Makefile knows how to compile a module
.

for e.g if you configure your kernel for Arm architecture or machine then configured kernel Makefile will tell how to compile and for which arhitecture your modules should be built.

To be compiled, a kernel module needs access to the kernel
headers, containing the defnitions of functions, types and
constants
.

Can it be build solely?

No you cant build solely since you module should should know for which kernel you want to build it and which configuration it needs to be compiled so that while inserting your module
All respective symbols and configuration should be matched. All this can be done through toplevel Makefile of configured kernel.

Eudyptula Challenge and kernel path

As per Eudyptula challenge rules, it is prohibited to give you direct solution, so I will try to describe elements of answer, so you can come up with solution by yourself. Basically, everything I've written below is described pretty much in Documentation/kbuild/modules.txt file (especially in section 3.1 - Shared Makefile ), so I don't think it would be some sort of rules violation. So below is just explanation for what is described in mentioned documentation.

KERNELRELEASE variable

What you are wrong about is thinking that $(KERNELRELEASE) is intended for keeping the path to the kernel. What $(KERNELRELEASE) variable actually means -- you can find it in Documentation/kbuild/makefiles.txt:

KERNELRELEASE

$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable
for constructing installation directory names or showing in
version strings. Some arch Makefiles use it for this purpose.

The thing is, your Makefile is going to be executed 2 times: from your make command and from kernel Makefile. And $(KERNELRELEASE) can be helpful to figure it out:

  1. If this variable is not defined, your Makefile is running from your make command; at this step you are going to execute kernel's Makefile (providing kernel directory using -C param). Once you have run make for kernel's Makefile (from inside of your Makefile), your Makefile is going to be executed second time (see next item).
  2. If this variable is defined, your Makefile is executing from kernel's Makefile (which defined this variable and called your Makefile back). At this step you can use kernel build system features, like obj-m.

-C param

What you really need to do is define some custom variable in your Makefile which will hold kernel directory path. You can call it KDIR for example. As you know, your kernel sources are located at this path: /lib/modules/$(shell uname -r)/build. Next you can provide this variable to -C param (see man 1 make) when executing kernel's Makefile.

Next you have to make it possible to pass this variable from outside of your Makefile. To do so, one can use conditional variable assignment operator:

KDIR ?= /lib/modules/$(shell uname -r)/build

This way if you pass KDIR variable to your Makefile, like this:

$ make KDIR=bla-bla-bla

the KDIR variable will have the value you passed. Otherwise it will contain default value, which is /lib/modules/$(shell uname -r)/build.

Error when inserting kernel module: module * uses symbol * from namespace *, but does not import it

It turned out that the source uses kernel_read() function, which requires importing the VFS namespace outside a file system module. This can be done with adding this declaration before the statement calling to kernel_read():

MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);

This fix should be applied to each file which called to kernel_read() in the source tree.



Related Topics



Leave a reply



Submit