struct machine_desc { /* * Note! The first four elements are used * by assembler code in head.S, head-common.S */ unsigned int nr; /* architecture number */ unsigned int phys_io; /* start of physical io */ unsigned int io_pg_offst; /* byte offset for io * page tabe entry */ const char *name; /* architecture name */ unsigned long boot_params; /* tagged list */ unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* end of video RAM */ unsigned int reserve_lp0 :1; /* never has lp0 */ unsigned int reserve_lp1 :1; /* never has lp1 */ unsigned int reserve_lp2 :1; /* never has lp2 */ unsigned int soft_reboot :1; /* soft reboot */ void (*fixup)(struct machine_desc *, struct tag *, char **, struct meminfo *); void (*map_io)(void);/* IO mapping function */ void (*init_irq)(void); struct sys_timer *timer; /* system tick timer */ void (*init_machine)(void); };/* * Set of macros to define architecture features. This is built into * a table by the linker. */ #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 };#endif 将前面定义的MACHINE_START和MACHINE_END展开后得到: static const struct machine_desc __mach_desc_W90P950EVB __used __attribute__((__section__(".arch.info.init"))) = { .nr = MACH_TYPE_W90P950EVB, /* architecture number */ .name = "W90P950EVB"", /* architecture name */ .phys_io = W90X900_PA_UART, /* start of physical io */ .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, .boot_params = 0x100, /* tagged list */ .map_io = nuc950evb_map_io, /* IO mapping function */ .init_irq = nuc900_init_irq, .init_machine = nuc950evb_init, .timer = &nuc900_timer, }MACH_TYPE_W90P950EVB定义在arch/arm/include/asm/mach-types.h内,值为1860 十六进制为:0x744. #define MACH_TYPE_W90P950EVB 1860这个值是机器的类型值,编译时由arch/arm/tool/mach- types里面定义的数据生成的。 /* arch/arm/tool/mach-types */ w90x900 MACH_W90X900 W90X900 1860而在arch/arm/kernel/head-common.S文件中的__lookup_machine_type函数中有如下的定义:/* * linux/arch/arm/kernel/head-common.S * * Copyright (C) 1994-2002 Russell King * Copyright (c) 2003 ARM Limited * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */#define ATAG_CORE 0x54410001 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) .align 2 .type __switch_data, %object __switch_data: ...................中间省略 .long processor_id @ r4 .long __machine_arch_type @ r5 .long __atags_pointer @ r6 .long cr_alignment @ r7 .long init_thread_union + THREAD_START_SP @ sp ...................中间省略/* * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for * more information about the __proc_info and __arch_info structures. */ .align 2 3: .long __proc_info_begin .long __proc_info_end 4: .long . .long __arch_info_begin .long __arch_info_end/* * Lookup machine architecture in the linker-build list of architectures. * Note that we can"t use the absolute addresses for the __arch_info * lists since we aren"t running with the MMU on (and therefore, we are * not in the correct address space). We have to calculate the offset. * * r1 = machine architecture number * Returns: * r3, r4, r6 corrupted * r5 = mach_info pointer in physical address space */ __lookup_machine_type: #ifdef CONFIG_ARCH_W90X900 //这个就是前面的1860,十六进制为:0x744 mov r1, #0x700 add r1, r1, #0x40 add r1, r1, #0x04 #endif adr r3, 4b ldmia r3, {r4, r5, r6} sub r3, r3, r4 @ get offset between virt&phys add r5, r5, r3 @ convert virt addresses to add r6, r6, r3 @ physical address space 1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type teq r3, r1 @ matches loader number? beq 2f @ found add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc cmp r5, r6 blo 1b mov r5, #0 @ unknown machine 2: mov pc, lr ENDPROC(__lookup_machine_type)