LINUX中的MACH定义之MACHINE_START / MACHINE_END
2012-09-25 10:37
519 查看
本文讲解LINUX中用MACHINE_START/MACHINE_END定义的MACH,并给出定义的各个成员函数在初始化过程中被调用的时机。
1. 定义一个MACH
LINUX中MACHINE定义是用MACHINE_START()/MACHINE_END两个宏来实现的,比如MSM的实现(arch/arm/mach-msm/board-halibut.c):
[cpp]
view plaincopyprint?
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中):
[cpp]
view plaincopyprint?
#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
[cpp]
view plaincopyprint?
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展开之后,得到:
[cpp]
view plaincopyprint?
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。
1. 定义一个MACH
LINUX中MACHINE定义是用MACHINE_START()/MACHINE_END两个宏来实现的,比如MSM的实现(arch/arm/mach-msm/board-halibut.c):
[cpp]
view plaincopyprint?
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
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中):
[cpp]
view plaincopyprint?
#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 \
};
#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
[cpp]
view plaincopyprint?
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);
};
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展开之后,得到:
[cpp]
view plaincopyprint?
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,
};
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。
相关文章推荐
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- Linux中的MACH定义之MACHINE_START / MACHINE_END
- Linux中的MACH定义之MACHINE_START / MACHINE_END
- LINUX中的MACH定义之MACHINE_START / MACHINE_END
- linux中MACHINE_START&END在9g10ek上实现
- linux之MACHINE_START和 MACHINE_END
- linux的MACHINE_START-MACHINE_END(转)
- MACHINE_START and MACHINE_END Macro define
- MACHINE_START-内核板级初始化实现机制(linux3.1.0)
- linux mips架构PHYS_OFFSET、CAC_BASE、HIGHMEM_START、PAGE_OFFSET、virt_to_phys、phys_to_virt、page_to_phys的定义
- linux 可变参数va_start va_arg va_end
- 【linux】具体芯片MACHINE_START处理
- MACHINE_START与MACHINE_END
- C语言中可变参数的用法——va_list、va_start、va_arg、va_end参数定义
- linux下strftime(),va_start(),va_end()函数的用法
- MACHINE_START与MACHINE_END
- MACHINE_START与MACHINE_END
- Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group
- MACHINE_START与MACHINE_END