Try to build tutorial for linux device driver - makefile

i am trying to learn how to write device driver on linux. I have looked at several online tutorials. They are simple enough but I have problem compiling it. I got a makefile error at the bottom. I have not done anything to the linux-header-2.6.32-27-generic. It is in the state that it was installed. It may be that it has some dependencies but I have no ideas which one. I am not sure what make is expecting.
I would appreciate any help.
Here is my system info.
Linux rat-desktop 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC 2010 i686 GNU/Linux
The include files are in /usr/src/linux-headers-2.6.32-27-generic
rat#rat-desktop:/usr/src/linux-headers-2.6.32-27-generic$ ls
arch firmware Kbuild modules.order security usr
block fs kernel Module.symvers sound virt
crypto include lib net source
Documentation init Makefile samples tools
drivers ipc mm scripts ubuntu
nothing.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int __init hello_init(void)
{
printk(KERN_ALERT "Hello,world tapas\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "Good Bye,cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m := nothing.o
KDIR = /usr/src/linux-headers-2.6.32-27-generic
all:
$(MAKE) make -C $(KDIR) M=pwd modules
clean:
rm -rf *.o *.ko *.mo.* *.symvers *.order
sudo make
make make -C /usr/src/linux-headers-2.6.32-27-generic M=pwd modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-27-generic'
make[1]: *** No rule to make target `make'. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-27-generic'
make: *** [all] Error 2
I used another Makefile which got me a little more detail
obj-m += nothing.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
rat#rat-desktop:~/deviceDrivers$ sudo make
make -C /lib/modules/2.6.32-27-generic/build M= modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-27-generic'
CHK include/linux/version.h
CHK include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-x86
make[2]: *** No rule to make target `kernel/bounds.c', needed by `kernel/bounds.s'. Stop.
make[1]: *** [prepare0] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-27-generic'
make: *** [all] Error 2

In the first Makefile, observe the make command that is being executed in the output when you run sudo make (generally sudo is not required to build the modules) :
make make -C /usr/src/linux-headers-2.6.32-27-generic M=pwd modules
In this case, make is searching for a target named 'make'! Remove the $(MAKE) from the Makefile and try. And also M=pwd option is incorrect!
In the second case, the PWD variable isn't defined. You can define it in the Makefile something like this :
PWD := $(shell pwd)

Related

Cross compiling hello world module

I am trying to cross compile a simple hello world program. The cross compiler I am using is for Buildroot Linux on a RPI4. I am trying to do the compilation on my Ubuntu machine.
I get this error:
make[2]: *** No rule to make target '/home/j_sizzle/Documents/Lab11-2/hello1.o', needed by '/home/j_sizzle/Documents/Lab11-2/hello1.mod'. Stop.
make[1]: *** [Makefile:1825: /home/j_sizzle/Documents/Lab11-2] Error 2
make[1]: Leaving directory '/home/j_sizzle/Documents/buildroot/buildroot-2021.11.1-rpi/output/build/linux-custom'
make: *** [Makefile:7: default] Error 2
My Makefile looks like this:
obj-m += hello1.o
KDIR := /home/j_sizzle/Documents/buildroot/buildroot-2021.11.1-rpi/output/build/linux-custom/
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) ARCH=arm CROSS_COMPILE=/home/j_sizzle/Documents/buildroot/buildroot-2021.11.1-rpi/output/host/bin/arm-buildroot-linux-uclibcgnueabihf- modules
clean:
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) clean
rm -f *~cd
I'm not really sure what I need to do here and I am somewhat new to makefiles so sorry if I am doing something dumb. I do know that this cross compiler works when just compiling a c program, but this is my first time trying to use it for modules.

Warning: modules_install: missing 'System.map' file. Skipping depmod

