歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> MACHINE_START and MACHINE_END Macro define

MACHINE_START and MACHINE_END Macro define

日期:2017/3/1 10:30:59   编辑:Linux編程

在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