LINUX中的MACH定义之MACHINE_START / MACHINE_END

 

田海立@CSDN

2011/08/18

 

本文讲解LINUX中用MACHINE_START/MACHINE_END定义的MACH,并给出定义的各个成员函数在初始化过程中被调用的时机。

 

1.      定义一个MACH

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

MACHINE_START(HALIBUT,"Halibut Board (QCT SURF7200A)")
         .boot_params      = 0x10000100,
         .map_io           = halibut_map_io,
         .init_irq         = halibut_init_irq,
         .init_machine     = halibut_init,
         .timer            = &msm_timer,
MACHINE_END

 

2.      MACHINE_START / MACHINE_END定义

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

#defineMACHINE_START(_type,_name)                        \
static const structmachine_desc __mach_desc_##_type      \
 __used                                                  \
 __attribute__((__section__(".arch.info.init")))= {      \
         .nr             = MACH_TYPE_##_type,            \
         .name           = _name,
 
#define MACHINE_END                                      \
};

 

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

struct machine_desc {
         /*
          * Note! The firstfour elements are used
          * by assembler codein head.S, head-common.S
          */
         unsigned int            nr;                  /* architecture number  */
         unsigned int            phys_io;             /* start of physical io */
         unsigned int            io_pg_offst;         /* byte offset for io
                                                       * page tabe entry      */
 
         const char              *name;               /* architecture name    */
         unsigned long           boot_params;         /* tagged list          */
 
         unsigned int            video_start;         /* start of video RAM   */
         unsigned int            video_end;           /* end of video RAM     */
 
         unsigned int            reserve_lp0:1;       /* never has lp0     */
         unsigned int            reserve_lp1:1;       /* never has lp1     */
         unsigned int            reserve_lp2:1;       /* never has lp2     */
         unsigned int            soft_reboot:1;       /* soft reboot       */
         void                    (*fixup)(struct machine_desc *,
                                          struct tag *, char **,
                                          struct meminfo *);
         void                    (*map_io)(void);     /* IO mapping function  */
         void                    (*init_irq)(void);
         struct sys_timer        *timer;              /* system tick timer    */
         void                    (*init_machine)(void);
};

 

3.      MACH HALIBUT的定义

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

struct machine_desc __mach_desc_HALIBUT{
__used                                                          
__attribute__((__section__(".arch.info.init")))= {
         .nr               = MACH_TYPE_HALIBUT,              
         .name             = "HalibutBoard (QCT SURF7200A)",
         .boot_params      = 0x10000100,
         .map_io           = halibut_map_io,
         .init_irq         = halibut_init_irq,
         .init_machine     = halibut_init,
         .timer            = &msm_timer,
};


总结一下: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。

 

*** 欢迎转载,并请注明原文来自http://blog.csdn.net/thl789/article/details/6699259 ***

 

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