Saturday, June 14, 2014

KBuild System and Hello World Part 2

। जय श्री भगवान् ।
In the last post we saw how to compile module and by using the insmod command we were able to see the messages on initialization and module unload time using rmmod command. In this post I'll talk try to show you how to extend that information.

When you are having similar type of modules then you might want to have a common Kbuild file. This common Kbuild file may include some common flags that are shared across most of the files. Note that you still need to define the includes from within the separate Kbuild only. Let's try to make another module and let's try to create a top level Kbuild directory and build the two modules having some similar flags and some flags specific for module or particular file.

I created another directory called pks_modules and I've put the module_1 files under directory module_1 and created another directory module_2. This is how it looks like


pranay@linux-y7pi:~/pks_modules> ls -d */
common/  module_1/  module_2/
pranay@linux-y7pi:~/pks_modules> 
pranay@linux-y7pi:~/pks_modules> ls module_1/
Kbuild  Makefile  my_module1.c  my_module1.h
pranay@linux-y7pi:~/pks_modules> 
pranay@linux-y7pi:~/pks_modules> ls module_2/
Kbuild  Makefile  module_2.h  module2_p1.c  module2_p2.c
pranay@linux-y7pi:~/pks_modules> 
pranay@linux-y7pi:~/pks_modules> ls common/
common.h
pranay@linux-y7pi:~/pks_modules> 

I've created some more files for our new module_2. The files in module_1 are still unchanged. Now we'll invoke make in the top level directory pks_modules instead of invoking it under each directory separately. To do this only some minor changes are to be done. To begin with we would need a Kbuild file and a Makefile in the topdir. The Makefile is exactly same so I won't be posting it again. The Kbuild file for the top-directory looks like below,

obj-m=module_1/ module_2/
subdir-ccflags-y := -DMY_DEBUG_FLAG

So in the above KBuild file all we do is set the directories to be build as modules. We also define one flag which would be available to all files in module_1 and module_2.  That's it for the top level directory now let's move to module_2 directory. See how I've changed the ccflags-y to subdir-ccflags-y because I want that all sub directories should get the value of this flag. ccflags is limited to the directory in which the Kbuild file exists. The listings are shown below for module_2

obj-m := module2.o
module2-objs := module2_p1.o module2_p2.o
ccflags-y := -I$(src)/../common
CFLAGS_module2_p2.o := -DDEBUG

In the above listing I've defined a file specific flag using CFLAGS_<filename>.o. You'll see how it affects the output when you compile and run it. The ccflags-y is used for all files for this Kbuild instance but file specific flags are not. This is where you can define new flags for a particular file instead of putting it all globally. Here are the listing of the rest of the files,


#ifndef __MODULE2__H
#define __MODULE2__H
/*
 * Let's include some more files.
 */
#include <linux/highmem.h>
#include <linux/list.h>

int print_and_ret0(const char *str);
#endif

#include <common.h>
#include <module_2.h>

#ifndef MY_DEBUG_FLAG
int print_and_ret0(const char *str)
{
        pr_debug("MY_DEBUG_FLAG isn't set:%s",str);
        return 0;
}
#else
int print_and_ret0(const char *str)
{
        pr_debug("MY_DEBUG_FLAG is set:%s",str);
        pr_debug("The printed string above is at address %p\n",str);
        return 0;
}
#endif

#include <common.h>
#include <module_2.h>

static int __init module2_init(void)
{
        return print_and_ret0("Loading module 2\n");
}

static void __exit module2_exit(void)
{
        pr_devel("Unloading module 2. This is also enabled"
                        " when debug option is set\n");
}

module_init(module2_init);
module_exit(module2_exit);

Try to insert this module and check the output. I've used pr_devel for printing the exit message just to show that DEBUG flag was defined only for this file. Since DEBUG wasn't defined for the module2_p1.c therefore you won't see any messages when you load the module. On Unloading the module however you should see the message.

Exercise 1.3

 Try to create another module so you would've 3 directories instead of 2. Undefine a variable passed down from the top dir and try to compile.

No comments :

Post a Comment

Thanks for commenting!