一. 内核中对于每种支持的开发板都会使用宏MACHINE_START、MACHINE_END来定义一个machine_desc结构,它定义开发板相关的一些属性及函数,比如机器类型ID、起始I/O物理地址、Bootloader传入的参数的地址、中断初始化函数、I/O映射函数等, //可以看出在\arch\arm\mach-at91(mach-xx) —mach中封装好硬件对象
MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91sam926x_timer,
.map_io = ek_map_io,
.init_irq = ek_init_irq,
.init_machine = ek_board_init,
MACHINE_END
//\arch\arm\include\asm\mach
#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 \
};
truct machine_desc {
unsigned int nr;
unsigned int phys_io;
unsigned int io_pg_offst;
const char *name;
unsigned long boot_params;
unsigned int video_start;
unsigned int video_end;
unsigned int reserve_lp0 :1;
unsigned int reserve_lp1 :1;
unsigned int reserve_lp2 :1;
unsigned int soft_reboot :1;
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void);
void (*init_irq)(void);
struct sys_timer *timer;
void (*init_machine)(void);
};
============================================
二:在内核启加载硬件程序 在main.c中 | start_kernel(void) | setup_arch(&command_line);//加载硬件 | mdesc = setup_machine(machine_arch_type); | list = lookup_machine_type(nr);//根据machine_arch_type从mach list中查找,
问题:lookup_machine_type如何通过machine_arch_type找到在make menuconfig 是配置的硬件??? 解决: 查看连接脚本arch/arm/kernel/vmlinux.lds.S 所有machine_desc结构体都处于“.arch.info.init”段中,在连接内核时,它们被组织在一起,开始地址为__arch_info_begin,结束地址为__arch_info_end,从”中可以看出:
38 __arch_info_begin = .;
39 *(.arch.info.init)
40 __arch_info_end = .;
- 不同的machine_desc结构用于不同的开发板,U-BOOT调用内核时,会在r1寄存器中给出开发板的标记(机器类型ID);对于S3C2410、S3C2440开发板,U-Boot传入的机器类型ID为MACH_TYPE_SMDK2410、MACH_TYPE_S3C2440,它们对应的machine_desc结构分别在arch/arm/mach-s3c2410/mach-smdk2410.c和
arch/arm/mach-s3c2440/mach-smdk2440.c中定义
190 3: .long .
191 .long __arch_info_begin
192 .long __arch_info_end
.........................
205 __lookup_machine_type:
206 adr r3, 3b
207 ldmia r3, {r4, r5, r6}
r4 = 190行的虚拟地址
r5 = __arch_info_begin (VA)
r6 = __arch_info_end (VA)
208 sub r3, r3, r4
209 add r5, r5, r3
210 add r6, r6, r3
211 1: ldr r3, [r5, #MACHINFO_TYPE]
r3 = r5 + MACHINFO_TYPE=machine_desc结构中定义的nr成员,即机器类型ID
212 teq r3, r1
213 beq 2f
214 add r5, r5, #SIZEOF_MACHINE_DESC
215 cmp r5, r6
216 blo 1b
217 mov r5, #0
218 2: mov pc, lr
上面代码功能说明:
__lookup_machine_type函数将这个r1寄存器中的机器类型ID与machine_desc结构中的nr成员比较,如果相等则表示找到了匹配的machine_desc结构,于是返回它的地址(存于r5中),如果__arch_machine_begin和__arch_machine_end间所有machine_desc结构的nr成员都不等于r1寄存器中的值,则返回0(r5等于0)
在配置菜单时,选中两个开发板即可:
System Type--->
S3C2410 Machines--->
[*] SMDK2410/A9M2410
S3C2440 Machines--->
[*] SMDK2440
参考:http://blog.sina.com.cn/s/blog_63ac1cef0100vco1.html
|