zoukankan      html  css  js  c++  java
  • linux内核段属性机制【转】

    本文转载自:https://github.com/TongxinV/oneBook/issues/9

    linux内核段属性机制

    以subsys_initcall和module_init为例

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

    subsys_initcall
        __define_initcall("4",fn,4)
    

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

    blog008
    分析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执行就会去按照链接脚本设置好的顺序一个个遍历。

    经过分析,可以看出,subsys_initcall和module_init的作用是一样的,只不过前者所声明的函数要比后者在内核启动时的执行顺序更早

    另外:do_initcalls怎么被调用,简单看下调用过程

    start_kernel() -> rest_init() ->kernel_init() -> do_basic_setup() ->do_initcalls()

  • 相关阅读:
    地平线4快速选车-适用入门玩家
    网站大全【杂】
    排序算法-C语言
    一个仿tp5分页组件的实现
    thinkphp 二级域名绑定模块,导致设置的路由被多域名共用的问题解决方案
    php核心技术与最佳实践 --- 错误与异常
    php核心技术与最佳实践 --- 错误与异常
    php核心技术与最佳实践--- oop
    《CSS揭秘》》
    css 单位之px , em , rem
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/6944883.html
Copyright © 2011-2022 走看看