内核中的宏定义__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
  • 3516

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

__bitwise   用于编译时sparse的强制类型检查,我们知道数值类型有Little-Endian,Big-Endian 以及 CPU-Endian等,  参考 http://www....

关于__init、__initdata和__exit、__exitdata的学习笔记

由于4年前对于C语言和Linux的知识贫乏,所以当时对于模块中的函数定义没有细看。这次在温习《LDD3》的时候,重新看了一下关于__init、__initdata和__exit、__exitdata的...

linux中的_init应用,含有__attribute__ 和section的意义和作用

在linux/init.h中定义如下: #define __init __section(.init.text) __cold notrace 有些版本的内核是这样定义的: #define __...

Linux内核与驱动开发学习总结:内核初始化宏__init(十二)

reference:http://blog.chinaunix.net/uid-25871104-id-2854544.html                      http://www....
  • fenggui
  • fenggui
  • 2015年06月26日 11:36
  • 784

linux启动流程(从start_kernel中的rest_init函数到init进程(1))

linux启动流程(从start_kernel中的rest_init函数到init进程(1))     在init/main.c文件中有个函数叫start_kernel,它是用来启动内核的主函数,我...

linux kernel是如何做到释放仅在启动时使用的内存的?

linux内核释放启动内存

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

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

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

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

MFC点点滴滴——对话框中使用定时器

在对话框中使用定时器: 1.定义定时器 #define TIMER1 1 2.开启定时器 在需要开启定时器的地方加入:SetTimer(TIMER1,1000,NULL);//启动定时器1,定...
  • zhd320
  • zhd320
  • 2012年11月22日 17:25
  • 3808
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内核中的宏定义__init,__initdata,__exitdata
举报原因:
原因补充:

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