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 archMakefiles
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:
- If this variable is not defined, your
Makefile
is running from yourmake
command; at this step you are going to execute kernel'sMakefile
(providing kernel directory using-C
param). Once you have runmake
for kernel's Makefile (from inside of your Makefile), yourMakefile
is going to be executed second time (see next item). - If this variable is defined, your
Makefile
is executing from kernel'sMakefile
(which defined this variable and called yourMakefile
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
How to Limit File Size on Commit
How to Change the Mime Type of a File from the Terminal
Linux Kernel: How to Capture a Key Press and Replace It with Another Key
How to Install Influxdb in Windows
Service Doesn't Support Chkconfig
Does Madvise(_, _, Madv_Dontneed) Instruct the Os to Lazily Write to Disk
Automated Test Tools for Linux/Ncurses
Increase of Virtual Memory Without Increse of Vmsize
Dependency Walker Equivalent for Linux
Shell Script Get Ctrl+Z with Trap
Find All Files Matching 'Name' on Linux System, and Search with Them for 'Text'
Using Named Pipes with Bash - Problem with Data Loss
Using Output of Awk to Run Command
Can 'Connect' Call on Socket Return Successfully Without Server Calling 'Accept'