I am trying to insert a kernel module using depmod and modprobe utilities in-order to resolve any dependencies. When I build the module it throws "Warning: modules_install: missing 'System.map' file. Skipping depmod."
And later when I try to execute modprobe it throws an error saying
"modprobe: FATAL: Module i2c_eeprom_client.ko not found in directory /lib/modules/4.19.58-v7+"
Below is the make file I am using:
obj-m += i2c_eeprom_client.o
KDIR = /lib/modules/$(shell uname -r)/build
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
make -C $(KDIR) M=$(PWD) modules_install
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
And below is the output of build:
make -C /lib/modules/4.19.58-v7+/build M=/home/pi/work/eeprom modules
make[1]: Entering directory '/usr/src/linux-headers-4.19.58-v7+'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/usr/src/linux-headers-4.19.58-v7+'
make -C /lib/modules/4.19.58-v7+/build M=/home/pi/work/eeprom
modules_install
make[1]: Entering directory '/usr/src/linux-headers-4.19.58-v7+'
INSTALL /home/pi/work/eeprom/i2c_eeprom_client.ko
DEPMOD 4.19.58-v7+
Warning: modules_install: missing 'System.map' file. Skipping depmod.
make[1]: Leaving directory '/usr/src/linux-headers-4.19.58-v7+'
How can i fix this problem ? Please help
Platform : Raspberry PI 3b+, Raspbian - linux 4.19.58-v7+
You can run depmod after the modules_install step. Also, it is better practice to separate the installation from the building to avoid having to build with root privileges:
obj-m += i2c_eeprom_client.o
# Default to running kernel's build directory if KDIR not set externally
KDIR ?= "/lib/modules/$(shell uname -r)/build"
all:
$(MAKE) -C "$(KDIR)" M="$(CURDIR)" modules
install:
$(MAKE) -C "$(KDIR)" M="$(CURDIR)" modules_install
depmod -A
clean:
$(MAKE) -C "$(KDIR)" M="$(CURDIR)" clean
Invoke as:
$ make
$ make install

Compile error when compiling a driver using Makefile

When I try to compile the hello.c as a driver component, I got an error as follows:
root#ubuntu:/home/steven/Downloads# make
make -C /lib/modules/`uname -r`/build M=/home/steven/Downloads modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-29-generic'
CC [M] /home/steven/Downloads/hello.o
**cc1: error: code model kernel does not support PIC mode**
scripts/Makefile.build:332: recipe for target '/home/steven/Downloads/hello.o' failed
make[2]: *** [/home/steven/Downloads/hello.o] Error 1
Makefile:1552: recipe for target '_module_/home/steven/Downloads' failed
make[1]: *** [_module_/home/steven/Downloads] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-29-generic'
Makefile:13: recipe for target 'modules' failed
make: *** [modules] Error 2
My Makefile is as follows:
ifneq ($(KERNELRELEASE),)
MODULE_NAME = hellomodule
$(MODULE_NAME)-objs := hello.o
obj-m := $(MODULE_NAME).o
else
KERNEL_DIR = /lib/modules/`uname -r`/build
MODULEDIR := $(shell pwd)
.PHONY: modules
default: modules
modules:
make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
clean distclean:
rm -f *.o *.mod.c .*.*.cmd *.ko
rm -rf .tmp_versions
endif
Can anybody help me to solve this problem?

For kernel module makefile: Use another name for the makefile and using command line parameter

