移植Linux内核到s3c6410(kernel 打印:Uncompressing Lin(3)

这里分配出了问题,怀疑是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里面为准,因为这个用户定义的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjwjw.html