(注:本文参考资料:朱有鹏嵌入式课程。本文为个人学习记录,如有错误,欢迎指正。)
1. uboot机器码
在uboot启动的start_armboot阶段,调用board_init函数初始化机器码。
int board_init(void) { .............................. gd->bd->bi_arch_number = MACH_TYPE_SMDKV210; gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; return 0; }
在uboot启动内核时,将机器码传参至内核。
uboot源码中,也有一个/uboot/arch/arm/include/mach-types.h文件,该文件维护至该版本的uboot所支持的所有机器码。
//利用寄存器向内核传参r0 = 0, r1 = machid, r2 = bi_boot_params theKernel (0, machid, bd->bi_boot_params);
2. Linux机器码
在内核源码根目录的/arch/arm目录下,每一个“mach-xxx”文件夹代表内核支持的CPU型号;在该文件夹下有多个“mach-xxx.c”文件,每个文件代表内核支持的开发板型号。在每个“mach-xxx.c”文件的末尾,都利用MACHINE_START宏定义一个机器描述符结构体,其中包含了该开发板的相关信息。
以/kernel/arch/arm/mach-s5pv210/mach-smdkv210.c文件为例,相关代码如下:
MACHINE_START(SMDKV210, "SMDKV210") /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ .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= smdkv210_map_io, .init_machine= smdkv210_machine_init, #ifdef CONFIG_S5P_HIGH_RES_TIMERS .timer= &s5p_systimer, #else .timer= &s3c24xx_timer, #endif 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= smdkv210_map_io, .init_machine= smdkv210_machine_init, .timer= &s5p_systimer, };
- 结构体中成员“.nr = MACH_TYPE_SMDKV210”,表示该开发板的机器码。
- 机器码值“MACH_TYPE_SMDKV210”在/kernel/include/generated/mach-types.h文件中定义,该文件在内核配置过程中自动生成。mach-types.h文件维护着该版本内核所支持的全部机器码。
- 结构体成员“.name= "SMDKV210"”,表示该开发板的名称。
- 结构体成员“.init_machine = smdkv210_machine_init”,定义了一个函数smdkv210_machine_init,该函数是一个硬件初始化函数,包含了内核中各种硬件的初始化信息。
3. uboot与Linux内核机器码的联系
在Linux内核初始化前期,会比对uboot的机器码和内核的机器码是否匹配,若不匹配,则停止启动内核。
ENTRY(stext) setmodePSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode @ and irqs disabled mrcp15, 0, r9, c0, c0 @ get processor id bl__lookup_processor_type @ r5=procinfo r9=cpuid movsr10, r5 @ invalid processor (r5=0)? beq__error_p @ yes, error 'p' bl__lookup_machine_type @ r5=machinfo 检查机器码是否匹配 movsr8, r5 @ invalid machine (r5=0)? beq__error_a @ yes, error 'a' bl__vet_atags bl__create_page_tables