.ko file not being built when building kernel modules - c

I am currently trying to learn how to make kernel modules from the 'Linux Device Drivers' book. I have the basic example typed out as follows:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk("Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
and I am using the following makefile to compile the file above, hello.c
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
When I run the make command, the console output is as follows:
make -C /lib/modules/5.13.0-40-generic/build M=/home/finlay/src/linux-drivers modules
make[1]: Entering directory '/usr/src/linux-headers-5.13.0-40-generic'
MODPOST /home/finlay/src/linux-drivers/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-5.13.0-40-generic'
For some reason the only files which are created are the following:
.Module.symvers.cmd
.modules.order.cmd
Module.symvers
modules.order
None of the files created seems to specifically be about the hello.c file. What's very strange is that this same file was working initially to create the hello.ko file however it is no longer working. Any ideas as to why this is not working?

I have now found the solution, I removed some lines from the makefile as I believed them to be redundant as I thought that they were only used if you were directly invoking the makefile from the kernel build directory. The correct makefile is 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

Related

Linux kernel module programming - Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: -fstack-protector not supported by compiler

I am on Linux Ubuntu 14.04. I want to start Linux Kernel Module Programming. I have hello.c (simple Hello World module) and Makefile. But, on "make" command, I get error.
I tried Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: -fstack-protector-strong not supported by compiler , but it did not work for me.
hello.c
/* hello.c − Illustrating the __init, __initdata and __exit macros. */
#include <linux/module.h>
/* Needed by all modules */
#include <linux/kernel.h>
/* Needed for KERN_INFO */
#include <linux/init.h>
/* Needed for the macros */
static int hello3_data __initdata = 3;
static int __init hello_3_init(void)
{
printk(KERN_INFO "Hello, world %d\n", hello3_data);
return 0;
}
static void __exit hello_3_exit(void)
{
printk(KERN_INFO "Goodbye, world 3\n");
}
module_init(hello_3_init);
module_exit(hello_3_exit);
Makefile
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
On "make" :-
k#k-Inspiron-3542:~/Kernel programs$ make
make -C /lib/modules/4.2.0-27-generic/build M=/home/k/Kernel programs modules
make[1]: Entering directory `/usr/src/linux-headers-4.2.0-27-generic'
arch/x86/Makefile:138: CONFIG_X86_X32 enabled but no binutils support
Makefile:662: Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: -fstack-protector not supported by compiler
make[1]: *** No rule to make target `programs'. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-27-generic'
make: *** [all] Error 2
Currently, my ubuntu has 4.2 kernel. I even tried this on 3.x kernel, but there was this same error.
Please help me in this. Thanks. :)
I had searched a lot before asking this question, but no solution worked for me. I continued my search and finally, this solution worked for me. https://askubuntu.com/questions/367838/compiling-error-while-installing-realtek-rtl8111e-in-64-bit-13-10-config-x86-x
Strangely, there should be no space(s) in the directory name in which kernel modules are there. So, I removed the space and it worked.
Hope it will help someone in future. :)
Your file works OK here. With your Makefile, and with the default Makefile:
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
The files hello.ko, hello.mod.c, hello.mod.o, hello.o, modules.order, Module.symvers are created. May be install this: sudo apt install g++ binutils-dev
If you don't have spaces in your compile directory and you're still getting this error, your kernel compilation may be failing because its directory belongs to root and you're running as an unprivileged user. Try sudo make

Build Linux Kernel Module using Makefile with different pathname

