内核中的宏定义__init,__initdata,__exitdata

原创 2016年05月31日 15:15:32

在linux内核中,我们经常会使用到一些宏定义,比如__init,__initdata,__exitdata等等。那么这些宏定义到底什么意思呢?接下来我们就来看一下。

kernel/include/linux/init.h:
我们来选择一些常用的宏定义,如下所示:

/* 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 __constsection(.init.rodata)
#define __exitdata  __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)


#define __exit          __section(.exit.text) __exitused __cold notrace

/* For assembly routines */
#define __HEAD      .section    ".head.text","ax"
#define __INIT      .section    ".init.text","ax"
#define __FINIT     .previous

#define __INITDATA  .section    ".init.data","aw",%progbits
#define __INITRODATA    .section    ".init.rodata","a",%progbits
#define __FINITDATA .previous

#define __CPUINIT        .section   ".cpuinit.text", "ax"
#define __CPUINITDATA    .section   ".cpuinit.data", "aw"
#define __CPUINITRODATA  .section   ".cpuinit.rodata", "a"

#define __MEMINIT        .section   ".meminit.text", "ax"
#define __MEMINITDATA    .section   ".meminit.data", "aw"
#define __MEMINITRODATA  .section   ".meminit.rodata", "a"

/* silence warnings when references are OK */
#define __REF            .section       ".ref.text", "ax"
#define __REFDATA        .section       ".ref.data", "aw"
#define __REFCONST       .section       ".ref.rodata", "a"

我们可以看到大多是和section相关的定义,这个段定义什么作用呢,它是为了告诉链接器应该把这个函数或者数据放置在哪个位置。一般是指放置到内核镜像的哪个位置上。内核相当于一个非常大的可执行程序,它里面包含了好多内容,我们按照分段的原则来存放这些内容。具体段的存放规则是由vmlinux.lds文件定义,它是负责把段信息告诉链接器的,当然我们也要在代码中声明属于哪个段。
通常编译器将函数放在.text 节,变量放在.data 或 .bss 节,使用 section 属性,可以让编译器将函数或变量放在指定的节中。那么例如:前面对__init 的定义便表示将它修饰的代码放在.init.text节。内核把段分的非常细致,是因为它会在运行过程中去定位相应的数据和代码,这样将更加方便处理。就像__init 修饰的所有代码都放在.init.text段,它只在启动阶段会被内核调用到,当初始化结束后就会释放这部分内存,以便充分利用内存,这个就是属于内存管理的部分了。

C代码中一般是按照这种规则来传递段信息的

__attribute__((section("section_name"))) 

可是上面的定义并不是如此,其实__section也是一个宏定义,我们在kernel/include/linux/compiler.h:

#ifndef __section
# define __section(S) __attribute__ ((__section__(#S)))
#endif

至于汇编代码我们就都很清楚了,直接使用.section即可。

版权声明:本文为博主原创文章,未经博主允许不得转载。

__initdata 的奇怪影响

__initdata 的奇怪影响作者: 宋立新Email:zjujoe@yahoo.com 恍然大悟后,当然也就不奇怪了。 不过当时 __initdata 修饰符确实给我们带来很大的困惑。  事情的经...
  • zjujoe
  • zjujoe
  • 2010年04月21日 16:23
  • 3608

Linux中,特殊宏 __bitwise、 __force、 __init 、__initdata 的使用

__bitwise   用于编译时sparse的强制类型检查,我们知道数值类型有Little-Endian,Big-Endian 以及 CPU-Endian等,  参考 http://www....
  • Ai_Knight
  • Ai_Knight
  • 2015年10月30日 11:38
  • 1195

__init的用法

在kernel中有很多__init,这个东东到底是何方神圣捏?且听小生我一一道来。下面是其定义:file:/include/linux/init.h 43 #define __init      __...
  • eroswang
  • eroswang
  • 2008年04月23日 13:52
  • 13408

linux中的__init __initdata __initconst __exitdata __exit_call 的学习小结

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

“.rodata.str1.4”的连接(link)问题

关于“.rodata.str1.4”的连接(link)问题【问题描述】 最近在写一些嵌入式底层相关的程序,有如下程序段(编译器为arm-linux-gcc 3.4.1):while(1) { uns...
  • ce123
  • ce123
  • 2012年11月21日 11:12
  • 4784

Linux段管理,BSS段,data段,.rodata段,text段

最近在解决一个编译问题时,一直在考虑一个问题,那就是Linux下可执行程序运行时内存是什么状态,是按照什么方式分配内存并运行的。查看了一下资料,就此总结一下,众所周知,linux下内存管理是通过虚存管...
  • wdxin1322
  • wdxin1322
  • 2014年10月28日 12:23
  • 4940

#pragma arm section说明

原文pdf文件请到如下地址下载查看:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/kic7Pjkh1mbSEg.ht...
  • humanbeng
  • humanbeng
  • 2012年09月12日 16:17
  • 7728

挖掘SimpleSection.o

挖掘SimpleSection.o
  • Allblues57
  • Allblues57
  • 2015年03月09日 11:24
  • 449

GNU/GCC/G++ 编译/链接生成的常见段(section)表

自建开发平台最令人头疼的莫过于处理链接器产生的大量错误。其中难免接触到段。本文列出了大多出可以碰到的标准段名及其定义,希望可以给你带来帮助。...
  • zvvzxzko2006
  • zvvzxzko2006
  • 2015年09月17日 11:44
  • 1470

快速理解 .bss、.data和.rodata

全局变量是放在全局内存中的,用static修饰的局部变量也是会放在放全局内存的,它的作用域是局部的,但生命期是全局的。 全局强调的是它的生命期,而不是它的作用域,所以有时可能把两者的概念互换。一般来说...
  • qq_26626709
  • qq_26626709
  • 2016年07月12日 13:53
  • 1118
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内核中的宏定义__init,__initdata,__exitdata
举报原因:
原因补充:

(最多只允许输入30个字)