Uboot全称 Universal Boot Loader ,一个遵循GPL协议的的开源项目,其作用是引导操作系统,支持引导Linux、VxWorks、Solaris等操作系统;其源码组织形式和Linux源码很相似,编译也可参照Linux源码编译,且包含许多Linux源码中的驱动源码,所以Uboot实际上可以算作一个微型的操作系统,可以做一些简单工作。
Uboot需要完成的工作有:读Flash、初始化sdram、启动内核。 总结起来的话就是:
Uboot还要负责部署整个计算机系统;
注意: 在从Flash读出内核写到sdram之前,需要先关闭看门狗,再初始化sdram、初始化系统时钟。
为了完成这个工作,且便于调试,还要开发一下其他功能:例如设置Uboot的一些参数,再把设置好的参数写入到Flash,还需要用到网卡、usb及串口等以便调试。
大多数的Uboot都包含两种不同的操作模式:“下载模式”和“启动模式”。
下载模式 是指Uboot将通过串口或网络等通信手段从主机下载文件,然后控制启动流程。
启动模式 是指Uboot从目标机上的某个固态存储设备上将操作系统自动加载到RAM中运行。
在典型的嵌入式Linux系统中
部署: Uboot程序部署在Flash(能作为启动设备的Flash)上、OS部署在FLash(嵌入式系统中用Flash代替了硬盘)上、内存在掉电时无作用,CPU在掉电时不工作。
启动:嵌入式系统上电后先执行Uboot、然后Uboot负责初始化DDR、初始化Flash,然后将OS从Flash中读取到DDR中,然后启动OS(OS启动后Uboot就无用了)。
-
Android系统的启动和Linux系统(典型的嵌入式系统启动)几乎一样。几乎一样意思就是前面完全一样,只是在内核启动后加载根文件系统后就不同了。
-
可以认为启动分为2个阶段:第一个阶段是Uboot到OS启动;第二个阶段是OS启动后到rootfs加载到命令行执行;现在我们说的是第一个阶段,Android的启动和Linux的差别在第二阶段。
Uboot在使用中的两个关键点:命令和环境变量
命令 就是Uboot的shell中可以识别的各种命令。
Uboot中有几十个命令,其中有一些常用另一些不常用(我们还可以自己给Uboot添加命令)。
Uboot启动后大部分时间和工作都是在shell下完成的(譬如Uboot部署系统在shell下输命令、设置环境变量也得在命令行底下,启动内核也要在命令行底下敲命令)。
Uboot的每个命令都有事先规定好的各种格式。
-
有些命令是 带参数(注意格式是固定的);
-
有些命令是 不带参数的(譬如printenv/print命令);
-
有些命令带 可选的参数(既可带也可不带,带不带参数的执行结果是不同的);
-
有些命令带 必须的参数(譬如setenv/set命令);
-
有些命令有 简化的别名(譬如printenv命令可以简化为print,譬如setenv可以简化为set);
-
有些命令是一个 命令族(譬如movi);
-
采用“ help+命令名”来查询命令的详细信息,只输入help时,则打印出命令列表。
第一个命令:
print
该命令不用带参数,作用是打印出系统中所有的环境变量。
注意: 环境变量和全局变量不同之处在于:
-
全局变量的生命周期是在程序的一次运行当中,开始运行时诞生程序结束时死亡,下次运行程序时从头开始;
-
环境变量被存储在Flash的另一块专门区域(Flash上有一个环境变量分区),一旦我们在程序中保存了该环境变量,那么下次开机时该环境变量的值将维持上一次更改保存后的值。
第二个命令: set、save
-
setenv/set 设置(添加/更改)环境变量,
用法:set name value
-
saveenv/save 保存环境变量的更改,该命令不带参数,直接执行
注意:
想要彻底更改一个环境变量的值,需要2步:
1、set命令来更改内存中的环境变量;
2、用save命令将其同步到Flash中环境变量的分区。
第四个命令: Tftp
通过网络下载文件
Uboot> setenv ethaddr
Uboot> setenv ipaddr
Uboot> setenv serverip (tftp服务器的地址)
注意: Tftp方式下载时实际上Uboot扮演的是Tftp客户端程序角色,主机Windows或虚拟机Ubuntu中必须有一个Tftp服务器,然后将要下载的镜像文件放在服务器的下载目录中,然后开发板中使用Uboot的Tftp命令去下载即可。
第五个命令: Flinfo
查看Flash扇区信息, 用法:uboot>flinfo
第六个命令: SD卡/iNand操作指令movi
开发板如果用SD卡/EMMC/iNand等作为Flash,则在Uboot中操作Flash的指令为movi(或mmc)。
movi的指令都是movi read和movi write一组的,movi read用来读取iNand到DDR上,movi write用来将DDR中的内容写入iNand中。
第七个命令: 启动内核指令bootm、go
bootm启动内核同时给内核传参,而Go命令启动内核不传参。
U
boot的终极目标就是启动内核,启动内核在Uboot中表现为一个指令,Uboot命令行中调用这个指令就会启动内核(不管成功与否)。