InsaneCoder
InsaneCoder

Reputation: 8268

Does the main kernel "make" command also make modules internally?

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

Answers (2)

InsaneCoder
InsaneCoder

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

Ian Abbott
Ian Abbott

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

Related Questions