I'm trying to compile the simplest kernel module possible, from the The Linux Kernel Module Programming Guide. hello.c:
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
Makefile:
obj-m = hello.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
Output of make:
make -C /lib/modules/5.14.0/build M=/home/parallels/dev/demo modules
make[1]: Entering directory '/home/parallels/linux-5.14'
CC [M] /home/parallels/dev/demo/hello.o
MODPOST /home/parallels/dev/demo/Module.symvers
ERROR: modpost: missing MODULE_LICENSE() in /home/parallels/dev/demo/hello.o
make[2]: *** [scripts/Makefile.modpost:150: /home/parallels/dev/demo/Module.symvers] Error 1
make[2]: *** Deleting file '/home/parallels/dev/demo/Module.symvers'
make[1]: *** [Makefile:1766: modules] Error 2
make[1]: Leaving directory '/home/parallels/linux-5.14'
make: *** [Makefile:4: all] Error 2
This is all after I have compiled the linux kernel from source and run make modules_install. I don't really understand that second line of output: make[1]: Entering directory '/home/parallels/linux-5.14', that is the directory in which I downloaded and compiled the linux kernel, I don't see what it has to do with this module I'm trying to compile.
I have seen others ask about this missing MODULE_LICENSE() error, but they are usually asking about much more complicated modules and the answers don't seem relevant to this very simple module. A few of the answers had to do with changing the name of either the source code file or the .o file, but trying either way simply produced errors about no rule to make target with the changed name.
Also, this is all on a vm of Kali linux running linux kernel 5.14.0 which I compiled from source.
You need to add call to MODULE_LICENSE to your source file (hello.c in your case). This is what the error message is talking about. E.g.
MODULE_LICENSE("GPL");
Most modules also call MODULE_AUTHOR:
MODULE_AUTHOR("your-name");
Related
I'm doing some experiment on rpi4, and trying to reproduce this kernel module from github https://github.com/sysprog21/dont-trace on my rpi4. I encounter this problem:
make -C /lib/modules/`uname -r`/build M=/home/ubuntu/dont-trace modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.65-rt49-preemptrt-full-raspi'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110
You are using: gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
CC [M] /home/ubuntu/dont-trace/dont_trace.o
/bin/sh: 1: scripts/basic/fixdep: Exec format error
make[2]: *** [scripts/Makefile.build:289: /home/ubuntu/dont-trace/dont_trace.o] Error 126
make[2]: *** Deleting file '/home/ubuntu/dont-trace/dont_trace.o'
make[1]: *** [Makefile:1896: /home/ubuntu/dont-trace] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.15.65-rt49-preemptrt-full-raspi'
make: *** [Makefile:7: all] Error 2
The kernel here is cross-compiled from x86 server and do show above. I was wondering how to solve this problem & what's the root cause. I can make it on x86 server. It should be something fundamental knowledge I don't understand. Thks!
it seems work this time
My solution might be a bit workaround, but it works. I follow the clues /bin/sh: 1: scripts/basic/fixdep: Exec format error. So I copy the source code to local raspberry pi, and make modules_prepare to construct complete /scripts, then move it into /lib/modules/`uname -r\`/build. It remain the gcc version warning, but work properly.
I am having some issues cross-compiling a module for the Raspberry Pi 4.
The compiler used is: aarch64-linux-gnu-.
The kernel used is: linux-5.10.42
And the error during compilation is as follows:
make -C /opt/linux-5.10.42 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- M=/home/x/build/linux-driver-gpio-customled modules
make[1]: Entering directory '/opt/linux-5.10.42'
CC [M] /home/x/build/linux-driver-gpio-customled/customled.o
In file included from ./include/linux/types.h:6,
from ./include/linux/list.h:5,
from ./include/linux/module.h:12,
from /home/x/build/linux-driver-gpio-customled/customled.c:1:
./include/uapi/linux/types.h:5:10: fatal error: asm/types.h: No such file or directory
5 | #include <asm/types.h>
| ^~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.build:279: /home/x/build/linux-driver-gpio-customled/customled.o] Error 1
make[1]: *** [Makefile:1821: /home/x/build/linux-driver-gpio-customled] Error 2
make[1]: Leaving directory '/opt/linux-5.10.42'
make: *** [Makefile:5: default] Error 2
So my question is as follows: Where should this file asm/types.h come from? To my knowledge it should be included in the kernel arch/arm64/include/asm/ subdirectory. But it's not. Other architectures, namely x86 have it.
Is there another way to build a module without including linux/module.h that i'm not aware of?
Any help is greatly appreciated.
Got it!
The files are autogenerated, there is a handy make command used to prepare the build environment for out-of-tree kernel modules. What I did was run
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_prepare
inside the kernel source.
Hope this helps someone with not spending time on such a simple mistake.
I can't get why insmod gives Invalid parameters error (can't see anything in dmesg):
$ sudo insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Invalid parameters
$ sudo insmod /hello.ko
insmod: ERROR: could not load module /hello.ko: No such file or directory
I have no parameters in my module. It is just hello world example.
My environment:
$ uname -r
3.16.0-4-amd64
I have installed all possible kernel headers packages:
linux-headers-3.16.0-4-all
linux-headers-3.16.0-4-all-amd64
linux-headers-3.16.0-4-amd64
linux-headers-3.16.0-4-common
linux-headers-amd64
My code:
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
MODULE_LICENSE("GPL");
I use following Makefile:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
make output:
$ make
make -C /lib/modules/3.16.0-4-amd64/build M=/home/user/c.driver/driver-1 modules
make[1]: Entering directory '/usr/src/linux-headers-3.16.0-4-amd64'
Makefile:10: *** mixed implicit and normal rules: deprecated syntax
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-4-amd64'
CC [M] /home/user/c.driver/driver-1/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/user/c.driver/driver-1/hello.mod.o
LD [M] /home/user/c.driver/driver-1/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-3.16.0-4-amd64'
Update: same result with 14.04.1-Ubuntu
maybe it's because you forget that:
module_init(init_module);
module_exit(cleanup_module);
and I usually declare init_module() and cleanup_module() as a static function.
and fellowing code are my kernel module template:
#include <linux/module.h>
#include <linux/kernel.h>
static int init_module(void)
{
...
return 0;
}
static void exit_module(void)
{
...
}
module_init(init_module);
module_exit(exit_module);
MODULE_LICENSE("GPL");
For me, the issue was that that module file was in a shared folder (in fact, my Ubuntu box is a VM on Parallels). Copy the module to a local folder and try again.
Thanks to #avasin for this. The answer was in the comments but not quick to find, so adding it here as it may help others. This held me up for a couple of hours.
Getting error while compiling my first kernel module in Fedora linux.
Source code :--
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
static int __init hello_start(void)
{
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile :----
obj-m = hello.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
error at make time :--
$ make
make -C /lib/modules/3.8.6-203.fc18.x86_64/build M=/home/dinesh/development/linux/kernel_modules/hello modules
make: *** /lib/modules/3.8.6-203.fc18.x86_64/build: No such file or directory. Stop.
make: *** [default] Error 2
Now if i see build is there or not , i get following o/p. Build is shown as an softlink :---
$ ls -l /lib/modules/3.8.6-203.fc18.x86_64/
total 2632
lrwxrwxrwx. 1 root root 38 Apr 15 21:32 build -> /usr/src/kernels/3.8.6-203.fc18.x86_64
drwxr-xr-x.
I got same error even after installing, kernel-devel :--
My makefile is correct it have correct tab before rule. Please suggest how to resolve this error ?
As guido said, you have to match your current kernel and the kernel-devel package.
To get your kernel version run
uname -r
I get 3.6.10-4.fc18.x86_64, download that kernel-devel version
sudo yum install kernel-devel-3.6.10-4.fc18
Or update your system and boot with the new kernel, I believe those two will automatically match.
I'm building a sample kernel module under linux . The module sources are "out of the kernel tree". I've got kernel source tree from git. But it takes time to configure the kernel. So at this moment i'm just trying to build the module against kernel headers provided by my Distribution.
My Makefile :
KVERSION=$(shell uname -r)
PWD := $(shell pwd)
all:
make -C /lib/modules/$(KVERSION)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
$(info Building with KERNELRELEASE = ${KERNELRELEASE})
obj-m := hello.o
But make stops with reporting that i could not find etc, that means it could not find the headers.
but the files are there :
$ls /lib/modules/$(uname -r)/build
$arch block crypto drivers firmware fs include init ipc kernel lib Makefile Makefile.common mm Module.symvers net samples scripts security sound System.map tools usr virt
I guess its a trivial problem. But still i could not find the solution.
Thanks in advance.
EDIT: Errors :
Building with KERNELRELEASE =
make -C /lib/modules/2.6.32-220.el6.x86_64/build/ M=/usr/local/src/kernel_mods
make[1]: Entering directory `/usr/src/kernels/2.6.32-220.el6.x86_64'
Building with KERNELRELEASE = 2.6.32-220.el6.x86_64
LD /usr/local/src/kernel_mods/built-in.o
CC [M] /usr/local/src/kernel_mods/hello.o
/usr/local/src/kernel_mods/hello.c:2:27: error: linux/modules.h: No such file or directory
/usr/local/src/kernel_mods/hello.c:21: error: expected declaration specifiers or â...â before string constant
/usr/local/src/kernel_mods/hello.c:21: warning: data definition has no type or storage class
/usr/local/src/kernel_mods/hello.c:21: warning: type defaults to âintâ in declaration of âMODULE_LICENSEâ
/usr/local/src/kernel_mods/hello.c:21: warning: function declaration isnât a prototype
/usr/local/src/kernel_mods/hello.c:22: error: expected declaration specifiers or â...â before string constant
/usr/local/src/kernel_mods/hello.c:22: warning: data definition has no type or storage class
/usr/local/src/kernel_mods/hello.c:22: warning: type defaults to âintâ in declaration of âMODULE_AUTHORâ
/usr/local/src/kernel_mods/hello.c:22: warning: function declaration isnât a prototype
/usr/local/src/kernel_mods/hello.c:23: error: expected declaration specifiers or â...â before string constant
/usr/local/src/kernel_mods/hello.c:23: warning: data definition has no type or storage class
/usr/local/src/kernel_mods/hello.c:23: warning: type defaults to âintâ in declaration of âMODULE_DESCRIPTIONâ
/usr/local/src/kernel_mods/hello.c:23: warning: function declaration isnât a prototype
make[2]: *** [/usr/local/src/kernel_mods/hello.o] Error 1
make[1]: *** [_module_/usr/local/src/kernel_mods] Error 2
make[1]: Leaving directory `/usr/src/kernels/2.6.32-220.el6.x86_64'
make: *** [all] Error 2
I think you meant to do
#include <linux/module.h>
rather than
#include <linux/modules.h>