上文中,我们说到了使用uboot去启动kernel支持的几种方式以及压缩kernel的几种形式,本章节将要接着内核的启动说起。
上一章我们对uImage格式进行了初步的说明,并说这样的格式已经被废弃,但是依然保留了相应的代码。boot_get_kernel主要用于uImage头校验,从而得到kernel的启动位置。当argc<2时,代表传参数不足,则使用默认的加载位置进行加载。
上面这里基本就包含了启动镜像的基本过程。GZIP/BZIP2是压缩格式,uboot提供了解压内核的方式,但可以不使用,内核有自解压。
uboot最早支持uImage启动方式,后面有了设备树(FDT)于是就有了LEGACY与FIT两种启动方式,后面有了zImage,但是为了省事用goto使用zImage启动,把代码夹在了FDT与uImage的启动方式之间。
内核->DDR->校验->启动内核。将DDR到启动内核分为三个阶段,使用do_bootm_linux进行内核的启动。
do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
bootm_headers_t *images)其中images为镜像启动信息
查看镜像是否有效if(image->legacy_hdr_valid)。
ulong ep,其中ep为entry point的缩写意为程序入口,一个镜像文件起始执行不在第一个字节,前面的部分是存放头信息的。
执行镜像的过程:
thekernel=(void (*)(int,int,uint)) ep;
void (*thekernel)(int zero,int arch,unint params);
ep为偏移量的第一个入口地址的函数的地址。
thekernel指向镜像的真正入口地址,当调用thekernel时,代表了uboot的生命周期结束。
thekernel(0,machid,bd->bi_boot,params);
getenv("machid");将机器码传给内核有两个方案①环境变量machid。②gd->bd->bi_arch_num。对于x210而言,这是由x210_sd.h的硬编码决定的。
uboot给linux内核做传参准备,uboot的最后一句话是staring kernel......说明uboot该干的事情干完了,但不能保障kernel成功执行。若一直卡在这个位置应该对内核中是否内容、uboot到kernel的传参是否正确、内核加载地址等方面进行检查。
本章结束了,我们对uboot进行了扫尾工作,但由于内核启动与uboot传参之间的紧密联系,所以后面的几章内容或许还能见到uboot的身影,后面会用几个章节的时间对uboot进行总结。