I'm trying to build a kernel module under Debian 9.
I installed the necessary packages using
sudo apt-get install build-essential linux-headers-4.9.0-5-amd64
but I get the following error message when I try to compile my module:
> make
make -C /lib/modules/4.9.0-5-amd64/build M=/home/sven/tmp/kernel modules
make[1]: Entering directory '/lib/modules/4.9.0-5-amd64/build'
make[1]: *** No rule to make target 'modules'. Stop.
make[1]: Leaving directory '/lib/modules/4.9.0-5-amd64/build'
Makefile:6: recipe for target 'all' failed
make: *** [all] Error 2
The problem seems to be that there is no Makefile in the
/lib/modules/4.9.0-5-amd64/build
directory. In fact, this directory is empty ...
This might be a beginner's question, but does anybody know how to fix this?
The source code for the kernel module as well as the corresponding Makefile are listed below.
Thank you very much for your help!
C Code for module:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Homer S.");
MODULE_DESCRIPTION("hmmmm ...");
MODULE_VERSION("1.0")
static int __init
start(void) {
printk(KERN_INFO "\nCHELLAS!\n\n");
return 0;
}
static void __exit
end(void) {
printk(KERN_INFO "\nCIAO!\n\n");
return 0;
}
module_init(start);
module_exit(end);
Makefile to compile the module:
obj-m+=foo.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
The makefile works fine with a more recent linux-headers package, it may have been a temporary issue or a problem with the package installation on your system.
Mind that your .c code would not compile tho:
diff --git a/foo.c b/foo.c
index 97611ef..5769fa7 100644
--- a/foo.c
+++ b/foo.c
## -5,7 +5,7 ##
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Homer S.");
MODULE_DESCRIPTION("hmmmm ...");
-MODULE_VERSION("1.0")
+MODULE_VERSION("1.0");
static int __init
## -18,7 +18,6 ## start(void) {
static void __exit
end(void) {
printk(KERN_INFO "\nCIAO!\n\n");
- return 0;
}
Related
Visual Studio Code project
CMake connects files
As a beginner I want to integrate testlib.h
and testlib.c which I can call in the main.c
testlib.c and .h should also call boot.h - but this doesn't work!
Including my teslib.h and testlib.c in main,c works. But In testlib.h I need access e.g. to boot.h ... but I cannot include this file!
Here is the code:
#include "testlib.h"
#include <stdint.h>
#include "boot.h" // why there comes an error when I want to include this?
#include <stddef.h>
int f123(void){
int a = 2;
return a;
}
void print_uart_22(const char text[])
{
int a;
(void)a;
(void)text;
}
Why there comes the error message?
There must be something wrong with the paths...
but main.c is next to testlib.h
main.c also includes "boot.h" without error
/testlib.c:4:10: fatal error: boot.h: No such file or directory
[build] #include "boot.h"
[build] ^~~~~~~~
[build] compilation terminated.
Why?
hahaaha
main.c is located next to testlib.h and testlib.c!
main.c includes also boot.h and there is no error.
I'm trying to compile following 'Hello World'.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("BOBR");
MODULE_DESCRIPTION("HELLO MODULE");
MODULE_VERSION("0.10");
static char *name = "user";
module_param(name, charp, S_IRUGO);
MODULE_PARM_DESC(name, "The name to display");
static int __init hello_init(void) {
printk(KERN_INFO "HEllo, %s!\n", name);
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye, %s !\n", name);
}
module_init(hello_init);
module_exit(hello_exit);
My Makefile is
ifneq ($(KERNELRELEASE),)
include Kbuild
#KDIR ?= ../repos/linux
else
KDIR ?= /lib/modules/4.9.0-6-amd64/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
clean:
$(MAKE) -C $(KDIR) M=$$PWD clean
endif
I start make as: make ARCH=arm CROSS_COMPILE='ccache arm-eabi-' PATH=/opt/gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi/bin:$PATH
I compile on Debian 4.9.0-6-amd64. Target is arm32 4.16.18.
The problem is that I get a module for my host machine (I can insmod it), but the target kernel rejects it as invalid module.
When I try to change the linux path in the Makefile to the target kernel sources, the compilation fails with fatal error: asm/barrier.h: No such file or directory.
I am trying to pass a "define variable called DEBUG" at compile time for a kernel module.
i.e provide the same functionality as DEBUG does below, but in a Makefile for a kernel module.
gcc -o foo -DDEBUG=1 foo.c
Can anyone give me a hint on how this can be achieved?
The Makefile:
# name of the module to be built
TARGET ?= test_module
# How to pass this during compile time? (-D$(DEBUG) or something similar)
DEBUG ?= 1
#define sources
SRCS := src/hello.c
#extract required object files
OBJ_SRCS := $(SRCS:.c=.o)
#define path to include directory containing header files
INCLUDE_DIRS = -I$(src)/includes
ccflags-y := $(INCLUDE_DIRS)
#define the name of the module and the source files
obj-m += $(TARGET).o
$(TARGET)-y := $(OBJ_SRCS)
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
#echo "insert module:\n\t sudo insmod $(TARGET).ko"
#echo "remove module:\n\t sudo rmmod $(TARGET)"
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I am using the module from link (with a small change in the init function, see the #if #endif statement)
hello.c:
#include <linux/module.h> // included for all kernel modules
#include <linux/kernel.h> // included for KERN_INFO
#include <linux/init.h> // included for __init and __exit macros
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lakshmanan");
MODULE_DESCRIPTION("A Simple Hello World module");
static int __init hello_init(void)
{
#if (DEBUG == 1)
printk(KERN_INFO "DEBUG = 1\n")
#endif
printk(KERN_INFO "Hello world!\n");
return 0; // Non-zero return means that the module couldn't be loaded.
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
I would like to see that dmesg poduces the following after
sudo insmod test_module.ko
DEBUG = 1
Hello world!
Solution:
ccflags-y := -DDEBUG=$(DEBUG)
Made the code below execute as intended
#if (DEBUG == 1)
printk(KERN_INFO "DEBUG = 1\n")
#endif
ccflags-y := -DDEBUG=$(DEBUG)
Made the code below execute as intended
#if (DEBUG == 1)
printk(KERN_INFO "DEBUG = 1\n")
#endif
I have compiled this code:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/genhd.h> // declaration of printk_all_partitions()
MODULE_LICENSE("GPL");
int __init start (void) {
printk ("evaluating the module ") ;
printk_all_partitions();
printk (" module inserted .. ");
return 0 ;
}
void __exit x(void) {
printk ("module unloaded ..");
}
module_init(start);
module_exit (x);
MODULE_LICENSE("GPL");
makefile is:
EXTRA_CFLAGS += -Wall
obj-m += printk_all_partitions.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
when I run make I get
WARNING: "printk_all_partitions" [/root/c++/modulez/multiple_source_files/printk_plm/printk_all_partitions.ko] undefined!
egrep -w 'printk|printk_all_partitions' /proc/kallsyms :
ffffffff8162f135 T printk
ffffffff81ac7b46 T printk_all_partitions
Now the only difference between printk and printk_all_partitions is that printk_all_partitions does not exist in the Module.symvers
and printk is:
0x27e1a049 printk vmlinux EXPORT_SYMBOL
By the time i finished the writing I found out that a function must be EXPORT_SYMBOL-ed too in order for it to work
but if (somehow) Modules.symvers was deleted , and the kernel sources were not available, both printk and printk_all_partitions are begin with a "T", what other way to know is one is exported or not?
Normally this line
obj-m += printk_all_partitions.o
is the name of the module you're trying to create. In this case you're naming your module the same as an existing symbol, is this deliberate?
I'm a noob to linux kernel programming and thought I'd be able to find the answer for this (since it seems really simple) but haven't had any luck yet. I need to make a linux kernel module that prints the version number of the kernel. The assignment requires that implement a module which displays this kind of message when loaded:
"Hello Master. You are currently using Linux (version)", where (version) is the kernel version no.
How can I do this? I tried using uname (http://man7.org/linux/man-pages/man2/uname.2.html) but when I include sys/utsname.h, I get a fatal error upon compiling with my makefile
"Cannot open include file: 'sys/utsname.h': No such file or directory".
Here is my module
#undef __KERNEL__
#define __KERNEL__
#undef __MODULE__
#define __MODULE__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <sys/utsname.h>
struct utsname unameData;
static int __init config_init(void)
{
uname(&unameData);
printk(KERN_INFO "Version number is %s\n", unameData.version);
return 0;
}
static void __exit config_exit(void)
{
printk(KERN_INFO "config_exit executed with success\n");
return;
}
module_init(config_init);
module_exit(config_exit);
MODULE_LICENSE("GPL");
Makefile
obj-m := config.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
Firstly, you need to use the correct headers and also the correct function utsname(). Following code work well for me.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/utsname.h>
static int __init my_init(void)
{
printk(KERN_INFO "Kernel version %s\n", utsname()->version);
printk(KERN_INFO "Kernel release %s\n", utsname()->release);
return 0;
}
static void __exit my_exit(void)
{
printk(KERN_INFO "exit module");
return;
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
dmesg output should looks something like this:
[ 1117.358451] Kernel version #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014
[ 1117.358457] Kernel release 3.13.0-37-generic