在driver文件中经常看到"__init"修饰的代码,那么__init标记有什么意义?
是不是很清楚了?"__init"仅告诉kernel,此函数仅在初始化阶段使用,使用后所占用的内存资源会释放
关于宏__define_initcall 可结合上一篇
先看下面这段英文说明:(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******