第1阶段——uboot分析之硬件初始化start_armboot函数(5)

start_armboot()分析: 在start.S初始化后跳转到start_armboot实现第2阶段硬件相关的初始化(烧写擦除flash,网卡驱动,usb驱动,串口驱动,从FLASH读内核,启动内核等)然后调用main_loop();实现u-boot环境参数设置(print),读内核,启动内核等

start_armboot函数代码如下(位于u-boot-1.1.6/lib_arm/borad.c)

void start_armboot (void)
{
...
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { //init_sequence:进入初始化序列,初始化CPU,GPIO,中断,环境,串口,设置SDRAM首地址和长度等
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}

size = flash_init (); //初始化NOR FLASH
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); //初始化malloc(相当于C语言中的malloc()和free(),实现堆的分配和释放)
nand_init();    //初始化NAND FLASH
env_relocate (); //将环境参数[enviconment]迁移[relocate]到内存指定位置
cs8900_get_enetaddr (gd->bd->bi_enetaddr); //初始化网络设备
....
for (;;) {
main_loop (); //死循环调用main_loop();
}

main_loop()分析(位于u-boot-1.1.6/common/main.c):
环境参数设置,从flash读出内核,启动内核等
void main_loop (void)
{
...

s = getenv ("bootdelay"); //char指针变量s指向bootdelay(开机倒计时)环境变量
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; //这个CONFIG_BOOTDELAY全局变量等于3,表示bootdelay=3S、
...
...
s = getenv ("bootcmd"); //char指针变量s指向bootcmd(command)环境变量
...
...
if (bootdelay >= 0 && s && !abortboot (bootdelay)) { //当开机bootdelay秒内无串口输入时
...
# ifndef CFG_HUSH_PARSER
{
printf("Booting Linux ...\n"); //启动 Linux ...
run_command (s, 0); //执行bootcmd命令 s= getenv ("bootcmd");
}
...
}
/*bootcmd:启动命令 */
/*在uboot里输入print就会有这么一行"boodcmd=nand read .jffs2 0x30007FC0 kernel; bootm 0x30007FC0" */ 
/*当在开机bootdelay秒内未有串口输入,则会执行bootcmd命令: */ 
/*1.从NAND FLASH中读出内核到SDRAM的0x30007FC0中(nand read .jffs2 0x30007FC0 kernel) */ 
/* 2.从0x30007FC0中启动内核 */
...
...
run_command("menu", 0); //当开机bootdelay秒内有串口输入时,进入菜单界面,按q(queue)键退出
...
...
for (;;) { //进入u-boot界面
...
len = readline (CFG_PROMPT); //一直扫描串口输入的命令(以回车结尾)
...
rc = run_command (lastcommand, flag); //执行串口输入的命令
}
...
}

本章小结:

uboot-第二阶段硬件初始化主要主要执行以下三个过程: 1.启动内核(开机不按空格) { s = getenv ("bootcmd"); //char指针变量s指向bootcmd(command)环境变量 run_command (s, 0); //执行bootcmd命令 run_command():执行命令函数 } 2.进入菜单(开机按空格) { run_command("menu", 0); //进入菜单界面,按q(queue)键退出 } 3.进入u-boot界面(退出菜单后) { len = readline (CFG_PROMPT); //一直扫描串口输入的命令(以回车结尾) rc = run_command (lastcommand, flag); //执行串口输入的命令 } *上面三个过程都是执行了run_command()函数,所以u-boot核心在于执行命令。接下来开始分析u-boot怎么实现查找命令和制作命令。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏施炯的IoT开发专栏

《101 Windows Phone 7 Apps》读书笔记-NOTEPAD

课程内容 Ø 读写文件     Notepad提供了快速、高效的记录手段,它具有以下的特点: Ø 自动保存,使得速记变得快速而简单。 Ø 提供每条笔记的快...

18410
来自专栏散尽浮华

nginx负载均衡(5种方式)、rewrite重写规则及多server反代配置梳理

Nginx除了可以用作web服务器外,他还可以用来做高性能的反向代理服务器,它能提供稳定高效的负载均衡解决方案。nginx可以用轮询、IP哈希、URL哈希等方式...

3856
来自专栏ionic3+

【Appetite】ionic3实录(七)次页实现及分析解决问题【下】

一般一些js插件,是依托dom的。我们观察initSwiper方法,第一个参数'.wheel .swiper-container'其实是个选择器,所以它也是依托...

622
来自专栏陈仁松博客

UWP基础教程 - XAML资源

在Windows 10 UWP应用开发中,XAML用于应用界面设计,无论是开发人员还是设计人员经常会设计自定义用户界面或者控件行为,其中会涉及到不同方面的代码设...

33610
来自专栏向治洪

Android监听自身卸载,弹出用户反馈调查

1,情景分析         在上上篇博客中我写了一下NDK开发实践项目,使用开源的LAME库转码MP3,作为前面几篇基础博客的加深理解使用的,但是这样的项目用...

2175
来自专栏nummy

Tornado入门(八)【运行和部署】

由于Tornado自身提供了HTTPServer, 所以它的运行和部署与其他Python Web 框架不一样。我们可以直接写一个main()方法来启动一个服务器...

622
来自专栏琯琯博客

Yii2 学习笔记之场景应用

2954
来自专栏liulun

自己动手写客户端UI库——创建第一个控件

在上一篇文章中我们主要讲了C#如何和JS通信, 这一篇文章中,我们将创建一个最基础的Button控件 WUI库中控件的继承机制 我们先解释最简单的继承...

1757
来自专栏進无尽的文章

一次模块重构的总结

不同子类通过重写 BaseItem 的公共属性的 set、get 方法来达到初始化组件或者获取所需提交数据等 这一步中把转化的逻辑都写在了自定义控件内部,对...

302
来自专栏较真的前端

关于事件的前端面试题总结

1975

扫码关注云+社区