• 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;
  • 相关阅读:
    @PathVariable("cart_id") @RequestParam("ur") @RequestBody 比较
    将字符串数组解析为数组
    org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class ...
    nacos+openFeign #找不到服务 feign.FeignException$NotFound: status 404 reading
    java生成一个范围的数字
    栏中栏
    百度PaddlePaddle入门-4(5步法之八股文)
    百度PaddlePaddle入门-3(框架)
    百度PaddlePaddle入门-2(使用Numpy构建神经网络)
    MachineLearning入门-3(hello word)
  • 原文地址:https://www.cnblogs.com/tech-lqh/p/9005856.html
Copyright © 2020-2023  润新知