Reputation: 8268
I am learning how to write kernel drivers and this is my first attempt to build one. I have created a folder drivers/naveen/
for my module files - hello.c
,Kconfig
and Makefile
. These are the contents of these files :
Kconfig
config HELLO_WORLD
tristate "Hello World support"
default m
---help---
This option enables printing hello world
Makefile
obj-$(CONFIG_HELLO_WORLD) += hello.o
hello.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init hello_init(void)
{
printk(KERN_ERR "This is NAVEEN module");
return 0;
}
static int __exit hello_exit(void)
{
printk(KERN_ERR "NAVEEN exiting module");
return 0;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Naveen");
MODULE_LICENSE("GPL");
Also, I have added the following line in drivers/Makefile
:
obj-$(CONFIG_HELLO_WORLD) += naveen/
and the following line in drivers/Kconfig
:
source "drivers/naveen/Kconfig"
My generated .config
contains CONFIG_HELLO_WORLD=m
.
I did make ARCH=x86_64 -j16
and I can see hello.ko
generated. Why? I was expecting to get it generated only when I had done make modules
as its set to be as modular with m
inside the .config
, and not to be compiled with just make. Can someone please explain the behaviour to me or what wrong I am doing?
Does that mean that make
also does make modules
. I can see from make help
that make
actually means make all
and hence it should do make modules
as well internally, and so there should be no need to do make modules
once make is successful.
Upvotes: 0
Views: 842
Reputation: 8268
Linux kernel consists of 2 parts - core kernel and modules. When we do simply make
, it means make all
which means make vmlinux && make modules
. Hence, if we have done make
, we need not do make modules
again and we can simply run the command make modules_install
without doing make modules
.
Upvotes: 1
Reputation: 17413
You are doing nothing wrong. The modules
target has been a dependency of the all
target since kernel version 2.6.0 (actually since kernel version 2.5.60 I think).
The way you are adding your module is to add it to the kernel source tree. It is also possible to build custom modules outside the kernel source tree - so called "out-of-tree" kernel modules. Typically, those don't need a Kconfig file and the obj-$(CONFIG_HELLO_WORLD)
would be replaced with obj-m
in the Makefile.
Here is a Makefile for an "out-of-tree" version of your "hello" module:
ifneq ($(KERNELRELEASE),)
# Kbuild part of Makefile
obj-m += hello.o
else
# Normal part of Makefile
#
# Kernel build directory specified by KDIR variable
# Default to running kernel's build directory if KDIR not set externally
KDIR ?= "/lib/modules/`uname -r`/build"
all:
$(MAKE) -C "$(KDIR)" M=`pwd` modules
clean:
$(MAKE) -C "$(KDIR)" M=`pwd` clean
endif
This Makefile uses a common trick so that the same Makefile can be invoked as a "normal" Makefile and as a "kbuild" Makefile. The "normal" part between the else
and endif
lines invokes $(MAKE)
on the kernel's Makefile (the location of which is specified by the KDIR
variable), telling it to build the modules
target in the current directory (specified by M=`pwd`
). The "kbuild" part is between the ifneq($(KERNELRELEASE),)
and else
lines and is in the normal "kbuild" format for building parts of the kernel.
That trick depends on the KERNELRELEASE
variable being initially unset or empty. It will be set to a non-empty value by the kernel's Makefile rules.
Upvotes: 0