浅析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)对应起来了。
|