U-Boot bootargs简析

  Linux内核启动时需要一些配置信息,如根文件系统的类型、flash分区情况、串口终端的编号、内存的使用情况等等,而由于U-Boot和Linux Kernel的镜像是独立的两个文件,所以只能两者约定好在内存的什么地方存放启动参数,这样U-Boot在启动引导时就将启动参数放置在相应的地址处,而Linux Kernel则去相应的地址读取,然后加以处理。

  对于Tiny210开发板,启动参数放置在DDR2 SDRAM起始地址后的0x100偏移处,U-Boot中board/samsung/goni/goni.c中有如下代码:

 1 int board_init(void)
 2 {
 3     /* Set Initial global variables */
 4     s5pc110_gpio = (struct s5pc110_gpio *)S5PC110_GPIO_BASE;
 5 
 6     gd->bd->bi_arch_number = MACH_TYPE_GONI;
 7     gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 8 
 9     return 0;
10 }

  PHYS_SDRAM_1在include/configs/s5p_goni.h中就被定义为DDR2 SDRAM的起始地址。

  而在内核中,arch/arm/mach-s5pv210/mach-mini210.c中也有相关的定义,两者的地址是一样的。

  那么参数应该如何在内存中组织呢?对于内核来说,它应该知道参数是从哪开始,从哪结束,这一点的解决方法是,第一个参数和最后一个参数都约定好形式,下面有说明。

  先看几个用到的数据结构。

 1 struct tag_header {
 2     u32 size;
 3     u32 tag;
 4 };
 5 
 6 struct tag {
 7     struct tag_header hdr;
 8     union {
 9         struct tag_core        core;
10         struct tag_mem32    mem;
11         struct tag_videotext    videotext;
12         struct tag_ramdisk    ramdisk;
13         struct tag_initrd    initrd;
14         struct tag_serialnr    serialnr;
15         struct tag_revision    revision;
16         struct tag_videolfb    videolfb;
17         struct tag_cmdline    cmdline;
18 
19         /*
20          * Acorn specific
21          */
22         struct tag_acorn    acorn;
23 
24         /*
25          * DC21285 specific
26          */
27         struct tag_memclk    memclk;
28     } u;
29 };
30 
31 struct tag *params;

  在启动内核的函数中,全局变量被初始化为:

  params = ( struct tag *)bd->bi_boot_params;

  对U-Boot来说,只要牵住params这个变量,不断向后面写参数就行了,下面简单分析几个参数的填写过程。

  第一个参数必须是TAG_CORE
  

1 设置ATAG_CORE的伪代码
2 params->hdr.tag = ATAG_CORE;
3 params->hdr.size = ( sizeof ( struct tag_header ) + sizeof( struct tag_core ) ) >> 2;
4 params->u.core.flags = 0;
5 params->u.core.pagesize = 0;
6 params->u.core.rootdev = 0;
7 params = params + params->hdr.size;

  重要的参数CMDLING_TAG

1 设置ATAG_CMDLINE的伪代码
2 params->hdr.tag = ATAG_CMDLINE;
3 params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_cmdline ) ) >> 2;
4 p = getenv( "bootargs" );
5 check_bootargs_not_null( p ) && bootargs_valid( p );
6 strcpy( params->u.cmdline.cmdline, p );
7 params = params + params->hdr.size;

  重要参数CONFIG_SETUP_MEMORY_TAGS

1 for( i = 0; i < CONFIG_NR_DRAM_BANKS; i++ )    //tiny210中此宏为1
2 {
3     params->hdr.tag = ATAG.MEM;
4     params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_mem32 ) ) >> 2;
5     params->u.mem.start = bd->bi_dram.start;
6     params->u.mem.size = bd->bi_dram.size;
7     params = params + params->hdr.size;
8     
9 }

  可选参数CONFIG_REVISION_TAG

1 params->hdr.tag = ATAG_REVISION;
2 params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_revision ) ) >> 2;
3 revision = board_get_revision();
4 params->u.revision.rev = revision;
5 params = params + params->hdr.size;

  可选参数SERIAL_TAG

1 params->hdr.tag = ATAG_SERIAL;
2 params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_serial ) ) >> 2;
3 serialnr = board_get_serialnr(); 
4 params->u.serialnr.low = serialnr.low;
5 params->u.serialnr.high = serialnr.high
6 params = params + params->hdr.size;

  INITRD_TAG,所谓initrd 就是init ramdisk

 1 if( images->rd_start && images->rd_end )
 2  3     setup_initrd_tag( gd->bd, images->rd_start, images->rd_end );
 4     虽然s5p_goni.h中使用了宏定义,但是没有使用。
 5     params->hdr.tag = ATAG_INITRD2; ATAG_INITRD是压缩的ramdisk image所在    的虚拟地址,ATAG_INITRD2是相应的物理地址。
 6     params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_initrd ) ) >> 2;
 7     params->u.initrd.start = initrd_start;
 8     params->u.initrd.size = initrd_end - initrd_start;
 9     params += params->hdr.size;    
10

对应于开始的ATAG_CORE,最后一个也需要固定格式的tag:

1 params->hdr.tag = ATAG_NONE;
2 params->hdr.size = 0;

 

转载于:https://www.cnblogs.com/tech-lqh/p/9005856.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值