u-boot 内核同时传递cmdline时的处理

u-boot 内核同时传递cmdline时的处理

默认是内核boot option里面的config_cmdline,如果u-boot也传参数,则会覆盖。

u-boot传参数方法如下:
在do_bootm_linux中:
72 #ifdef CONFIG_CMDLINE_TAG
73         char *commandline = getenv ("bootargs");
74 #endif
。。。。。。。。。。。
127 #ifdef CONFIG_CMDLINE_TAG
128         setup_commandline_tag (bd, commandline);
129 #endif
在其中会将也就是bootargs的数据作为atags的一项,传递给内核:
218         params->hdr.tag = ATAG_CMDLINE;
219         params->hdr.size =
220                 (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
221 
222         strcpy (params->u.cmdline.cmdline, p);

内核这边则有:
699 static int __init parse_tag_cmdline(const struct tag *tag)
700 {
701         strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
702         return 0;
703 }
704 
705 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);

通过__tagtable,parse_tag_cmdline将在初始化中被调用,如果存在u-boot传来的bootargs,则覆盖掉内核原有的config_cmdline。default_command_line会由原始编译内核时的config_cmdline变为bootargs。

继续内核会去分析command,在setup_arch中,
771         char *from = default_command_line;
。。。。
806         memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
807         saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
808         parse_cmdline(cmdline_p, from);
可以看出随后内核将这个改变后的值进行parse,并且根据parse的结果做相应的设置。

比如首先分析内存:
809         paging_init(&meminfo, mdesc);
包括页表,内存区域等设置。剩下的cmdline会交由后面分析,setup_arch返回后,start_kernel执行到
530         parse_args("Booting kernel", command_line, __start___param,
531                    __stop___param - __start___param,
532                    &unknown_bootoption);
就会调用parse_args对剩下的cmdline进行解析。

可以看出,对于cmdline的处理是以uboot为优先,但是如果将parse_tag_cmdline函数中的内容注释掉,则起作用的就是内核了。


附带额外说一些对内存的设置。cmdline里面有类似mem=xxx这样的设置,但初次以外,内核还必须知道ram的起始地址,因为不像x86,固定从0开始,而且每款arm的soc,内存地址映射都不一样,所以内核必须知道物理地址起址是多少。

首先u-boot中会通过init_sequence指针去设置dram:
5 init_fnc_t *init_sequence[] = {
。。。
298         dram_init,              /* configure available RAM banks */
。。。
301 };
dram设置内存大小和起始地址:
268 int dram_init(void)
269 {       
270         gd->bd->bi_dram[0].start = PHYS_SDRAM;
271         gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
272         return 0;
273 }
PHYS_SDRAM和PHYS_SDRAM_SIZE都定义在各自的include/configs/xxx.h里面

在do_bootm_linux里面,有:
124 #ifdef CONFIG_SETUP_MEMORY_TAGS
125         setup_memory_tags (bd);
126 #endif
就是设置atags的内存区域的值:
static void setup_memory_tags (bd_t *bd)
186 {
187         int i;
188 
189         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
190                 params->hdr.tag = ATAG_MEM;
191                 params->hdr.size = tag_size (tag_mem32);
192 
193                 params->u.mem.start = bd->bi_dram[i].start;
194                 params->u.mem.size = bd->bi_dram[i].size;
195 
196                 params = tag_next (params);
197         }
198 }

类似parse_tag_cmdline,会有:
611 static int __init parse_tag_mem32(const struct tag *tag)
612 {  
613         if (meminfo.nr_banks >= NR_BANKS) {
614                 printk(KERN_WARNING            
615                        "Ignoring memory bank 0x%08x size %dKB\n",
616                         tag->u.mem.start, tag->u.mem.size / 1024);
617                 return -EINVAL;                
618         }
619         arm_add_memory(tag->u.mem.start, tag->u.mem.size);
620         return 0;
621 }  
622 
623 __tagtable(ATAG_MEM, parse_tag_mem32);

但是注意,并不是你传了这个atag,他就会起作用,在setup_arch中有:
792         if (mdesc->fixup)
793                 mdesc->fixup(mdesc, tags, &from, &meminfo);
这个fixup函数是板级相关的,通常就是一些ram起址大小bank之类的设定函数,如果执行过了,nrbank就不为0了,那么继续执行后面的语句时:
795         if (tags->hdr.tag == ATAG_CORE) {
796                 if (meminfo.nr_banks != 0)
797                         squash_mem_tags(tags);
798                 parse_tags(tags);
799         }
就会调用squash_mem_tags把你u-boot传入的值给干掉,使parse_tags函数调用时不会处理ATAG_MEM。

参考链接:
1.http://blog.chinaunix.net/u1/46715/showart_367493.html
2.http://blog.csdn.net/cooboos/archive/2010/05/07/5567142.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值