第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 条评论
登录 后参与评论

相关文章

来自专栏JadePeng的技术博客

axios介绍与使用说明 axios中文文档

本周在做一个使用vuejs的前端项目,访问后端服务使用axios库,这里对照官方文档,简单记录下,也方便大家参考。 Axios 是一个基于 Promise 的 ...

1.8K9
来自专栏后台全栈之路

基于汇编的 C/C++ 协程 - 实现

将 libco 和 libevent 两者的功能糅合起来,所以我把我的工程,命名为 libcoevent,意为 “基于 libevent 的同步协程服务器编程框...

4522
来自专栏积累沉淀

Oracle递归查询:使用prior实现树操作

oracle树查询的最重要的就是select…start with…connect by…prior语法了。依托于该语法,我们可以将一个表形结构的数据以树的顺...

2735
来自专栏佳爷的后花媛

php基础(一)

static 是静态变量,在局部函数中存在且只初始化一次,使用过后再次使用会使用上次执行的结果; 作为计数,程序内部缓存,单例模式中都有用到。

1452
来自专栏你不就像风一样

深入理解Spring Boot数据源与连接池原理

在使用Spring Boot数据源之前,我们一般会导入相关依赖。其中数据源核心依赖就是spring‐boot‐starter‐jdbc 如下

7593
来自专栏owent

可执行文件压缩

最近看Rust相关东西的时候看到一篇关于压缩可执行文件的文章。压缩可执行文件对嵌入式开发特别有用,但是延伸一下用来减少我们游戏行业里预编译的工具二进制包大小和A...

3281
来自专栏我的博客

linux基本命令集锦

1. Cat命令 使用权限:所有使用者  使用方式:cat [-AbeEnstTuv] [–help] [–version] fileName  说明...

3327
来自专栏Android 研究

Android插件化基础3----Android的编译打包流程详解

.apk文件其实就是一个压缩包,把文件的后缀改成.zip,用压缩软件解压搜就可的下图(我是mac)

1281
来自专栏流媒体人生

代理存根DLL的创建

源自于一位网友的提问 http://topic.csdn.net/u/20091101/20/10b3651a-7494-44fb-9861-fb2d3c...

832
来自专栏地方网络工作室的专栏

Shell 命令行,生成当前文件夹目录索引 index.html 文件

Shell 命令行,生成当前文件夹目录索引 index.html 文件 做了一些原型图放在 git 上面,在服务器配置好自动拉取 git 中的文件,并配置一个 ...

2249

扫码关注云+社区