(注:本文參考資料:朱有鵬嵌入式課程。本文為個人學習記錄,如有錯誤,歡迎指正。)
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