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

Linux中的MACH定义之MACHINE_START / MACHINE_END

2013-10-30 14:11 435 查看
原文地址:Linux中的MACH定义之MACHINE_START
/ MACHINE_END 作者:kangjunping

(写在转载之前)
    在linux中machine对应一个设备,对于开发者而言对应一个新的项目,项目开展的初始需要对应定义一个MACH,在arch/arm/mach-xxx/目录下,此文件中定义了GPIO的使用,外设,i2c总线等系统信息,所以在参加一个项目的开始,应该认真的分析machine定义文件,了解项目的情况。
    在arch/arm/下定义了很多mach-xxx的文件夹,一般是按照厂商或者平台命名,例如高通平台的为mach-msm,marvell的为mach-mmp,mach-pxa。
 
本文讲解LINUX中用MACHINE_START/MACHINE_END定义的MACH,并给出定义的各个成员函数在初始化过程中被调用的时机。

 

1.      定义一个MACH

 

LINUX中MACHINE定义是用MACHINE_START()/MACHINE_END两个宏来实现的,比如MSM的实现(arch/arm/mach-msm/board-halibut.c):
 
1.MACHINE_START(HALIBUT,"Halibut Board (QCT SURF7200A)")  

 2.         .boot_params      = 0x10000100,  

 3.         .map_io           = halibut_map_io,  

 4.         .init_irq         = halibut_init_irq,  

 5.         .init_machine     = halibut_init,  

 6.         .timer            = &msm_timer,  

 7.MACHINE_END  

 

2. MACHINE_START / MACHINE_END定义

 

上面的定义中,用到了这两个宏MACHINE_START/MACHINE_END,下面是它们具体的定义(在arch/arm/include/asm/mach/arch.h中): 

 

1.#defineMACHINE_START(_type,_name)                        \   

 2.static const structmachine_desc __mach_desc_##_type      \  

 3. __used                                                  \  

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

 5.         .nr             = MACH_TYPE_##_type,            \  

 6.         .name           = _name,  

 7.   

 8.#define MACHINE_END                                      \   

 9.};  

 

struct machine_desc也是定义在arch/arm/include/asm/mach/arch.h

 

1.struct machine_desc {  

 2.         /* 

 3.          * Note! The firstfour elements are used 

 4.          * by assembler codein head.S, head-common.S 

 5.          */  

 6.         unsigned int            nr;                  /* architecture number  */  

 7.         unsigned int            phys_io;             /* start of physical io */  

 8.         unsigned int            io_pg_offst;         /* byte offset for io 

 9.                                                       * page tabe entry      */  

 10.   

 11.         const char              *name;               /* architecture name    */  

 12.         unsigned long           boot_params;         /* tagged list          */  

 13.   

 14.         unsigned int            video_start;         /* start of video RAM   */  

 15.         unsigned int            video_end;           /* end of video RAM     */  

 16.   

 17.         unsigned int            reserve_lp0:1;       /* never has lp0     */  

 18.         unsigned int            reserve_lp1:1;       /* never has lp1     */  

 19.         unsigned int            reserve_lp2:1;       /* never has lp2     */  

 20.         unsigned int            soft_reboot:1;       /* soft reboot       */  

 21.         void                    (*fixup)(struct machine_desc *,  

 22.                                          struct tag *, char **,  

 23.                                          struct meminfo *);  

 24.         void                    (*map_io)(void);     /* IO mapping function  */  

 25.         void                    (*init_irq)(void);  

 26.         struct sys_timer        *timer;              /* system tick timer    */  

 27.         void                    (*init_machine)(void);  

 28.};  

 

3.      MACH HALIBUT的定义

 

把1中定义的MACH展开之后,得到:

 

1.struct machine_desc __mach_desc_HALIBUT{  

 2.__used                                                            

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

 4.         .nr               = MACH_TYPE_HALIBUT,                

 5.         .name             = "HalibutBoard (QCT SURF7200A)",  

 6.         .boot_params      = 0x10000100,  

 7.         .map_io           = halibut_map_io,  

 8.         .init_irq         = halibut_init_irq,  

 9.         .init_machine     = halibut_init,  

 10.         .timer            = &msm_timer,  

 11.};  

 

总结一下:MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。
 

4.  成员函数被调用的时机

 

在setup_arch() [setup.c#758~760]中init_irq, timer & init_machine分别被赋值给下列变量:

 

         init_arch_irq = mdesc->init_irq; 
 
         system_timer = mdesc->timer;

 

         init_machine = mdesc->init_machine;

 

而这三个函数指针是在下列场景中被调用的:

 

1)     start_kernel()[main.c#589]-> init_IRQ() [irq.c] ->init_arch_irq();

 

2)     start_kernel()[main.c#595]->time_init () [time.c] ->system_time->init();

 

3)     customize_machine()[setup.c#692] -> init_machine();

 

customize_machine是被放在arch_initcall段的,按照顺序被调用。xxx_initcall段内的函数是按下列顺序被调用的:start_kernel() [main.c#682] -> rest_init() [启动内核线程]-> kernel_init() –> do_basic_setup()-> do_initcalls();

 

map_io是在下列顺序中被调用

 

4)     start_kernel()[main.c#546]-> setup_arch () [setup.c#745] -> paging_init() [mmu.c#1028] -> devicemaps_init()[mmu.c#993] -> map_io()

 

从它们在start_kernel()中被调用的顺序,可知它们执行的先后为:map_io; init_irq; timer->time_init; init_machine。
本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-09/43351p2.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息