__init 、 __initdata 的解释

本文解释了Linux内核中用于标记初始化函数和数据的宏的用途和使用方法,包括如何在函数和数据中添加相应的宏来确保内核在初始化阶段正确地管理和释放资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习linux内核代码的时候,经常会遇见以上的符号,不知道是什么意思,貌似在C语言中不曾有规则定义过,下面是它的用法。
在linux中“/include/linux/init.h”中定义以上宏。
定义如下:

  1. #define __init      __section(.init.text) __cold notrace 
  2. #define __initdata  __section(.init.data) 
  3. #define __initconst __section(.init.rodata) 
  4. #define __exitdata  __section(.exit.data) 
  5. #define __exit_call __used __section(.exitcall.exit) 

__init 、 __initdata ......的使用方法在原文件中是这样注释的:

  1. /* These macros are used to mark some functions or <span style="white-space: pre;"> </span> ||这些宏用于标记一些函数和初始化的数据(不能用于非初始化的数据),作为“初始化”的功能。
  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||<span style="background-color: rgb(255, 255, 255);">源。</span>
  5. * phase and free up used memory resources after
  6. *
  7. * <strong><span style="color: rgb(255, 0, 0); font-size: 18px;">Usage</span></strong>:||用法
  8. * <span style="font-size: 18px;"><strong>For functions:</strong></span>||用于函数
  9. *
  10. * You should add __init immediately before the function name, like:||你应该直接添加__init在函数名字的前面
  11. *
  12. <span style="color: rgb(0, 102, 0);"> * static void __init initme(int x, int y)
  13. * {
  14. *    extern int z; z = x * y;
  15. * }</span>
  16. *
  17. * If the function has a prototype somewhere, you can also add//如果函数已有一个原型,你也可以添加__init在靠近函数原型的括号和分号之间
  18. * __init between closing brace of the prototype and semicolon:
  19. *
  20. <span style="color: rgb(0, 102, 0);"> * extern int initialize_foobar_device(int, int, int) __init;</span>
  21. *
  22. * <span style="font-size: 18px;">For initialized data:</span><span style="font-size: 14px;">//用于初始化数据</span>
  23. * You should insert __initdata between the variable name and equal||你应该把__initdata放在变量名和等号中间,后面跟的是具体的值
  24. * sign followed by value, e.g.:
  25. *
  26. <span style="color: rgb(0, 102, 0);"> * static int init_variable __initdata = 0;
  27. * static const char linux_logo[] __initconst = { 0x32, 0x36, ... };</span>
  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. * <span style="color: rgb(68, 68, 68); line-height: 13px; font-family: Verdana, sans-serif; font-size: 9pt;">不要忘了初始化数据在文件范围内,即在一个函数中,如gcc,否则将数据到的bss段,而不是到init部分。</span><span style="color: rgb(68, 68, 68); line-height: 13px; font-family: Verdana, sans-serif; font-size: 9pt; background-color: rgb(230, 236, 249);">另外请注意,这个数据不能是“const”。</span>
  33. * Also note, that this data cannot be "const".
  34. */ 
/* 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:||你应该直接添加__init在函数名字的前面
 *
 * 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在靠近函数原型的括号和分号之间
 * __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||你应该把__initdata放在变量名和等号中间,后面跟的是具体的值
 * 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.
 * 不要忘了初始化数据在文件范围内,即在一个函数中,如gcc,否则将数据到的bss段,而不是到init部分。另外请注意,这个数据不能是“const”。
 * Also note, that this data cannot be "const".
 */
后面中文是我给出的简单翻译。

内核中采用这种方式去标记一些初始化的函数和数据,其中一个原因是标记为初始化的函数和数据,表明该函数和数据仅在初始化期间使用。在模块装载之后,模块装载就会将初始化函数扔掉。这样可以将该函数占用的内存释放出来。

在学习这些宏的作用时可参考博文:http://blog.chinaunix.net/uid-26694208-id-3078013.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值