Machine_start/machine_end defined by Mach in Linux
Tian haili @ csdn
2011/08/18
This article describes the Mach defined by machine_start/machine_end in Linux, and provides the time for each defined member function to be called during initialization.
1. Define a Mach
In Linux, machine is defined by using two macros, machine_start ()/machine_end, such as implementation of 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 Definition
The two macros machine_start/machine_end are used in the above definition. The specific definitions are as follows (in 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_descIt is also defined in 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. Definition of Mach halibut
Expand the Mach defined in 1 and get the following result:
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,};
To sum up, machine_start mainly defines the type of "struct machine_desc", which is placed in section (".arch.info. init"). It is the initialization data and will be discarded after the kernel is up.
4. When a member function is called
In setup_arch () [setup. C #758 ~ In 760], init_irq, Timer & init_machine are assigned to the following variables:
Init_arch_irq = mdesc->Init_irq;
System_timer = mdesc->Timer;
Init_machine = mdesc->Init_machine;
These three function pointers are called in the following scenarios:
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 is put in the arch_initcall segment and called in order. Functions in the xxx_initcall segment are called in the following order: start_kernel ()[Main. C #682.]-> Rest_init () [start the kernel thread]-> kernel_init ()-> do_basic_setup ()-> do_initcils ();
Map_ioIs called in the following order
4) start_kernel ()[Main. C #546.]-> Setup_arch () [setup. C #745]-> paging_init () [MMU. C #1028]-> devicemaps_init () [MMU. C #993]-> map_io ()
From the sequence in start_kernel (), we can see that they are executed successively as map_io; init_irq; timer-> time_init; init_machine.
*** Welcome to reprint, and please indicate the original from http://blog.csdn.net/thl789/article/details/6699259 ***