I am trying to compile a very simple module, but it fails to create *.ko when i am not adding -g flag. Here is the source code:
#include <linux/init.h>
#include <linux/module.h>
static int simple_test_init(void){
printk(KERN_INFO "Hello Kernel!");
return 0;
}
static void simple_test_exit(void){
printk(KERN_INFO "Goodbye Kernel!");
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple test module");
module_init(simple_test_init);
module_exit(simple_test_exit);
And here is GCC/Makefile.
KBUILD_CFLAGS := -Werror -fcf-protection=branch
obj-m += test.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
And finally the output of GCC.
make -C /lib/modules/5.19.3-arch1-1/build M=/test modules
make[1]: Entering directory '/usr/lib/modules/5.19.3-arch1-1/build'
CC [M] /test/test.o
/test/test.o: warning: objtool: folio_flags+0x29: 'naked' return found in RETHUNK build
/test/test.o: warning: objtool: simple_test_init+0x22: 'naked' return found in RETHUNK build
/test/test.o: warning: objtool: simple_test_exit+0x1e: 'naked' return found in RETHUNK build
/test/test.o: warning: objtool: folio_flags+0x29: missing int3 after ret
/test/test.o: warning: objtool: simple_test_init+0x22: missing int3 after ret
/test/test.o: warning: objtool: simple_test_exit+0x1e: missing int3 after ret
MODPOST /test/Module.symvers
CC [M] /test/test.mod.o
LD [M] /test/test.ko
BTF [M] /test/test.ko
pahole: /test/test.ko: No such file or directory
make[3]: *** [scripts/Makefile.modfinal:60: /test/test.ko] Error 1
make[3]: *** Deleting file '/test/test.ko'
make[2]: *** [scripts/Makefile.modpost:134: __modpost] Error 2
make[1]: *** [Makefile:1763: modules] Error 2
make[1]: Leaving directory '/usr/lib/modules/5.19.3-arch1-1/build'
make: *** [Makefile:6: all] Error 2
Thank you.
Related
I have a simple kernel module with multiple objects. When I compile it, it prompts me that MODULE_LICENSE is missing. It's defined in the main.o but somehow undetected by the compiler:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
make[1]: Entering directory '/usr/src/kernels/5.14.0-105.el9.x86_64'
CC [M] /tmp/linux5-multi-files/util.o
LD [M] /tmp/linux5-multi-files/main.o
MODPOST /tmp/linux5-multi-files/Module.symvers
ERROR: modpost: missing MODULE_LICENSE() in /tmp/linux5-multi-files/main.o
make[2]: *** [scripts/Makefile.modpost:150: /tmp/linux5-multi-files/Module.symvers] Error 1
make[2]: *** Deleting file '/tmp/linux5-multi-files/Module.symvers'
make[1]: *** [Makefile:1792: modules] Error 2
make[1]: Leaving directory '/usr/src/kernels/5.14.0-105.el9.x86_64'
make: *** [Makefile:5: build] Error 2
On older Linux (centos 6-7) it works fine, but on CentOS 8 and CentOS 9, it no longer works. What was wrong? I've attached all the files.
-- attached all files --
Makefile
main-objs := util.o
obj-m += main.o
build:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
make -C /lib/modules/`uname -r`/build M=`pwd` clean
main.c
#include "util.h"
static void __exit cleanup(void)
{
}
static int __init startup(void)
{
test();
return 0;
}
module_init(startup);
module_exit(cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux");
util.h
#ifndef UTIL_H
#define UTIL_H
#include <linux/module.h>
#include <linux/kernel.h>
void test(void);
#endif
util.c
#include "util.h"
void test()
{
printk(KERN_INFO "whatever\n");
}
To further debug this issue, I've added -v to the ccflags, and main.c is not even compiled on CentOS 8!
So far it looks like the module name can't be the same as the object name, so I have to modify the makefile to something like this:
xxx-objs := main.o util.o
obj-m += xxx.o
And the problem is gone.
I want to read a txt file and write another txt file in kernel module
How should I do ?
I have seen many website.
It seems like it has many ways to solve this question
ex : filp_read() or kernel_read() or vfs_read()
[Sloved] But I have tried many times, it couldn't makefile.
[Answer] Use mv make Makefile
reverse.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
static char buf[] ="It's from linux kernel\n";
static char buf1[32];
int __init test_init(void)
{
struct file *fp;
mm_segment_t fs;
loff_t pos;
printk("test enter\n");
fp =filp_open("/home/j0000/Desktop/file/kernel_file",O_RDWR | O_CREAT,0644);
if (IS_ERR(fp)){
printk("create file error\n");
return -1;
}
fs =get_fs();
set_fs(KERNEL_DS);
pos =0;
vfs_write(fp,buf, sizeof(buf), &pos);
pos =0;
vfs_read(fp,buf1, sizeof(buf), &pos);
printk("Write contet=%s\n",buf1);
filp_close(fp,NULL);
set_fs(fs);
return 0;
}
void __exit test_exit(void)
{
printk("test exit\n");
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
makefile
obj-m :=reverse.o
read_userspace-objs:= read_userspace_file.o
KVERSION := $(shell uname -r)
KDIR := /usr/src/linux-headers-$(KVERSION)/
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o *.cmd *.ko *.mod.c .tmp_versions Module.symvers modules.order
error message
j0000#ubuntu:~/Desktop/file$ make
make -C /usr/src/linux-headers-5.11.0-37-generic/ M=/home/j0000/Desktop/file modules
make[1]: Entering directory '/usr/src/linux-headers-5.11.0-37-generic'
scripts/Makefile.build:44: /home/j0000/Desktop/file/Makefile: No such file or directory
make[2]: *** No rule to make target '/home/j0000/Desktop/file/Makefile'. Stop.
make[1]: *** [Makefile:1849: /home/j0000/Desktop/file] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.11.0-37-generic'
make: *** [makefile:8: default] Error 2
j0000#ubuntu:~/Desktop/file$
updated error message
I have seen these error many times~
So may I ask why it can't use get_fs & set_fs in this situation
j0000#ubuntu:~/Desktop/file$ make
make -C /usr/src/linux-headers-5.11.0-37-generic/ M=/home/j0000/Desktop/file modules
make[1]: Entering directory '/usr/src/linux-headers-5.11.0-37-generic'
CC [M] /home/j0000/Desktop/file/reverse.o
/home/j0000/Desktop/file/reverse.c: In function ‘test_init’:
/home/j0000/Desktop/file/reverse.c:20:9: error: implicit declaration of function ‘get_fs’; did you mean ‘sget_fc’? [-Werror=implicit-function-declaration]
20 | fs =get_fs();
| ^~~~~~
| sget_fc
/home/j0000/Desktop/file/reverse.c:20:9: error: incompatible types when assigning to type ‘mm_segment_t’ {aka ‘struct <anonymous>’} from type ‘int’
/home/j0000/Desktop/file/reverse.c:21:5: error: implicit declaration of function ‘set_fs’; did you mean ‘sget_fc’? [-Werror=implicit-function-declaration]
21 | set_fs(KERNEL_DS);
| ^~~~~~
| sget_fc
/home/j0000/Desktop/file/reverse.c:21:12: error: ‘KERNEL_DS’ undeclared (first use in this function); did you mean ‘KERNFS_NS’?
21 | set_fs(KERNEL_DS);
| ^~~~~~~~~
| KERNFS_NS
/home/j0000/Desktop/file/reverse.c:21:12: note: each undeclared identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:288: /home/j0000/Desktop/file/reverse.o] Error 1
make[1]: *** [Makefile:1849: /home/j0000/Desktop/file] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.11.0-37-generic'
make: *** [Makefile:8: default] Error 2
Actually I use this website for tutorial
https://www.cnblogs.com/arnoldlu/p/8879800.html
After all, I will use kernel_read & kernel_write to fix my bug.
Thanks for answering my question :)
I have the following files: buffer.c, buffer.h, chardevin.c, chardevout.c and Makefile. Both chardevin.c and chardevout.c are kernel modules. Both kernel modules include buffer.h, which is implemented by buffer.c. Ideally, I'd like the makefile to make both kernel modules while linking the buffer implementation (i.e. produce chardevin.ko and chardevout.ko). I can't seem to figure this part out...
Here's the contents of my Makefile:
obj-m += chardevin.o chardevout.o
obj-y += buffer.c
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
I get the following as output, however:
kylemart#ubuntu:/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex$ make
make -C /lib/modules/4.4.0-31-generic/build/ M=/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex modules
make[1]: Entering directory `/usr/src/linux-headers-4.4.0-31-generic'
CC [M] /mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.o
CC [M] /mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.o
Building modules, stage 2.
MODPOST 2 modules
WARNING: "buffer_read" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.ko] undefined!
WARNING: "buffer_length" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.ko] undefined!
WARNING: "buffer_write" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.ko] undefined!
WARNING: "buffer_length" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.ko] undefined!
CC /mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.mod.o
LD [M] /mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.ko
CC /mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.mod.o
LD [M] /mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.4.0-31-generic'
Here's the contents of buffer.h:
#ifndef BUFFER_H
#define BUFFER_H
ssize_t buffer_write(const char *src, size_t n);
ssize_t buffer_read(char *dest, size_t n);
size_t buffer_length(void);
#endif
What am I doing wrong?
EDIT:
Changed "buffer.c" to "buffer.o" in the Makefile. Here's the output:
kylemart#ubuntu:/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex$ make
make -C /lib/modules/4.4.0-31-generic/build/ M=/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex modules
make[1]: Entering directory `/usr/src/linux-headers-4.4.0-31-generic'
Building modules, stage 2.
MODPOST 2 modules
WARNING: "buffer_read" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.ko] undefined!
WARNING: "buffer_length" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevout.ko] undefined!
WARNING: "buffer_write" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.ko] undefined!
WARNING: "buffer_length" [/mnt/hgfs/ucf-os-linux/SplitDriverWithMutex/chardevin.ko] undefined!
make[1]: Leaving directory `/usr/src/linux-headers-4.4.0-31-generic'
Replace as below this:
obj-y += buffer.c -- > obj-y += buffer.o
If I manually compile the code below, I got no error:
/*
* File: newmain.c
* Author: Mike
*
* Created on September 18, 2015, 7:36 PM
*/
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
int main(int argc, char** argv) {
printf ("Hello!");
return 0;
}
However, by doing the with NetBeans, I got the following error:
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory '/cygdrive/c/Users/Mike/Documents/NetBeansProjects/CppApplication_1'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/Cygwin_4.x-Windows/cppapplication_1.exe
make[2]: Entering directory '/cygdrive/c/Users/Mike/Documents/NetBeansProjects/CppApplication_1'
mkdir -p build/Debug/Cygwin_4.x-Windows
rm -f "build/Debug/Cygwin_4.x-Windows/newmain.o.d"
gcc -c -g -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/newmain.o.d" -o build/Debug/Cygwin_4.x-Windows/newmain.o newmain.c
mkdir -p dist/Debug/Cygwin_4.x-Windows
g++ -o dist/Debug/Cygwin_4.x-Windows/cppapplication_1 build/Debug/Cygwin_4.x-Windows/main.o build/Debug/Cygwin_4.x-Windows/newmain.o
build/Debug/Cygwin_4.x-Windows/newmain.o: In function `main':
/cygdrive/c/Users/Mike/Documents/NetBeansProjects/CppApplication_1/newmain.c:14: multiple definition of `main'
build/Debug/Cygwin_4.x-Windows/main.o:/cygdrive/c/Users/Mike/Documents/NetBeansProjects/CppApplication_1/main.cpp:15: first defined here
collect2: error: ld returned 1 exit status
nbproject/Makefile-Debug.mk:63: recipe for target 'dist/Debug/Cygwin_4.x-Windows/cppapplication_1.exe' failed
make[2]: *** [dist/Debug/Cygwin_4.x-Windows/cppapplication_1.exe] Error 1
make[2]: Leaving directory '/cygdrive/c/Users/Mike/Documents/NetBeansProjects/CppApplication_1'
nbproject/Makefile-Debug.mk:60: recipe for target '.build-conf' failed
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory '/cygdrive/c/Users/Mike/Documents/NetBeansProjects/CppApplication_1'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
How can I get this code being executed in the NetBeans too?
I want to separate my kernel module to sources. But I can't compile it properly.
print_hello.h
#ifndef PRINT_HELLO_H_
#define PRINT_HELLO_H_
void print_hello(void);
#endif /* PRINT_HELLO_H_ */
print_hello.c:
#include <linux/kernel.h>
#include "print_hello.h"
void print_hello(void) {
printk("Hello, World!\n");
}
main.c:
#include<linux/module.h>
#include<linux/version.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include "print_hello.h"
int hello_init(void) {
print_hello();
return 0;
}
module_init(hello_init);;
MODULE_LICENSE("GPL");
Makefile:
obj-m += main.o
main-objs := print_hello.o main.o
all:
make -C /lib/modules/3.2.51/build M=$(PWD) modules
clean:
make -C /lib/modules/3.2.51/build M=$(PWD) clean
but when I compile this program this error occur:
root#linux:r# make
make -C /lib/modules/3.2.51/build M=/home/root/hello modules
make[1]: Entering directory `/usr/src/build'
CC [M] /home/root/hello/main.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "print_hello" [/home/root/hello/main.ko] undefined!
LD [M] /home/root/hello/foo.ko
make[1]: Leaving directory `/usr/src/build'
Any solution to solve this problem?