Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15498941
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2007-07-05 11:29:51

 

浅析setup_arch()函数tag_list的uboot[u-boot]由来

文章来源:http://gliethttp.cublog.cn

1.linux中
//------------------------------------------------------
arch/arm/kernel/setup.c->setup_arch()
void __init setup_arch(char **cmdline_p)
{
    struct tag *tags = (struct tag *)&init_tags;
    struct machine_desc *mdesc;
    char *from = default_command_line;
    ROOT_DEV = MKDEV(0, 255);
    setup_processor();
    mdesc = setup_machine(machine_arch_type);
    machine_name = mdesc->name;
    if (mdesc->soft_reboot)
        reboot_setup("s");
    if (mdesc->param_offset)
        tags = phys_to_virt(mdesc->param_offset);    //tags指向AT91_SDRAM_BASE + 0x100地址,该地址处的tag list由uboot生成
    /*
     * Do the machine-specific fixups before we parse the
     * parameters or tags.
     */

    if (mdesc->fixup)
        mdesc->fixup(mdesc, (struct param_struct *)tags,
             &from, &meminfo);
    /*
     * If we have the old style parameters, convert them to
     * a tag list.
     */

    if (tags->hdr.tag != ATAG_CORE)                  //2007-07-05 gliethttp 非tag list需要转换;不过uboot传递的是tag list
        convert_to_tag_list(tags);
    if (tags->hdr.tag == ATAG_CORE) {
        if (meminfo.nr_banks != 0)                  //具体的解析
            squash_mem_tags(tags);
        parse_tags(tags);
    }
    if (meminfo.nr_banks == 0) {
        meminfo.nr_banks = 1;
        meminfo.bank[0].start = PHYS_OFFSET;
        meminfo.bank[0].size = MEM_SIZE;
    }
    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(saved_command_line, from, COMMAND_LINE_SIZE);
    saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
    parse_cmdline(&meminfo, cmdline_p, from);
    bootmem_init(&meminfo);
    paging_init(&meminfo, mdesc);
    request_standard_resources(&meminfo, mdesc);
    /*
     * Set up various architecture-specific pointers
     */

    init_arch_irq = mdesc->init_irq;
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
    conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
    conswitchp = &dummy_con;
#endif
#endif
}
//------------------------------------------------------
arch/arm/vmlinux-armv.lds.in
__arch_info_begin = .;
    *(.arch.info)
__arch_info_end = .;
//------------------------------------------------------
include/asm-arm/mach/Arch.h
#define MACHINE_START(_type,_name)                   \
const struct machine_desc __mach_desc_##_type        \
 __attribute__((__section__(".arch.info"))) = {      \
    .nr        = MACH_TYPE_##_type,                  \
    .name        = _name,

#define MAINTAINER(n)

#define BOOT_MEM(_pram,_pio,_vio)                    \
    .phys_ram    = _pram,                            \
    .phys_io    = _pio,                              \
    .io_pg_offst    = ((_vio)>>18)&0xfffc,

#define BOOT_PARAMS(_params)                         \
    .param_offset    = _params,

#define VIDEO(_start,_end)                           \
    .video_start    = _start,                        \
    .video_end    = _end,

#define DISABLE_PARPORT(_n)                          \
    .reserve_lp##_n    = 1,

#define BROKEN_HLT /* unused */

#define SOFT_REBOOT                                  \
    .soft_reboot    = 1,

#define FIXUP(_func)                                 \
    .fixup        = _func,

#define MAPIO(_func)                                 \
    .map_io        = _func,

#define INITIRQ(_func)                               \
    .init_irq    = _func,

#define MACHINE_END                                  \
};
//------------------------------------------------------
arch/arm/mach-at91rm9200/Core.c
MACHINE_START(AT91RM9200, "ATMEL AT91RM9200")
    MAINTAINER("SAN People / ATMEL")
    BOOT_MEM(AT91_SDRAM_BASE, AT91C_BASE_SYS, AT91C_VA_BASE_SYS)
    BOOT_PARAMS(AT91_SDRAM_BASE + 0x100)
    FIXUP(at91rm9200_fixup)
    MAPIO(at91rm9200_map_io)
    INITIRQ(at91rm9200_init_irq)
MACHINE_END
//------------------------------------------------------
arch/arm/mach-at91rm9200/Core.c->at91rm9200_fixup()
将ramdisk设为根文件系统
static void __init at91rm9200_fixup(struct machine_desc *desc, struct param_struct *unused,
         char **cmdline, struct meminfo *mi)
{
#ifdef CONFIG_BLK_DEV_INITRD
    ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
    setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
//    setup_initrd(0xc0100000, 3*1024*1024);
#endif
}
2.uboot中
//------------------------------------------------------
u-boot的include/asm-arm/setup.h定义了struct tag结构体
u-boot的lib_arm/armlinux.c->do_bootm_linux()
->setup_start_tag()
->setup_serial_tag()
->setup_revision_tag()
->setup_memory_tags()
->setup_commandline_tag()
->setup_initrd_tag()
->setup_videolfb_tag()
->setup_end_tag()
//------------------------------------------------------
其中u-boot的setup_start_tag会将bd->bi_boot_params传给params
static void setup_start_tag (bd_t *bd)
{
    params = (struct tag *) bd->bi_boot_params;
    params->hdr.tag = ATAG_CORE;
    params->hdr.size = tag_size (tag_core);
    params->u.core.flags = 0;
    params->u.core.pagesize = 0;
    params->u.core.rootdev = 0;
    params = tag_next (params);
}
在board/at91rm9200dk/at91rm9200dk.c->board_init()函数中定义了bd->bi_boot_params的初始值gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;所以这就刚好和linux中arch/arm/mach-at91rm9200/Core.c的BOOT_PARAMS(AT91_SDRAM_BASE + 0x100)对应起来了。

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