How to provide include directory path in kernel module Makefile - linux

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

Related

Unable to load kernel module 'elan_i2c_core.ko'

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

How to insert dependent modules into Kernel?

I have a Parrot AR.Drone 2.0 running Ubuntu and I want to connect it to the single board computer using cable. There are no Ethernet ports on the drone so I decided to use USB-Ethernet adapter (D-Link DUB-E100).
After entering uname -a in the terminal I get the following line:
Linux uclibc 2.6.32.9-g980dab2 #1 PREEMPT Mon Oct 6 11:50:23 CEST 2013 armv7l GNU/Linux
I followed this article and instead of module for wifi I used module for USB-Ethernet adapter.
This how I edited Makefile:
TARGET = dub_e100
OBJS = dub_e100.o
MDIR = drivers/net/usb
KDIR = /home/artemii/Downloads/linux
EXTRA_CFLAGS = -DEXPORT_SYMTAB
PWD = $(shell pwd)
DEST = /home/artemii/Downloads/linux/$(MDIR)
obj-m := $(TARGET).o
default:
make -C $(KDIR) SUBDIRS=$(PWD) modules
$(TARGET).o: $(OBJS)
$(LD) $(LD_RFLAG) -r -o $# $(OBJS)
install:
su -c "cp -v $(TARGET).ko $(DEST) && /sbin/depmod -a"
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
.PHONY: modules clean
-include $(KDIR)/Rules.make
After that I compiled the kernel with following lines:
make
export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabi-
make
Leter on I transfer generated 'dub_e100.ko' file into drone and ran the following command line:
insmod dube100.ko
Terminal threw an error insmod: can't insert 'dub_e100.ko': unknown symbol in module, or unknown parameter.
Checking dmesg | tail gives:
usb 1-1:1.0: uevent
dub_e100: Unknown symbol mii_ethtool_sset
dub_e100: Unknown symbol mii_link_ok
dub_e100: Unknown symbol mii_nway_restart
dub_e100: Unknown symbol generic_mii_ioctl
dub_e100: Unknown symbol mii_ethtool_gset
I assume that adapter's module depends on mii module, so I generated mii.ko file with following makefile:
TARGET = dub_e100
OBJS = dub_e100.o
MDIR = drivers/net/usb
KDIR = /home/artemii/Downloads/linux
EXTRA_CFLAGS = -DEXPORT_SYMTAB
PWD = $(shell pwd)
DEST = /home/artemii/Downloads/linux/$(MDIR)
obj-m := $(TARGET).o
obj-m += mii.o
default:
make -C $(KDIR) SUBDIRS=$(PWD) modules
$(TARGET).o: $(OBJS)
$(LD) $(LD_RFLAG) -r -o $# $(OBJS)
install:
su -c "cp -v $(TARGET).ko $(DEST) && /sbin/depmod -a"
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
.PHONY: modules clean
-include $(KDIR)/Rules.make
After that I consiquately run mii.ko and dube100.ko on the drone. All the modules visible in lsmod. But after inserting the adapter to the drone it crushes and reboots. After reboot this modules dessapiar from lsmod.
Is there something I am doing wrong? I might generated or ran modules improperly.
insmod does not handle module dependencies. It's manual page says:
insmod is a trivial program to insert a module into the kernel. Most users will want to use modprobe(8) instead, which is more clever and can handle module dependencies.
Note that you may have to run depmod before the modprobe automatic dependency loading works as intended.

Linux modules version error "Invalid module format"

I made Linux external module and because my module need Linux kernel symbol,
I set the Modversion config and make it.(also did make modules_install)
My module was made exactly in lib/modules/(my linux)/extra/
But when I insert my module, shell prints error message
insmod: ERROR: could not insert module oxen_aggregator_module.ko: Invalid module format
This is dmesg contents
[ 341.458351] oxen_aggregator_module: version magic '3.17.8-gentoo-r1 SMP mod_unload modversions ' should be '3.17.8-gentoo-r1 SMP mod_unload '
But I need modversions flag because if I didn't set that flag, Module.symvers have just 0x00000000 addresses.
Could you help me? How can I solve?
My Make file
SRCS = oxen_aggregator_module.c
OBJS = $(SRCS:.c=.o)
obj-m += $(OBJS)
KBUILD_EXTRA_SYMBOLS={/usr/src/linux-$(shell unamr -r)/Module.symvers}
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
$(RM) Module.markers modules.order
You attempt to load module into kernel, for which it(module) hasn't be built. Or you build module for one kernel, but use KBUILD_EXTRA_SYMBOLS with Module.symvers file, created for another kernel.
If you need to use KBUILD_EXTRA_SYMBOLS with kernel's Module.symvers file, then it is definitely mess with different kernels somewhere.

module compiling : asm/linkage.h file not found

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

Running the Linux Kernel Module ( Hello World )

I am trying to run a hello world kernel module but its showing module.h is no present. but i have module.h in /usr/src/linux.2.xx.xx/includes/.Please help me how to set this path?
Try the following in your shell in the directory with the source of your module:
export KDIR=/usr/src/linux.2.xx.xx
make -C $KDIR M=`pwd`
That header should be used via #include <linux/module.h>
try to touch a new makefile which coding like below
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
this makefile should name "Makefile"
put it in the same directory with the hello.c file

Resources