meminfo初始化
1. u-boot中设置启动参数
1)启动命令
u-boot-env.txt
bootcmd
if ${recovery}; then
run nandrecovery;
else
if mmc init; then
if run loadbootscript; then
run bootscript;
else
if run loaduImage; then
run mmcboot;
else
run nandboot;
fi;
fi;
else
run nandboot;
fi;
fi
nandboot
echo Booting from nand ...;
run nandargs;
nand read ${loadaddr} boot;
booti 0x82000008
nandargs
setenv bootargs console=${console} init=${init} mem=${mem} ip=${ip} mpurate=${mpurate} omap_vout.vid1_static_vrfb_alloc=y vram=${vram} omapfb.vram=0:8M androidboot.console=${tty} root=${root_nand} rootfstype=${rootfstype_nand} ubi.mtd=${ubi_mtd}
这一部分属于commandline,会在setup_commandline_tag中插入params数组,并标上ATAG_CMDLINE,会在parse_args的时候,用对应的处理函数来处理,具体如下
2)环境变量
include/configs/d7800.h
#define CONFIG_EXTRA_ENV_SETTINGS \
"init=/init\0" \
"mem=256M\0" \
"mpurate=800\0" \
……2.kernel中用parse_args解析此bootarg,具体可参考另一份笔记Linux启动参数“init=xxx”分析parse_args -> parse_one -> unknown_bootoption -> obsolete_checksetup -> obs_kernel_param.setup_func = early_mem3.kernel中设置对应bootarg的处理函数early_param("mem", early_mem); -> __setup_param(str, fn, fn, 1) ->#define __setup_param(str, unique_id, fn, early) \static const char __setup_str_##unique_id[] __initconst \
__aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
__used __section(.init.setup) \
__attribute__((aligned((sizeof(long))))) \= { __setup_str_##unique_id, fn, early }4.early_mem函数static int __init early_mem(char *p){
static int usermem __initdata = 0;
unsigned long size, start;
char *endp;
/*
* If the user specifies memory size, we
* blow away any automatically generated
* size.
*/
if (usermem == 0) {
usermem = 1;
meminfo.nr_banks = 0;
}/** defined in arch/arm/plat-omap/include/plat/memory.hstart = PHYS_OFFSET;
* PHYS_OFFSET = UL(0x80000000)
*/
size = memparse(p, &endp);
if (*endp == '@')
start = memparse(endp + 1, NULL);
arm_add_memory(start, size);
return 0;
}最后遗留一个问题,假如有几块内存需要处理怎么办?没关系,Linux提供了对应的机制。就是__tagtable(ATAG_MEM, parse_tag_mem32);这是一张表格,代表了一组ATAG_MEM param,用parse_tag_mem32来处理。这一组param同样也是在u-boot阶段就加入了。即:do_bootm_linux -> setup_memory_tags (u-boot)只不过在D7800中CONFIG_NR_DRAM_BANKS=1(configs/d7800.h)。static void setup_memory_tags (bd_t *bd){int i;for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {params->hdr.tag = ATAG_MEM;params->hdr.size = tag_size (tag_mem32);params->u.mem.start = bd->bi_dram[i].start;params->u.mem.size = bd->bi_dram[i].size;params = tag_next (params);}}meminfo中的内存地址全部是真正的物理地址。