Linux中的MACH定义之MACHINE_START / MACHINE_END


http://hi.baidu.com/ch_ff/blog/item/26af5f7b7f9a20f02f73b361.html


本文讲解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。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值