Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1146412
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: LINUX

2016-12-01 10:39:25



 MACHINE_START(SMDK6410, "SMDK6410")
    /* Maintainer: Ben Dooks */
    .phys_io    = S3C_PA_UART & 0xfff00000,
    .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S3C64XX_PA_SDRAM + 0x100,

    .init_irq    = s3c6410_init_irq,
    .map_io        = smdk6410_map_io,
    .init_machine    = smdk6410_machine_init,
    .timer        = &s3c64xx_timer,
MACHINE_END

//////////////////////////////////////////////////////////////////////////////

#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                \
};
//////////
 MACHINE_START(SMDK6410, "SMDK6410")
#define MACHINE_START(_type,_name) 
_type == SMDK6410
_name == “SMDK6410“
//////////////////////////////////////////////////////////////////////////////

上面变形一下,展开宏就是如下:
static const struct machine_desc __mach_desc_SMDK6410  = { 
     .nr        = MACH_TYPE_SMDK6410,
     .name        = “SMDK6410“,

/* Maintainer: Ben Dooks */
    .phys_io    = S3C_PA_UART & 0xfff00000,
    .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S3C64XX_PA_SDRAM + 0x100,

    .init_irq    = s3c6410_init_irq,
    .map_io        = smdk6410_map_io,
    .init_machine    = smdk6410_machine_init,
    .timer        = &s3c64xx_timer,
};
/////////////
由__section__(".arch.info.init"))可知static const struct machine_desc __mach_desc_SMDK6410 这个
成员是放在arch/arm/kernel/vmlinux.lds链接脚本的
.arch.info.init段里的。
vmlinux.lds文本如下:
  __arch_info_begin = .;
   *(.arch.info.init)
  __arch_info_end = .;

/////////////////////////////////////////////////////////////////////////////

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);
};
               
///////////////////////////////////////////////////////////////////////////////
看看    .init_machine    = smdk6410_machine_init, 是如何被调用的?

/////////////

static void (*init_machine)(void) __initdata;

static int __init customize_machine(void)
{
    /* customizes platform devices, or adds new ones */
    if (init_machine)

                 //此处调用的就是  .init_machine    = smdk6410_machine_init, 
 
        init_machine();

return 0;
}
///////////////////////////////////////////


//类同于module_initcall(
customize_machine)
 
arch_initcall(customize_machine);


#define arch_initcall(fn)        __define_initcall("3",fn,3)
#define __define_initcall(level,fn,id) \
    static initcall_t __initcall_##fn##id __used \
    __attribute__((__section__(".initcall" level ".init"))) = fn

展开就是:

#define arch_initcall(  customize_machine )        __define_initcall("3",  customize_machine ,3)

__define_initcall(level,fn,id)
level = "3"       fn = 
 
customize_machine    id = 3

static initcall_t  __initcall_customize_machine3  = customize_machine;

__section__(".initcall" level ".init")   == __section__(".initcall""3"".init") == __section__(".initcall3.init")
 
 
 
__initcall_customize_machine3 是存放在 arch/arm/kernel/vmlinux.lds链接脚本的.initcall3.init段里的

///////////////////////////////////////////////////////////////////////////////

void __init setup_arch(char **cmdline_p)
{
    struct tag *tags = (struct tag *)&init_tags;
    struct machine_desc *mdesc;
    char *from = default_command_line;

    setup_processor();
    mdesc = setup_machine(machine_arch_type);
    machine_name = mdesc->name;

    if (mdesc->soft_reboot)
        reboot_setup("s");

    if (__atags_pointer)
        tags = phys_to_virt(__atags_pointer);
    else if (mdesc->boot_params)
        tags = phys_to_virt(mdesc->boot_params);

    /*
     * If we have the old style parameters, convert them to
     * a tag list.
     */
    if (tags->hdr.tag != ATAG_CORE)
        convert_to_tag_list(tags);
    if (tags->hdr.tag != ATAG_CORE)
        tags = (struct tag *)&init_tags;

    if (mdesc->fixup)
        mdesc->fixup(mdesc, tags, &from, &meminfo);

    if (tags->hdr.tag == ATAG_CORE) {
        if (meminfo.nr_banks != 0)
            squash_mem_tags(tags);
        save_atags(tags);
        parse_tags(tags);
    }

    init_mm.start_code = (unsigned long) &_text;
    init_mm.end_code   = (unsigned long) &_etext;
    init_mm.end_data   = (unsigned long) &_edata;
    init_mm.brk       = (unsigned long) &_end;

    memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
    boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
    parse_cmdline(cmdline_p, from);
    paging_init(&meminfo, mdesc);
    request_standard_resources(&meminfo, mdesc);

#ifdef CONFIG_SMP
    smp_init_cpus();
#endif

    cpu_init();

    /*
     * Set up various architecture-specific pointers
     */
    init_arch_irq = mdesc->init_irq;
    system_timer = mdesc->timer;
//函数指针
init_machine变量在这里赋值。
    init_machine = mdesc->init_machine;

#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
    conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
    conswitchp = &dummy_con;
#endif
#endif
    early_trap_init();
}
 

阅读(2087) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~