Linux内核initcall,5.5.1 通过initcall初始化

5.5.1 通过initcall初始化

当创建init()之后,它会调用do_initcalls()函数,而do_initcalls()函数是用来调用所有被*_initcall宏系列所注册的初始化函数的,其实现代码如代码清单5-10所示。

代码清单5-10 使用initcalls初始化static void __init do_initcalls(void)

{

initcall_t *call;

for(call= &__initcall_start; call

if (initcall_debug) {

printk(KERN_DEBUG "Calling initcall 0x%p", *call);

print_symbol(":%s()", (unsigned long) *call);

printk("\n");

}

(*call)();

}

除了两个用于指示循环范围的标签__initcall_start和__initcall_end之外,该段代码很好理解。在C源代码和头文件中不会看到这样的标签,它们是在vmlinux链接阶段所用的链接脚本文件中定义的,用来表示使用*_initcall宏系列所生成的初始化函数列表的起始和结束位置。你可以在Linux内核顶层目录下的System.map文件中看到每一个这样的标签,这些标签以字符串__initcall开始,就像代码清单5-8中所表示的那样。

你如果对do_initcalls()函数中的调试打印信息感到疑惑的话,可以看一下由在引导过程中设置的内核命令行参数initcall_debug所执行的系统调用,该命令行参数允许打印如代码清单5-10所示的调试信息。内核只需简单地以内核命令行参数initcall_debug开始就可以实现这些调试信息的输出 。

下面是一个启用了这些调试语句时的输出的例子:...

Calling initcall 0xc00168f4: tty_class_init+0x0/0x3c()

Calling initcall 0xc000c32c: customize_machine+0x0/0x2c()

Calling initcall 0xc000c4f0: topology_init+0x0/0x24()

Calling initcall 0xc000e8f4: coyote_pci_init+0x0/0x20()

PCI: IXP4xx is host

PCI: IXP4xx Using direct access for memory space

...

注意在代码清单5-7中对customize_machine()的调用,调试信息的输出包括了函数的虚拟内核地址(在该例中是0xc000c32c)和函数大小(在这里是0x2c)。这是了解内核初始化的一个有效方法,特别是对不同子系统和模块的调用次序的理解。即使是在一个具有相当配置的嵌入式系统之上,也有几十个这样的初始化函数通过这种方式调用。在这个以嵌入式ARM XScale为平台的例子中,共有92个这样不同的内核初始化程序。

【责任编辑:云霞 TEL:(010)68476606】

点赞 0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值