您的位置:首页 > 运维架构 > Linux

【linux】具体芯片MACHINE_START处理

2015-04-23 11:36 295 查看
欢迎转载,转载时需保留作者信息,谢谢。
邮箱:tangzhongp@163.com
博客园地址:http://www.cnblogs.com/embedded-tzp
Csdn博客地址:http://blog.csdn.net/xiayulewa
 
MACHINE_START定义了一个具体机器。Linux已经定义好了调用接口,只需要实现MACHINE_START中的成员即可。   Mach-mini2440.c (src\arch\arm\mach-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,  /* 在src\arch\arm\kernel\vmlinux.lds中定义__initcall0_start = .; *(.initcall0.init) *(.initcall0s.init) */     __initcall1_start, /* 在src\arch\arm\kernel\vmlinux.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函数会执行所有的在src\arch\arm\kernel\vmlinux.lds中定义的__initcall0_start与_initcall_end之间的段。   Setup.c (src\arch\arm\kernel)中有:   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 (src\include\linux)中有: #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_machine→machine_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_irq→machine_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;  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: