GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET

, GCC特性之__init修饰解析 - kasalyn的专栏 - 博客频道 - CSDN.NET

GCC特性之__init修饰解析


在driver文件中经常看到"__init"修饰的代码,那么__init标记有什么意义?

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

  1. /* These macros are used to mark some functions or  
  2.  * initialized data (doesn't apply to uninitialized data) 
  3.  * as `initialization' functions. The kernel can take this 
  4.  * as hint that the function is used only during the initialization 
  5.  * phase and free up used memory resources after 
  6.  * 
  7.  * Usage: 
  8.  * For functions: 
  9.  *  
  10.  * You should add __init immediately before the function name, like: 
  11.  * 
  12.  * static void __init initme(int x, int y) 
  13.  * { 
  14.  *    extern int z; z = x * y; 
  15.  * } 
  16.  * 
  17.  * If the function has a prototype somewhere, you can also add 
  18.  * __init between closing brace of the prototype and semicolon: 
  19.  * 
  20.  * extern int initialize_foobar_device(int, int, int) __init; 
  21.  * 
  22.  * For initialized data: 
  23.  * You should insert __initdata between the variable name and equal 
  24.  * sign followed by value, e.g.: 
  25.  * 
  26.  * static int init_variable __initdata = 0; 
  27.  * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; 
  28.  * 
  29.  * Don't forget to initialize data not at file scope, i.e. within a function, 
  30.  * as gcc otherwise puts the data into the bss section and not into the init 
  31.  * section. 
  32.  *  
  33.  * Also note, that this data cannot be "const". 
  34.  */  
  35.   
  36. /* These are for everybody (although not all archs will actually 
  37.    discard it in modules) */  
  38. #define __init      __section(.init.text) __cold notrace  
  39. #define __initdata  __section(.init.data)  
  40. #define __initconst __section(.init.rodata)  
  41. #define __exitdata  __section(.exit.data)  
  42. #define __exit_call __used __section(.exitcall.exit)  
  43.   
  44. /* 
  45.  * modpost check for section mismatches during the kernel build. 
  46.  * A section mismatch happens when there are references from a 
  47.  * code or data section to an init section (both code or data). 
  48.  * The init sections are (for most archs) discarded by the kernel 
  49.  * when early init has completed so all such references are potential bugs. 
  50.  * For exit sections the same issue exists. 
  51.  * 
  52.  * The following markers are used for the cases where the reference to 
  53.  * the *init / *exit section (code or data) is valid and will teach 
  54.  * modpost not to issue a warning.  Intended semantics is that a code or 
  55.  * data tagged __ref* can reference code or data from init section without 
  56.  * producing a warning (of course, no warning does not mean code is 
  57.  * correct, so optimally document why the __ref is needed and why it's OK). 
  58.  * 
  59.  * The markers follow same syntax rules as __init / __initdata. 
  60.  */  
  61. #define __ref            __section(.ref.text) noinline  
  62. #define __refdata        __section(.ref.data)  
  63. #define __refconst       __section(.ref.rodata)  
  64.   
  65. /* compatibility defines */  
  66. #define __init_refok     __ref  
  67. #define __initdata_refok __refdata  
  68. #define __exit_refok     __ref  
  69.   
  70.   
  71. #ifdef MODULE  
  72. #define __exitused  
  73. #else  
  74. #define __exitused  __used  
  75. #endif  
  76.   
  77. #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)

  1. /** 
  2.  * module_init() - driver initialization entry point 
  3.  * @x: function to be run at kernel boot time or module insertion 
  4.  *  
  5.  * module_init() will either be called during do_initcalls() (if 
  6.  * builtin) or at module insertion time (if a module).  There can only 
  7.  * be one per module. 
  8.  */  
  9. #define module_init(x)  __initcall(x);  
  10.   
  11. /** 
  12.  * module_exit() - driver exit entry point 
  13.  * @x: function to be run when driver is removed 
  14.  *  
  15.  * module_exit() will wrap the driver clean-up code 
  16.  * with cleanup_module() when used with rmmod when 
  17.  * the driver is a module.  If the driver is statically 
  18.  * compiled into the kernel, module_exit() has no effect. 
  19.  * There can only be one per module. 
  20.  */  
  21. #define module_exit(x)  __exitcall(x);  

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

  1. #define __initcall(fn) device_initcall(fn)   
  2.   
  3. #define device_initcall(fn)        __define_initcall("6",fn,6)  

关于宏__define_initcall 可结合上一篇

LINUX内核中的xx_initcall初始化标号

得到进一步理解

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





如果你觉得本文对你有帮助,请点一下左下角的“好文要顶”和“收藏该文”
原文地址:https://www.cnblogs.com/liujinghuan/p/5841492.html