here is the simple module program code.
#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 %d\n",hello3_data);
}
module_init(hello_3_init);
module_exit(hello_3_exit);
I've initialized a variable with __initdata
macro and a function with __init
. when I did insmod
the module was inserted and i was able to see the log message(/var/log/messages). But, when I did rmmod
it was unable to remove it, and it says Resource busy
.
My question is does the `modules_init` function cleans the memory of `hello3_data`??
or it is done by `module_exit`??.
Someone please explain.
Please when declaring the varialble hello3_data
you're using the __initdata
modifier which specifies that the variable shall be used in only the __init
function.
Try recompile your kernel module with options like make CONFIG_DEBUG_SECTION_MISMATCH=y
and you shall see warnings like this:
WARNING: /home/pengyu/temp/yusen/test_mod.o(.exit.text+0x3): Section mismatch in reference from the function cleanup_module() to the variable .init.data:hello3_data
The function __exit cleanup_module() references
a variable __initdata hello3_data.
This is often seen when error handling in the exit function
uses functionality in the init path.
The fix is often to remove the __initdata annotation of
hello3_data so it may be used outside an init section.
You could simply remove __initdata
and try again.
EDITED:
Here I'm trying to provide further explanations. The kernel module itself is in the format of ELF (Executable and Linkable Format)
(with some kernel-module-specific sections). Feature of the .init
and .fini
sections is supported by the linkers and loaders including insmod
.
In this case the attribute #define __initdata __section(.init.data)
works like __attribute__((section(".init.data")))
which explicitly specifies which section the data/function shall be put in.
As a kernel module the section of .init
is not guaranteed to be kept after module initialization, and anything inside that section is not supposed to be referenced outside the initialization function. See page 31 of Linux Device Drivers, Third Edition:
The _init token in the definition may look a little strange; it is a hint to the kernel that the given function is used only at initialization time. The module loader drops the initialization function after the module is loaded, making its memory available for other uses. There is a similar tag (_initdata)for data used only during initialization. Use of __init and __initdata is optional, but it is worth the trouble. Just be sure not to use them for any function (or data structure)you will be using after initialization completes