Let we've written the following simplest module source file:
#include <linux/init.h>
#include <linux/module.h>
static int __init md_init(void){
printk("Hello kernel");
return 0;
}
static void __exit md_exit(void){
printk("Goodbye kernel");
}
module_init(md_init);
module_exit(md_exit);
How can I see this source after preprocessing? I want to know how are __init and __exit macros deployed and what's the module_init(md_init) and module_exit(md_exit)? How it works?
If you have your driver in the kernel, you can get it by doing:
make path-to-module/srcfile.i
As an example, I created a test directory under drivers/staging/, put your file in there, created a simple Kconfig and Makefile, updated the Kconfig and Makefile in staging, then ran
make drivers/staging/test/test.i
If you have the source outside the kernel tree, but have a Kconfig and Makefile set up, then:
make -C /path/to/kernel/src M=/path/to/driver srcfile.i
The result was of init and exit macros:
static int __attribute__ ((__section__(".init.text"))) __attribute__((__cold__)) __attribute__((no_instrument_function)) md_init(void)
{
printk("Hello kernel");
return 0;
}
static void __attribute__ ((__section__(".exit.text"))) __attribute__((__used__)) __attribute__((__cold__)) __attribute__((no_instrument_function)) md_exit(void)
{
printk("Goodbye kernel");
}
If you only plan to get the preprocessed output of kernel module, don't use Makefile, cause Makefiles (sub-make) will try to produce an object file with ability to insert into the kernel. Which contradicts with gcc -E, which just stops after preprocessing. So, just do the followings by using gcc:
gcc -E new.c -I$TREE/include -I$TREE/arch/x86/include -I$TREE/include/uapi
-E is to get the preprocessed output, $TREE is the location of your kernel tree and if you use other arch then change x86. And we know that, gcc takes include dir parameter with -I, so pass all the kernel include dir through -I. Hope this helps!
,To see the intermediate files. i.e the .i files and .s files after the compiler pre-processing, change the Makefile and add EXTRA_CFLAGS=’-save-temps’
Makefile:
make -C /usr/lib/modules/$(shell uname -r)/build M=$(shell pwd) modules EXTRA_CFLAGS=’-save-temps’
after this, once you run 'make' you can see the your_module_filename.i in
ls /usr/lib/modules/$(uname -r)/build/{your_modulename.i}
and the source with pre-processor changes will be available almost at the end of the file.