• 【linux】具体芯片MACHINE_START处理


    欢迎转载,转载时需保留作者信息,谢谢。

    邮箱:tangzhongp@163.com

    博客园地址:http://www.cnblogs.com/embedded-tzp

    Csdn博客地址:http://blog.csdn.net/xiayulewa

    MACHINE_START定义了一个具体机器。Linux已经定义好了调用接口,只需要实现MACHINE_START中的成员即可。

     

    Mach-mini2440.c (srcarcharmmach-s3c24xx)  中定义:

     

    MACHINE_START(MINI2440, "MINI2440")

        /* Maintainer: Michel Pollet <buserror@gmail.com> */

        .atag_offset    = 0x100,

        .map_io     = mini2440_map_io,

        .init_machine   = mini2440_init,

        .init_irq   = s3c2440_init_irq,

        .init_time  = samsung_timer_init,

        .restart    = s3c244x_restart,

    MACHINE_END

     

    #define MACHINE_START(_type,_name)         

    static const struct machine_desc __mach_desc_##_type   

     __used                        

     __attribute__((__section__(".arch.info.init"))) = {   

        .nr     = MACH_TYPE_##_type,       

        .name       = _name,

     

    #define MACHINE_END            

    };

    可见编译后放置在段.arch.info.init中。

     

    struct machine_desc成员的处理流程

     

    Ø  init_machine

    start_kernel→rest_init→kernel_init→kernel_init_freeable→do_basic_setup→do_initcalls

     

    static initcall_t *initcall_levels[] __initdata = {

        __initcall0_start,  /* srcarcharmkernelvmlinux.lds中定义__initcall0_start = .; *(.initcall0.init) *(.initcall0s.init) */

        __initcall1_start, /* srcarcharmkernelvmlinux.lds中定义*/

        __initcall2_start, /* 同上*/

        __initcall3_start, /* 同上*/

        __initcall4_start, /* 同上*/

        __initcall5_start, /* 同上*/

        __initcall6_start, /* 同上*/

        __initcall7_start, /* 同上*/

        __initcall_end, /* 同上*/

    };

     

    static void __init do_initcalls(void)

    {

        int level;

     

        for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)

            do_initcall_level(level);

    }

     

    因此do_initcalls函数会执行所有的srcarcharmkernelvmlinux.lds中定义__initcall0_start_initcall_end之间的段。

     

    Setup.c (srcarcharmkernel)中有:

     

    static int __init customize_machine(void)

    {

        /*

         * customizes platform devices, or adds new ones

         * On DT based machines, we fall back to populating the

         * machine from the device tree, if no callback is provided,

         * otherwise we would always need an init_machine callback.

         */

        if (machine_desc->init_machine)

            machine_desc->init_machine();

    #ifdef CONFIG_OF

        else

            of_platform_populate(NULL, of_default_bus_match_table,

                        NULL, NULL);

    #endif

        return 0;

    }

    arch_initcall(customize_machine);

     

    Init.h (srcincludelinux)中有:

    #define arch_initcall(fn)       __define_initcall(fn, 3)

     

    #define __define_initcall(fn, id)

        static initcall_t __initcall_##fn##id __used

    __attribute__((__section__(".initcall" #id ".init"))) = fn

     

    最后得到函数customize_machine被分配到了__initcall0_start_initcall_end之间的段.initcall3.init.

     

    总结:整个流程为: start_kernel→rest_init→kernel_init→kernel_init_freeable→do_basic_setup→do_initcalls

    customize_machinemachine_desc->init_machine()MACHINE_START宏定义的.init_machine   = mini2440_init

     

    Ø  map_io

    setup_arch→paging_init→devicemaps_init→ mdesc->map_io();MACHINE_START宏定义的.map_io     = mini2440_map_io

     

    Ø  init_irq

     

    start_kernel→init_IRQ→init_irqmachine_desc->init_irq()

    MACHINE_START宏定义的.init_irq   = s3c2440_init_irq

     

    Ø  init_time:

    start_kernel→time_init→machine_desc->init_time()

    MACHINE_START宏定义的.init_time  = samsung_timer_init

     

  • 相关阅读:
    shiro (java安全框架)
    day13
    自己修改select的样式(修改select右边的小三角)
    如何让2个并列的div根据内容自动保持同等高度
    js定时显示广告代码
    jquery 模块拖拽
    JS获取浏览器可视区域尺寸
    jQuery事件绑定的最佳实践
    flot图插件使用
    计算json的和
  • 原文地址:https://www.cnblogs.com/embedded-tzp/p/4450035.html
Copyright © 2020-2023  润新知