在arm-linux中的/arch/arm目录下,有许多与具体处理器相关的目录,里面有与具体板子相关的文件,这个文件大部分内容是对平台设备的结构体初始化(例如串口,LCD,Nand falsh等),这里以 arm-s5pv210为例说明,对应的板级文件是mach-x210.c,在这个文件中宏定义 MACHINE_START专门用来初始化基础硬件设备。定义如下:
MACHINE_START(SMDKV210, "SMDKV210")
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init,
.timer = &s5p_systimer,
MACHINE_END
MACHINE_START的定义在arch/arm/include/asm/mach/arch.h
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
展开这个宏定义后
static const struct machine_desc __mach_desc_SMDKV210
__used
__attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_SMDKV210,
.name = "SMDKV210",
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init,
.timer = &s5p_systimer,
};
这里定义了一个 machine_desc 类型结构体变量,这个类型的变量放在内核代码段.arch.info.init中,在内核启动时,被函数 lookup_machine_type 取出函数指针(此函数用汇编实现,在汇编文件中)。
ENTRY(lookup_machine_type)
stmfd sp!, {r4 - r6, lr}
mov r1, r0
bl __lookup_machine_type
mov r0, r5
ldmfd sp!, {r4 - r6, pc}
然后在 setup_arch 中执行machine_desc 中的成员函数, 程序流程为:
start_kernel(void)
--> setup_arch(&command_line);
--> setup_machine(machine_arch_type); //machine_arch_type?
--> lookup_machine_type()
通过 lookup_machine_type() 函数取出函数指针后,在 setup_arch 函数中给函数指针赋值,如下:
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
然后在 setup.c 文件中发现下面的函数 和宏定义:
static void (*init_machine)(void) __initdata;
static int __init customize_machine(void)
{
/* customizes platform devices, or adds new ones */
if (init_machine)
init_machine();
return 0;
}
arch_initcall(customize_machine);
#define arch_initcall(fn) __define_initcall("3",fn,3)
成员函数 init_machine 但是它没有被显式调用,而是放在了 arch_initcall 这个宏定义中,系统启动时会扫描这个段去调用执行它。
1、MACH_TYPE_SMDKV210
MACH_TYPE_SMDKV210 它是uboot传递过来的,动态保存在generated/mach-types.h中,在 arch \ arm \ include \ asm \ mach-type.h 中包含了
SMDKV210 宏在 / arch / arm / tools / mach-types 文件里定义,所以MACH_TYPE_SMDKV210 的值是 2456。
2、.init_machine
.init_machine这个成员是一个函数指针,值为 smdkc110_machine_init,这个函数也在 mach-x210.c 中定义。
http://blog.csdn.net/charliewangg12/article/details/41483261