浅析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)对应起来了。
阅读(568) | 评论(0) | 转发(0) |