u-boot分析3:第二阶段代码分析(1)
u-boot的最终目的就是启动内核,我们围绕这个重点来分析相关代码,弄清u-boot的主要启动流程,其他的代码可以暂时先不看。
下面试start_armboot函数的流程图:
CPU进行一些初始化后,会调用flash_init()、nand_init()来初始化Norflash和Nandflash,这样就有能力读写Norflash和Nandflash。
接着初始化环境变量:
环境变量分两种1是默认的代码里写死的;2是flash上保存的。uboot启动时,env_relocate()会判断flash上是否有环境变量,有就用,没有就使用默认的。
u-boot环境变量如下:
继续看代码,有一个main_loop()。可以知道在void start_armboot (void)中,经过一系列初始化等,到最后进入到一个主循环main_loop(),这个主循环控制着串口u-boot的界面,以及内核的启动。
进一步分析main_loop():main_loop()中有如下代码,u-boot启动时有一个倒数计时,如果在计时时间内没有按空格键的话,就启动Linux,首先是获取"bootcmd",
s = getenv ("bootcmd"); 然后
run_command (s, 0);
"bootcmd"是u-boot环境变量,刚刚查看过:bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
从Nandflash上读出内核: nand read.jffs2 0x30007FC0 kernel; //从kernel分区读内核到0x30007FC0地址
启动内核 :bootm 0x30007FC0 //从0x30007FC0地址启动内核
具体为什么是这个地址0x30007FC0后面再做分析,这里先放下。
如果u-boot在倒数计时中按了空格键,则代码跳转到如下:跳转到 run_command("menu", 0);就是按完空格后,u-boot出现一个菜单选项。
进入一个死循环换,就是u-boot控制界面,等着输入,我们在串口输入一个命令,它就解析并执行。
由上可以看出,u-boot启动内核:s = getenv ("bootcmd"); 然后run_command (s, 0);
u-boot控制界面也是:run_command (lastcommand, 0);
u-boot的核心就是命令!!只有分析这些命令是怎么实现怎么执行的,我们才能搞清楚u-boot具体是怎们启动内核的。后面会自己实现一条命令,在u-boot启动时打印自己想要看到的信息这个例子来帮忙理解。
参考:《嵌入式Linux完全开发手册》