GCC特性之__init修饰解析

来源:互联网 发布:king网址软件 编辑:程序博客网 时间:2024/06/11 06:50
在driver文件中经常看到"__init"修饰的代码,那么__init标记有什么意义?

先看下面这段英文说明:(include/linux/init.h)

/* These macros are used to mark some functions or  * initialized data (doesn't apply to uninitialized data) * as `initialization' functions. The kernel can take this * as hint that the function is used only during the initialization * phase and free up used memory resources after * * Usage: * For functions: *  * You should add __init immediately before the function name, like: * * static void __init initme(int x, int y) * { *    extern int z; z = x * y; * } * * If the function has a prototype somewhere, you can also add * __init between closing brace of the prototype and semicolon: * * extern int initialize_foobar_device(int, int, int) __init; * * For initialized data: * You should insert __initdata between the variable name and equal * sign followed by value, e.g.: * * static int init_variable __initdata = 0; * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; * * Don't forget to initialize data not at file scope, i.e. within a function, * as gcc otherwise puts the data into the bss section and not into the init * section. *  * Also note, that this data cannot be "const". *//* These are for everybody (although not all archs will actually   discard it in modules) */#define __init__section(.init.text) __cold notrace#define __initdata__section(.init.data)#define __initconst__section(.init.rodata)#define __exitdata__section(.exit.data)#define __exit_call__used __section(.exitcall.exit)/* * modpost check for section mismatches during the kernel build. * A section mismatch happens when there are references from a * code or data section to an init section (both code or data). * The init sections are (for most archs) discarded by the kernel * when early init has completed so all such references are potential bugs. * For exit sections the same issue exists. * * The following markers are used for the cases where the reference to * the *init / *exit section (code or data) is valid and will teach * modpost not to issue a warning.  Intended semantics is that a code or * data tagged __ref* can reference code or data from init section without * producing a warning (of course, no warning does not mean code is * correct, so optimally document why the __ref is needed and why it's OK). * * The markers follow same syntax rules as __init / __initdata. */#define __ref            __section(.ref.text) noinline#define __refdata        __section(.ref.data)#define __refconst       __section(.ref.rodata)/* compatibility defines */#define __init_refok     __ref#define __initdata_refok __refdata#define __exit_refok     __ref#ifdef MODULE#define __exitused#else#define __exitused  __used#endif#define __exit          __section(.exit.text) __exitused __cold notrace

是不是很清楚了?"__init"仅告诉kernel,此函数仅在初始化阶段使用,使用后所占用的内存资源会释放

常用实例:

module_init(hello_init);

static int __init hello_init(void)
{
    printk(KERN_ALERT "Hello, world!/n");
    return 0;
}

关于module_init可参考 下面的解释:(include/linux/init.h)

/** * module_init() - driver initialization entry point * @x: function to be run at kernel boot time or module insertion *  * module_init() will either be called during do_initcalls() (if * builtin) or at module insertion time (if a module).  There can only * be one per module. */#define module_init(x)__initcall(x);/** * module_exit() - driver exit entry point * @x: function to be run when driver is removed *  * module_exit() will wrap the driver clean-up code * with cleanup_module() when used with rmmod when * the driver is a module.  If the driver is statically * compiled into the kernel, module_exit() has no effect. * There can only be one per module. */#define module_exit(x)__exitcall(x);

关于__initcall(x) 可继续参考此文件:(include/linux/init.h)

#define __initcall(fn) device_initcall(fn) #define device_initcall(fn)        __define_initcall("6",fn,6)

关于宏__define_initcall 可结合上一篇

LINUX内核中的xx_initcall初始化标号

得到进一步理解

*******Done*******