I am trying to compile a Linux kernel module using the standard example Makefile specified in the Linux Kernel Module Programming Guide. If the Makefile is called Makefile, then everything works. If I rename the Makefile to Makefile.hello or something else, then it fails as it cannot find the path Makefile. I was wondering if there is a command or set of flags I can add to my Makefile to make this function properly. I need to rename the Makefile as I am calling it from CMake. Cmake creates its own Makefiles and will commonly overwrite what I already have.
I replaced my kernel module code with the hello world example and replicated the problem. I know its the makefile.
hello world example hello.c
/*
* hello−1.c − The simplest kernel module.
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
Makefile
obj-m += hello.o
ifeq (,$(KDIR))
KDIR := /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) $(KCONFIG) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
If makefile is called Makefile. (Successfully builds)
$> make -f Makefile
make -C /lib/modules/4.4.0-21-generic/build M=/home/msmith/Desktop/kernel-test modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-21-generic'
CC [M] /home/msmith/Desktop/kernel-test/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/msmith/Desktop/kernel-test/hello.mod.o
LD [M] /home/msmith/Desktop/kernel-test/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-21-generic'
Make output if makefile is called Makefile.hello (Fails to build)
$> make -f Makefile.hello
make -C /lib/modules/4.4.0-21-generic/build M=/home/msmith/Desktop/kernel-test modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-21-generic'
scripts/Makefile.build:44: /home/msmith/Desktop/kernel-test/Makefile: No such file or directory
make[2]: *** No rule to make target '/home/msmith/Desktop/kernel-test/Makefile'. Stop.
Makefile:1396: recipe for target '_module_/home/msmith/Desktop/kernel-test' failed
make[1]: *** [_module_/home/msmith/Desktop/kernel-test] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-21-generic'
Makefile.hello:10: recipe for target 'all' failed
make: *** [all] Error 2
I tried adding the -f to the internal MAKE parameters, however that just caused more issues.
Move all Kbuild-related logic into the file Kbuild. Kernel's build system checks file with this name first, so it won't look into Makefile, created by CMake. This feature is documented in Documentation/kbuild/makefiles.txt.
I use exactly this approach in my CMake projects, related with Linux kernel.
Open script/Makefile.build into kernel tree:
41 # The filename Kbuild has precedence over Makefile
42 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
43 kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
44 include $(kbuild-file)
This part of code (43-44) include Makefile with name 'Makefile'.
The default Makefile. Name = Makefile ... and Makefile-hello, or Makefile.hello.
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
$ make : OK
$ make -f Makefile-hello OK
$ make -f Makefile.hello Also OK.
Your Makefile : $ make -f Makefile.msmith OK, no errors.

Linux Kernel Module Compilation

I am having trouble building helloworld Linux kernel module. I am using VirtualBox from SUN with Ubuntu ISO image that I downloaded from Ubuntu web site. Any help will be greatly appreciated. Bellow are the c code and the error message that I am getting:
The module file is called hellowrld.c and it contains the code below:
#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");
static int __init helloworld_init(void)
{
printk(KERN_INFO "Hello world!\n");
return 0;
}
static void __exit helloworld_exit(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(helloworld_init);
module_exit(helloworld_exit);
The make file is called makefile.c and it contains the code below:
obj -m += helloworld.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
The error message that I am getting when I run make command is below:
cc makefile.c -o makefile
makefile.c:1:4: error: expected '=', ',', ';', 'asm' or '__attribute__' before '-' token
obj-m helloworld.o
make: *** No targets specified no makefile found. Stop
The right Makefile looks like this ...
obj-m := helloworld.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order

error in generating .ko file for simple hello world module for linux kernel

I am a beginner in linux kernel development and trying to load a simple module in linux.
I have created an hello.c file, to be loaded as kernel module.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A Simple Hello World module");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
return 0;
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
this hello.c and the makefile both, I have kept in /home/linux/ directory.
makefile
obj-m +=hello.o
src= /usr/src/linux-headers-3.5.0-17-generic
all:
$(MAKE) -C $(src) SUBDIR-$(PWD) modules
clean:
rm -rf *.o *.ko
to generate .ko file, when I run the make command on terminal from the /home/linux directory , I get following error
h2o#h2o-Vostro-1015:~/linux$ make
make -C /usr/src/linux-headers-3.5.0-17-generic SUBDIR-/home/h2o/linux modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
make[1]: *** No rule to make target `SUBDIR-/home/h2o/linux'. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [all] Error 2
kindly advise what am I missing or doing wrong..
Makefile
obj-m := hello.o # Module Name is hello.c
KDIR := /lib/modules/$(shell uname -r)/build
all: $(MAKE) -C $(KDIR) M=$(PWD) modules
clean: $(MAKE) -C $(KDIR) M=$(PWD) clean $(RM) Module.markers
modules.order
its not guaranteed that headers file will always be located in /usr/src directory, but it will surely be located in /lib/modules directory.
make sure that system has latest header files
to find out which header files to be present
run `
uname -r
on terminal, output will be like
3.5.0-17-generic
to install header files run
sudo apt-get install linux-headers-$(uname -r)
You have:
$(MAKE) -C $(src) SUBDIR-$(PWD) modules
But it seems like you want:
$(MAKE) -C $(src)/SUBDIR-$(PWD) modules
Or something along those lines; where does the source code live? You need to -C there.
Kernel build system is a bit complex. It would be good to read the kernel build process documentation. Which gives better understanding about, say,
Targets like --- modules / modules_install
Options like --- -C $KDIR / M=$PWD
Command Syntax ---
$ make -C <path_to_kernel_src> M=$PWD
$ make -C /lib/modules/uname -r/build M=$PWD
$ make -C /lib/modules/uname -r/build M=$PWD modules_install
Loadable module goals --- obj-m
etc...

Compiling a simple device driver code

I just started learning linux device driver. I just wrote a simple device driver code and tried compiling it but when ever i do a make i get the following error
make: Nothing to be done for `default'
Here is my device driver code.
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Manoj");
MODULE_DESCRIPTION("My First Driver");
static int __init ofd_init ( void ) {
printk (KERN_INFO "ofd registered");
return 0;
}
static int __exit ofd_exit ( void ) {
printk (KERN_INFO "ofd unregistered");
return 0;
}
module_init ( ofd_init );
module _exit ( ofd_exit );
And my Makefile is like this
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
And in the path /lib/modules/3.2.0-58-generic-pae/build is also present.
can anyone please tell why this particular make file not working ?
obj-m:= hello.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
Before make -C press tab for space
The problem is in the make file.
Give a tab space before the command.
This is a general rule in writing a Makefile.
Change
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
to
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
For more information about the error refer this link.

Resources