同一份 kernel image,在不同的 board 上,竟然就會 run 不同的 board init code..
kernel code 是用 machine_arch_type 這個變數 作為 system 的id。
在 include/generated/machine-types.h 有machine id 的定義:
(ref: http://r40eubuntu.blogspot.tw/2013/08/machineisxxx.html)
....
#define MACH_TYPE_AQUARIUS 3009
#define MACH_TYPE_MX53_ARD 3010
#define MACH_TYPE_MX53_SMD 3011
#define MACH_TYPE_LSWXL 3012
#define MACH_TYPE_DOVE_AVNG_V3 3013
#define MACH_TYPE_SDI_ESS_9263 3014
....
#define MACH_TYPE_MX53_LOCO 3273
這個file 後面還有..配合的 function 宣告..
#ifdef CONFIG_MACH_MX53_LOCO
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# else
# define machine_arch_type MACH_TYPE_MX53_LOCO
# endif
# define machine_is_mx53_loco() (machine_arch_type == MACH_TYPE_MX53_LOCO)
#else
# define machine_is_mx53_loco() (0)
#endif
這樣kernel code 就可以用 machi_is_mx53_loco( ) 來決定要不要 run 某段 code..
__machine_arch_type 是在 arch/arm/boot/compressed/misc.c 指定 (填值) 的。
unsigned long
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p,
int arch_id)
{
unsigned char *tmp;
output_data = (unsigned char *)output_start;
free_mem_ptr = free_mem_ptr_p;
free_mem_end_ptr = free_mem_ptr_end_p;
__machine_arch_type = arch_id;
arch_decomp_setup();
tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
output_ptr = get_unaligned_le32(tmp);
putstr("Uncompressing Linux...");
do_decompress(input_data, input_data_end - input_data,
output_data, error);
putstr(" done, booting the kernel.\n");
return output_ptr;
}
這個 decompress_kernel 是由 kernel boot assembly code 呼叫的..
arch/arm/boot/compressed/head.S
b 1f
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
1: mov r7, r1 @ save architecture ID
.....
.....
mov r5, r2 @ decompress after malloc space
mov r0, r5
mov r3, r7
bl decompress_kernel
所以知道 machine_id 其實是 bootloader 給的..
u-boot:
結果裡面也有一份 machine-type.h
在 ./board/freescale/mx53_loco/mx53_loco.c
int board_init(void)
{
setup_boot_device();
setup_soc_rev();
gd->bd->bi_arch_number = MACH_TYPE_MX53_LOCO; /* board id for linux */
..
指定給 bi_arch_number, 然後在 bootm command 時..(bootm.c):
int machid = bd->bi_arch_number;
...
...
theKernel (0, machid, bd->bi_boot_params);
剛好是第二個 argument.對應 r1
沒有留言:
張貼留言