linux内核段属性机制

以subsys_initcall和module_init为例

subsys_initcall是一个宏,定义在linux/init.h中。经过对这个宏进行展开,发现这个宏的功能是:将其声明的函数放到一个特定的段:.initcall4.init

subsys_initcall
__define_initcall("4",fn,4)

以下文件在/include/linux/init.h:

分析module_init宏,可以看出它将函数放到.initcall6.init

module_init
__initcall
device_initcall
__define_initcall("6",fn,6)

打开编译过的内核源码树中的的/arch/arm/kernel/vmlinux.lds文件(没编译没有这个文件):

SECTIONS
{
. = 0xC0000000 + 0x00008000;
.init : { /* Init code and data */
_stext = .;
_sinittext = .;
*(.head.text)
*(.init.text) *(.cpuinit.text) *(.meminit.text)
......
. = ALIGN(16); __setup_start = .; *(.init.setup) __setup_end = .;
__initcall_start = .; *(.initcallearly.init) __early_initcall_end = .;
*(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init)
*(.initcall2.init) ... __initcall_end = .;
......

内核在启动过程中需要顺序的做很多事,内核如何实现按照先后顺序去做很多初始化操作。内核的解决方案就是给内核启动时要调用的所有函数归类,执行内核某一个函数然后每个类就会按照一定的次序被调用执行。这些分类名就叫.initcallx.init。x的值从1到8。内核开发者在编写内核代码时只要将函数设置合适的级别,这些函数就会被链接的时候放入特定的段,内核启动时再按照段顺序去依次执行各个段即可(通过某一个函数,链接脚本只是规定了某一程序段在内存中的存放位置)。

内核源代码

以下文件在/init/main.c

extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];

static void __init do_initcalls(void)
{
initcall_t *fn;

for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);

/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}

执行do_initcalls就会按照设定好的顺序去执行,通过函数的内容可以猜测出其原理就是链接脚本设置好的顺序,然后do_initcalls执行就会去按照链接脚本设置好的顺序一个个遍历

更多相关文章

  1. 浅谈Oracle函数返回Table集合
  2. Linux-C语言函数手册
  3. Linux 下nice 函数用法提高一个进程的友善值
  4. 【Linxu内核设计与实现】-第7章 中断和中断处理
  5. 设置查看linux 造成程序Core dumped 的函数调用层次
  6. Linux2.6内核调度器介绍
  7. Linux 3.4.39内核编译配置选项介绍
  8. ubuntu14.04下qemu调试linux内核
  9. ATT汇编与Intel汇编的区别,摘自《深入分析linux内核源码》一书

随机推荐

  1. 安卓中的shape
  2. Android Studio 学习之 Android SDK快速
  3. AES加解密在Android(安卓)4.2上的Encrypt
  4. Android Matrix详解
  5. Android(安卓)OpenGL射线拾取&手势旋转(二
  6. Android(安卓)基础Action
  7. android实现文件下载功能
  8. Android布局之LinearLayout与RelativeLay
  9. Android 滑动效果高级篇(七)—— 华丽翻页
  10. Android五大布局(一)LinearLayout.FrameLay