linux内核中__initdata的作用

在看android AOSP时看到这样一行代码

unsigned int __atags_pointer __initdata

__atags_pointer是Uboot传递给kernel的设备树首地址

这里定义了一个无符号整形,将用到它表示一个地址,但是后面__initdata代表什么呢?
引用内核中的宏定义__init,__initdata,_exitdata程序猿Ricky的日常干货的博客-CSDN博客
在linux内核中,我们经常会使用到一些宏定义,比如__init,__initdata,__exitdata等等。那么这些宏定义到底什么意思呢?接下来我们就来看一下。

kernel/include/linux/init.h:
我们来选择一些常用的宏定义,在路径:/vendor/nxp-opensource/kernel_imx/include/linux/init.h下,有如下代码:

50  #define __init      __section(".init.text") __cold  __latent_entropy __noinitretpoline __nocfi
51  #define __initdata  __section(".init.data")
52  #define __initconst __section(".init.rodata")
53  #define __exitdata  __section(".exit.data")
54  #define __exit_call __used __section(".exitcall.exit")

我们可以看到大多是和section相关的定义,这个段定义什么作用呢,它是为了告诉链接器应该把这个函数或者数据放置在哪个位置。一般是指放置到内核镜像的哪个位置上。内核相当于一个非常大的可执行程序,它里面包含了好多内容,我们按照分段的原则来存放这些内容。具体段的存放规则是由vmlinux.lds文件定义,它是负责把段信息告诉链接器的,当然我们也要在代码中声明属于哪个段。

通常编译器将函数放在.text 节,变量放在.data 或 .bss 节,使用 section 属性,可以让编译器将函数或变量放在指定的节中。那么例如:前面对__init 的定义便表示将它修饰的代码放在.init.text节。内核把段分的非常细致,是因为它会在运行过程中去定位相应的数据和代码,这样将更加方便处理。就像__init 修饰的所有代码都放在.init.text段,它只在启动阶段会被内核调用到,当初始化结束后就会释放这部分内存,以便充分利用内存,这个就是属于内存管理的部分了。

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

__attribute__((section("section_name")))

可是上面的定义并不是如此,其实__section也是一个宏定义,我们在/vendor/nxp-opensource/kernel_imx/include/linux/compiler_attributes.h下可以看到

267  #define __section(section)              __attribute__((__section__(section)))

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容