I have Kernel module sources (for arm) and I would like to compile two different drivers from the same source.
The kernel in compiled with 2 source files and with cross compile.
MODULE_MAME = modulename
SRCS = drv/source.c lib/libsrc.c
OBJS = $(SRCS:.c=.o)
obj-m += $(MODULE_MAME).o
$(MODULE_MAME)-y = $(OBJS)
KDIR := /mykermelsources/
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) clean
In one command, I would like to compile 2 modules.
Two choices:
Keeping 3 different Makefiles, one main that will call both other makefiles. One problem with this, I cannot make it working. make -f makefilediff or make --makefile=makefilediff give me an error.
Log:
make -C /mykermelsources/ ARCH=arm M=/home/mychardriver/ modules
make[1]: Entering directory '/mykermelsources'
scripts/Makefile.build:44: /home/mychardriver/Makefile: No such file or directory
make[2]: *** No rule to make target '/home/mychardriver//Makefile'. Stop.
make[1]: *** [_module_/home/mychardriver/] Error 2
make[1]: Leaving directory '/mykermelsources'
make: *** [all] Error 2
Transmitting command line parameter but it doesn't work. make SIDE=1
Seems the SIDE parameter/variable is never transmitted.
ifeq ($(SIDE),1)
MODULE_MAME = modulename_11
else
MODULE_MAME = modulename_22
endif
SRCS = drv/source.c lib/libsrc.c
OBJS = $(SRCS:.c=.o)a
obj-m += $(MODULE_MAME).o
$(MODULE_MAME)-y = $(OBJS)
KDIR := /mykermelsources/
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) SIDE=$(SIDE) modules
clean:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) clean
How can I build 2 kernel modules from same multiple source files ?
Just faced this issue, and this is what I did:
For each moduleX you want to build, write a Kbuild_moduleX with the targets. Example:
obj-$(MODULE) += MODULE.o
MODULE-y := source.o
Then, in your Makefile_moduleX, do:
all:
cp Kbuild_moduleX Kbuild
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
rm Kbuild
This works because the kernel scripts will give Kbuild priority over reading Makefile.
To compile, do make -f Makefile_moduleX
Is it pretty? No. Does it work? Yes.

can we install kernel module with make file

I have working kernel module which I install manually with insmod/modprobe command as learnt by reading book. however I was wondering if there is way to do it automatically after compiling - So basically how to automate insmod/modprobe command ?
My modprobe has a dependent file thread_module.o as well
My make file so far
obj-m := wakeup_counter.o
obj-m += thread_module.o
$INSTALL_MOD_PATH = /lib/modules/2.6.32-5-amd64/
all:
make -C /lib/modules/2.6.32-5-amd64/build M=$(PWD) modules
install:
make $(INSTALL_MOD_PATH) =/build modules_install
clean:
make -C /lib/modules/2.6.32-5-amd64/build M=$(PWD) modules
output after running : make install
root#xyz:/home/xyz/Desktop/Drivers/symbols# make install
make -C /lib/modules/2.6.32-5-amd64/build M=/home/xyz/Desktop/Drivers/symbols modules_install
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-5-amd64'
INSTALL /home/xyz/Desktop/Drivers/symbols/thread_module.ko
INSTALL /home/xyz/Desktop/Drivers/symbols/wakeup_counter.ko
DEPMOD 2.6.32-5-amd64
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-5-amd64'
Edit: After going through comments and https://www.kernel.org/doc/Documentation/kbuild/modules.txt I tried to add install command but I dont see any modules in the build path - Also at high level I get what we write in cmd prompt we type in Makefile but if someone can give an example it would help me to understand with nice base case to refer.
obj-m := wakeup_counter.o
obj-m += thread_module.o
KDIR = /lib/modules/2.6.32-5-amd64/build
all:
make -C $(KDIR) M=$(PWD) modules_install
clean:
make -C $(KDIR) M=$(PWD) clean
Example of command shell instruction being used as rule in Makefile:
install:
modprobe wakeup_counter
modprobe thread_module
Enhancing the answer posted by #cm161 for future users to highlight exact steps which worked for me
With below Makefile use following steps
Step 1: make ( type just make command) - for creation of modules i.e. .ko files and associated files
Step 2: make install
Step 3 : now do lsmod you should be able to see new modules
obj-m := wakeup_counter.o
obj-m += thread_module.o
KDIR = /lib/modules/2.6.32-5-amd64/build
all:
make -C $(KDIR) M=$(PWD) modules
cp wakeup_counter.ko /lib/modules/2.6.32-5-amd64/
cp thread_module.ko /lib/modules/2.6.32-5-amd64/
install:
modprobe wakeup_counter
modprobe thread_module
clean:
make -C $(KDIR) M=$(PWD) clean

Resources