linux中MACHINE_START&END在9g10ek上实现

在linux的板卡初始化文件中有machine的相关定义

//arch/arm/mach-at91/board-sam9261ek.c

MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")

    /* Maintainer: Atmel */

    .phys_io    = AT91_BASE_SYS,

    .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,

    .boot_params    = AT91_SDRAM_BASE + 0x100,

    .timer      = &at91sam926x_timer,

    .map_io     = ek_map_io,

    .init_irq   = ek_init_irq,

    .init_machine   = ek_board_init,

MACHINE_END

其中MACHINE_START和MACHINE_END为宏定义,定义于文件

//arch/arm/include/asm/arch.h

#ifndef __ASSEMBLY__

 

struct tag;

struct meminfo;

struct sys_timer;

 

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

 

MACH_TYPE_ AT91SAM9G10EK是9G10ek开发板在linux中的机器号。

“Atmel AT91SAM9G10-EK”是开发板信息,在终端输入cat /proc/cpuinfo可以查看。

在内核文件中arch/arm/tools/mach-types定义目前内核支持的板卡、芯片等:

##machine_is_xxx  CONFIG_xxxx  MACH_TYPE_xxx  number

at91sam9g10ek   MACH_AT91sam9G10EK  AT91SAM9G10EK  2159

 

MACHINE_START主要定义了“struct machine_desc”的类型,放在section(“.arch.info.init”),是初始化数据,kernel起来之后将被丢弃。

 

其余各个成员函数在setup_arch()中被赋值到内核结构体,在不同时期被调用:

1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用。
arch_initcall(customize_machine);

customize_machine()[setup.c#692] -> init_machine();

2. .init_irq在start_kernel()(文件init/main.c)--> init_IRQ() (在文件arch/arm/kernel/Irq.c)--> init_arch_irq()中被调用

3. .map_io 在 start_kernel()(文件init/main.c)-->setup_arch(&command_line) (在文件arch/arm/kernel/setup.c)--> paging_init()(在文件arch/arm/kernel/mm/Mmu.c) --> devicemaps_init()(在文件arch/arm/kernel/mm/Mmu.c)中被调用

4. .timer是定义系统时钟,定义TIMER4为系统时钟,在arch/arm/plat-s3c/time.c中体现。在start_kernel() --> time_init()(在文件arch/arm/kernel/Time.c)-->system_time->init()中调用。

5. .boot_params是bootloader向内核传递的参数的位置,这要和bootloader中参数的定义要一致。

 

从它们在start_kernel()中被调用的顺序,可知它们执行的先后为:map_io; init_irq; timer->time_init; init_machine。

 

参考:

1. http://blog.sina.com.cn/s/blog_753fd0b00100t8js.html 

2. http://blog.csdn.net/thl789/article/details/6699259

 

posted @ 2016-08-22 16:59  yuxi_o  阅读(267)  评论(0编辑  收藏  举报