uboot传递启动参数给内核

  uboot把内核复制到SDRAM之后,需要跳转到内核的入口函数执行。在跳转之前,还要给内核传递启动参数。传递方式是uboot把启动参数按一定的格式放在指定的地址(位于SDRAM),启动内核之后,内核再去这个地址上读取启动参数。

  在uboot源码中搜索do_bootm_linux函数如下:

int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
        ...
        ...
    boot_prep_linux(images);
    boot_jump_linux(images);
    return 0;
}    
 boot_prep_linux函数做的工作就是“把启动参数按一定的格式放在指定的地址”,函数内容如下:
static void boot_prep_linux(bootm_headers_t *images)
{
    char *commandline = getenv("bootargs");
        ...

    setup_start_tag(gd->bd);
        ...
        ...
    setup_commandline_tag(gd->bd, commandline);
    setup_memory_tags(gd->bd);
        ...
    setup_initrd_tag(gd->bd, images->rd_start,images->rd_end);
        ...
    setup_end_tag(gd->bd);
}
boot_prep_linux函数把启动参数封装成一个个“tag”,看看setup_start_tag函数的实现,可以得知这些tag被存放在哪个地址上:

 可以看到,params结构体的首地址就是存放tag的首地址,在源码中搜索bd->bi_boot_params可以发现,在u-boot-2012.04.01/board/samsung/smdk2440/smdk2440.c文件的board_init函数中有赋值:

也就是uboot在板子初始化的时候就给bd结构体的成员赋了值,bd的全程是board_data,很合理。

setup_commandline_tag是把uboot的“bootargs”参数作为linux的启动参数,查看include/configs/smdk2440.h文件可以知道:
 #define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"——bootargs为linux指定了控制台用到的串口和根文件系统存在的区域。
setup_memory_tags告诉linux板子上有几个ram区域,每个区域的大小是多少。
setup_initrd_tag功能不太清楚,先不关心。
设置完启动参数之后,在boot_jump_linux函数中调用kernel_entry(0, machid, r2)函数跳转到linux中。
  

 

 
原文地址:https://www.cnblogs.com/physworld/p/15039972.html