歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

MACHINE_START and MACHINE_END Macro define

在linux-2.6.38中,/arch/arm/mach-w90x900/mach-nuc950evb.c文件的最後部分,有如下宏定義:


MACHINE_START(W90P950EVB, "W90P950EVB")
 .phys_io = W90X900_PA_UART,
 .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, 
 .boot_params =  0x100,
 .map_io  = nuc950evb_map_io,
 .init_irq = nuc900_init_irq,
 .init_machine = nuc950evb_init,
 .timer  = &nuc900_timer,
MACHINE_END

 

而MACHINE_START和MACHINE_END宏定義在arch/arm/include/asm/mach/arch.h,如下:

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) 

Copyright © Linux教程網 All Rights Reserved