这里分配出了问题,怀疑是struct meminfo meminfo;的初始化出问题了,所以继续使用printascii/printhex8在各个阶段打印这个结构
u.mem.start=50000000
u.mem.size=10000000
1
r_banks=00000001
start=50000000
u.mem.size=10000000
root=/dev/ram rootfstype=ext2 init=/linuxrc console=ttySAC0,115200 mem=256
2
r_banks=00000000
start=50000000
u.mem.size=00000000
3
r_banks=00000000
start=50000000
u.mem.size=00000000
OK
发现是 parse_early_param();之后就r_banks=00000000确认内存解析函数
early_mem-->memparse
unsigned long long memparse(const char *ptr, char **retptr)
{
char *endptr; /* local pointer to end of parsed string */
unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
switch (*endptr) {
case 'G':
case 'g':
ret <<= 10;
case 'M':
case 'm':
ret <<= 10;
case 'K':
case 'k':
ret <<= 10;
endptr++;
default:
break;
}
if (retptr)
*retptr = endptr;
return ret;
}
size返回是0,终于发现竟然是我的boot args里的mem=256少了个M,悲剧!!!!!
总结一下console_init终端初始化前的定位方法:
1、使用low_level debug的printascii/printhex8做调试打印。
内核配置:
Kernel hacking-->Kernel low-level debugging functions
Kernel hacking-->S3C UART to use for low-level debug 选择UART num。
2、打印出来printk的__log_buf的物理地址的值,软复位或者按键复位后在uboot里使用md 这个物理地址查看打印内容。
printklogbuf = __pa(__log_buf);
printascii("\n__log_buf=");
printhex8(printklogbuf);
printascii("\n");
内存参数传递:
ATAG_MEM
uboot里在armlinux.c的setup_memory_tags里处理,bd->bi_dram[i].start和bd->bi_dram[i].size通常在自己单板的board文件里的dram_init来赋值:
#ifdef CONFIG_SETUP_MEMORY_TAGS
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);
}
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */
内核在这里解析:setup_arch-->parse_tags-->parse_tag_mem32
parse_tags就是根据传递参数里的tags标记,然后选择各种解析函数进行解析,内存解析就是添加内存分区,即修改struct meminfo meminfo的内容
static int __init parse_tag_mem32(const struct tag *tag)
{
return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
}
bootargs:
mem=xM或者其它单位,bootargs是在parse_tags-->parse_tag_cmdline拷贝到内核default_command_line里的,然后在setup_arch--> parse_early_param();解析里面的各个参数,内存就是通过这个early_mem函数来解析的。
优先级:
bootargs>ATAG_MEM。也就是如果在bootargs里面定义了mem=就以bootargs里面为准,因为这个用户定义的。