How Linux Get Tags - m805-8935

Having finished the HW environment initialization, the bootloader needs to pass some kernel-boot parameters to kernel when it tries to start Kernel. Indeed,  In addition to the common Command Line parameter, there are other indispensable parameters, such as system memory layout profile as well as vendor specific parameters. 

This article describes:

1. The way bootloader organizes such info.

2. The approach Kernel gets such info.


Part 1:Bootloader (Provider):

A.  Bootloader defines the memory area used to keep parameters (Linux organizes such parameters as TAGs) in

      lk/target/m805_893x_evm/rules.mk:

      #define BASE_ADDR := 0x80000000

      #define TAGS_ADDR := BASE_ADDR+0x00000100      //0x80000100

      #define KERNEL_ADDR := BASE_ADDR+0x00008000      //0x80008000

B.  Bootloader calls boot_linux() to start Kernel.

      The routine boot_linux() is defined in lk/app/aboot.c. The 2nd parameter is exact TAGS_ADDR.

      (BTW, the 1st parameter is exact KERNEL_ADDR, the start address of kernel image)

      The routine first defines a pointer point to TAGS_ADDR, then put all parameters into subsequent memory address:

      unsigned *ptr = tags; //TAGS_ADDR
 
      /* CORE */
      *ptr++ = 2;
      *ptr++ = ATAG_CORE;    //TAG type

      if (ramdisk_size) {
        *ptr++ = 4;  
        *ptr++ = ATAG_INITRD2;          //TAG type
        *ptr++ = (unsigned)ramdisk;  //Parameter
        *ptr++ = ramdisk_size;            //Parameter
      }

      ptr = target_atag_mem(ptr);     //TAG_MEM: The memory allocated to Kernel

                                                             //ATAG_TCC_PMAP. The memory allocated to specific HW. Vendor specific

      if (cmdline) {
        cmdline_len = strlen(cmdline);
        *ptr++ = 2 + ((cmdline_len + 3) / 4);
        *ptr++ = ATAG_CMDLINE;      //ATAG_CMDLINE
        strcpy(ptr, cmdline);
        ptr += (cmdline_len + 3) / 4;  //command line paramters
      }

      /* tag for the board revision */
      ptr = target_atag_revision(ptr);

      ptr = target_atag_is_camera_enable(ptr);

      ......

      /* END */
      *ptr++ = 0;        //ATAG_NONE
      *ptr++ = 0;
        //ATAG_NONE 


      Up to now, the bootloader has made the TAGs ready. The TAGs are organized this way:

     -------------------------- TAGS_ADDR

      2  (the size of tag TAG_CORE)

      TAG_CORE

      --------------------------

      TAG 1 SIZE

      TAG 1 TYPE

      TAG 1 para (if any)

      --------------------------

      TAG 2 SIZE

      TAG 2 TYPE

      TAG 2 para (if any)

      --------------------------

      ...

      --------------------------

      TAG n SIZE

      TAG n TYPE

      TAG n para (if any)

      --------------------------

      TAG_NONE

      TAG_NONE

      --------------------------


Part 2:Kernel (Consumer):

A. The kernel gets TAGs address via below macro in arch/arm/mach-tcc893x/board-m805_893x.c

    MACHINE_START(M805_893X, "m805_893x")
    /* Maintainer: Telechips Android BSP Team <android_ce@telechipc.com> */
    .boot_params    = PHYS_OFFSET + 0x00000100,  //0x80000100
    .reserve        = tcc8930_mem_reserve,
    .map_io         = m805_893x_map_io,
    .init_early        = m805_893x_init_early,
    .init_irq       = m805_893x_init_irq,
    .init_machine   = m805_893x_init_machine,
    .timer          = &tcc893x_timer,
    MACHINE_END

B. In arch/arm/kernel/setup.c, the routine setup_arch calls setup_machine_tags() in the same file to parse TAGs:

static struct machine_desc * __init setup_machine_tags(unsigned int nr)

{
   ......

    if (__atags_pointer)
        tags = phys_to_virt(__atags_pointer);
    else if (mdesc->boot_params) {
#ifdef CONFIG_MMU
        /*
         * We still are executing with a minimal MMU mapping created
         * with the presumption that the machine default for this
         * is located in the first MB of RAM.  Anything else will
         * fault and silently hang the kernel at this point.
         */
        if (mdesc->boot_params < PHYS_OFFSET ||
            mdesc->boot_params >= PHYS_OFFSET + SZ_1M) {
            printk(KERN_WARNING
                   "Default boot params at physical 0x%08lx out of reach\n",
                   mdesc->boot_params);
        } else
#endif
        {
            tags = phys_to_virt(mdesc->boot_params);    //Get TAGs physical address then turns it into virtual address.
        }
    }

#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
    /*
     * If we have the old style parameters, convert them to
     * a tag list.
     */

    if (tags->hdr.tag != ATAG_CORE)
        convert_to_tag_list(tags);
#endif

    if (tags->hdr.tag != ATAG_CORE) {
#if defined(CONFIG_OF)
        /*
         * If CONFIG_OF is set, then assume this is a reasonably
         * modern system that should pass boot parameters
         */
        early_print("Warning: Neither atags nor dtb found\n");
#endif
        tags = (struct tag *)&init_tags;
    }

    if (mdesc->fixup)
        mdesc->fixup(mdesc, tags, &from, &meminfo);

    if (tags->hdr.tag == ATAG_CORE) {
        if (meminfo.nr_banks != 0)
            squash_mem_tags(tags);
        save_atags(tags);
        parse_tags(tags);                                           //Calls TAG handlers to parse TAG.
    }

    /* parse_early_param needs a boot_command_line */
    strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);

    return mdesc;
}


PS: There is NO TAG packages in 8900 BSP!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值