I'm trying to load a custom made(sort of) module to get my touchpad to work. I downloaded "elan_i2c_core.c" and "elan_i2c.h" from github. Put them together on a folder made a "Makefile"(on the same folder) like:
ifneq ($(KERNELRELEASE),)
obj-m := elan_i2c_core.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
install:
$(MAKE) -C $(KDIR) M=$(PWD) modules_install
%:
$(MAKE) -C $(KDIR) M=$(PWD) $#
endif
When I ran sudo make it returned .ko files along with some other files but, returned some warnings too:
WARNING: "elan_i2c_ops" [/home/name/Templates/elan/elan_i2c_core.ko] undefined!
WARNING: "elan_smbus_ops" [/home/name/Templates/elan/elan_i2c_core.ko] undefined!
I tried
insmod elan_i2c_core.ko`
which returned:
insmod: ERROR: could not insert module elan_i2c_core.ko: Unknown symbol in module
The output of
depmod elan_i2c_core.ko`
was
insmod: ERROR: could not insert module elan_i2c_core.ko: Unknown symbol in module
How do I fix it? Do I have to recompile the whole kernel from scratch or am I doing something wrong?
Additional information:
Kernel version- 4.18.0-10-generic
OS- Ubuntu 18.10
I was learning kernel interrupt using a small demo kernel module
which use these two header include
asm/exception.h
asm/mach/irq.h
My Makefile is
ifeq (${KERNELRELEASE},)
KERNEL_SOURCE := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
make -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
clean:
make -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
else
obj-m := irq_demo.o
endif
The error I am getting
irq_demo.c:9:27: fatal error: asm/exception.h: No such file or directory
#include <asm/exception.h>
I found asm/exception.h in my system in /usr/src/linux-headers-3.16.0-30-generic/arch/arm/include/
[1]But how to include this path in Makefile
[2]Is /usr/src/linux-headers-3.16.0-30-generic/include/asm-generic/ linked with arch/arm/include/asm/ ? if yes , than How ?
First try
adding ARCH=arm after make
i.e.
make ARCH=arm -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
============================= OR =============================
Can you try adding line before make
CARGS = -I /lib/modules/$(shell uname -r)/arch/arm/include/
make $(CARGS) -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
I would like to define a macro for my kernel module by using the -D flag, but I can't figure out how to do it in a custom loadable kernel module.
Just to be clear, to set the macro TEST to 1 I usually do something like:
cc -D TEST=1 file.c -o file
And inside the file.c I have
#if TEST
//do something
#endif
Now, having the same code in a kernel module, how can I set TEST to 1 without touching the code?
This is my the Makefile:
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Since the -C flag it's recursively calling multiple makefiles, adding -D TEST=1 does not work, I get the following error:
make: invalid option -- 'D'
Anybody knows how to solve this problem?
Thanks in advance.
As suggested by #n.m. in the comments, the solution is to use the EXTRA_CFLAGS. So in my case it would be something like this:
all:
make EXTRA_CFLAGS=-DTEST=2 -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
or simply
EXTRA_CFLAGS:= -D TEST=2
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
I'm trying to build a kernel module in part of a larger project that uses premake5 to generate the Makefiles. However, there's no documentation on using premake to build a kernel module. Is this possible in premake? I'd like to stay consistent with using Premake in the project, if possible.
Thank you in advance for any insights.
My attempt thus far:
project "mymod"
kind "ConsoleApp"
language "C"
location "./"
files { "**.h", "**.c" }
if _ACTION == "clean" then
os.rmdir("obj")
end
buildcommands {
"make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules %{cfg.buildcfg}"
}
rebuildcommands {
"make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules %{cfg.buildcfg} rebuild"
}
cleancommands {
"make clean %{cfg.buildcfg}"
}
buildoptions{ "-Wno-unused-value", "-Wno-sign-compare",
"-Wno-unused-parameter", "-Wno-unused-function",
"-Wno-missing-field-initializers"}
configuration {"Release"}
defines { "NDEBUG" }
flags { "Optimize", "ExtraWarnings", "FatalWarnings", "FloatStrict", "EnableSSE2" }
What follows is an example of a working Makefile for building a kernel module. Granted, it's short and probably doesn't seem worth the trouble of using Premake, but that's because it is missing several object files from the listing, which currently have to be entered manually.
# Note that multiple KBUILD_EXTRA_SYMBOLS Entries are space-separated
KBUILD_EXTRA_SYMBOLS=$(ETHERCAT_TOPDIR)/Module.symvers \
$(HOME_DIR)/shmdrv/Module.symvers \
# the output kernel module
obj-m := corert.o
# the object files used
corert-objs := ctsrt_main.o globals.o ProcessMain.o \
CtsSharedData.o ProcessData.o \
ProcessSdo.o ProcessSimulate.o \
FsmWrite.o
ETHERCAT_TOPDIR = /usr/local/src/ethercat
EXTRA_CFLAGS = -I$(ETHERCAT_TOPDIR)/include -ffast-math -mhard-float
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) \
modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I am trying to compile an example of "hello world" Kernel Module,
problems found on ubuntu 11.04, kernel 3.2.6, gcc 4.5.2 and fedora 16, kernel 3.2.7, gcc 4.6.7.
code:
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static int __init hello_init (void)
{
printk("Hello module init\n");
return 0;
}
static void __exit hello_exit (void)
{
printk("Hello module exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
compiled with:
gcc -D__KERNEL__ -I /usr/src/linux/include/ -DMODULE -Wall -O2 -c hello.c -o hello.o
error:
In file included from /usr/src/linux/include/linux/kernel.h:13:0,
from /usr/src/linux/include/linux/cache.h:4,
from /usr/src/linux/include/linux/time.h:7,
from /usr/src/linux/include/linux/stat.h:60,
from /usr/src/linux/include/linux/module.h:10,
from hello.c:1: /usr/src/linux/include/linux/linkage.h:5:25: fatal error:
asm/linkage.h: file not found
then I found in /usr/src/linux/include/ there is no folder named 'asm' but 'asm-generic';
so I made a soft link 'asm' to 'asm-generic', and compiled agail:
this time the error was:
In file included from /usr/src/linux/include/linux/preempt.h:9:0,
from /usr/src/linux/include/linux/spinlock.h:50,
from /usr/src/linux/include/linux/seqlock.h:29,
from /usr/src/linux/include/linux/time.h:8,
from /usr/src/linux/include/linux/stat.h:60,
from /usr/src/linux/include/linux/module.h:10,
from hello.c:1: /usr/src/linux/include/linux/thread_info.h:53:29: fatal error:
asm/thread_info.h: file not found
So I realized I was wrong, but why ? T_T
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
is a proper way to build modules see kbuild documentation
And to see difference beetween your compiler invocation you could
cat /lib/modules/$(shell uname -r)/build/Makefile
And analyze an output
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
Here hello.c is your kernel source file. just use make to build your hello.ko module.
asm should be a link to the actual architecture you're compiling for, not to asm-generic.
You can't compile a generic kernel module, that would work on a generic architecture. You have to compile it for the particular architecture you're going to use.
I don't know why the asm didn't exist. It should be created as part of the configuration process.
You might get other errors later, if configuration is incomplete in other ways.
The asm includes (such as linkage.h) are architecture specific. There should be a set of directories under:
/usr/src/kernels/(kernel version goes here)/arch
that provide specific includes for the specific CPU architecture you are targeting your code to be compiled for.
Try adding this to your Makefile:
KVERSION :=R(shell uname -r)
and add the kernel and architecture (x86 in this example):
INCDIRS = -I./include -I/usr/src/kernels/$(KVERSION)/include -I/usr/src/kernels/$(KVERSION)/arch/x86
module compiling : asm/linkage.h file not found
This means this particular file was not found in specified DIR, which gets specified when we use -I option with make.
We can either link that asm-generic to asm, if all headers are present in asm-generic, or we can use make utility.
Make utility is preferred in case of building kernel modules.
Create a 'Makefile' in working DIR.
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
Use of -C option will change to DIR specified before reading the makefiles or doing anything else.
So to avoid this error, use -C option with DIR/lib/modules/$(shell uname -r)/build
By this your program will be able to find required files, you will get hello.ko file.
You can add this to kernel modules by
sudo insmod hello.ko
Similarly you can remove by
sudo rmmod hello