• 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******





    如果你觉得本文对你有帮助,请点一下左下角的“好文要顶”和“收藏该文”
  • 相关阅读:
    一个web程序员的年终总结
    编程要诀-心态
    初识vps,域名与购买,初步配置
    一个好的学习方法真的很重要——费曼学习法
    [译]C# 7系列,Part 8: in Parameters in参数
    Dalsa 8K彩色相机Camera link C#采图
    精简Command版SqlHelper
    ASP.NET MVC模块化开发——动态挂载外部项目
    net core WebApi——依赖注入Autofac
    .NET Core 3 WPF MVVM框架 Prism系列之命令
  • 原文地址:https://www.cnblogs.com/liujinghuan/p/5841492.html
Copyright © 2020-2023  润新知