嵌入式开发丨了解系统中的Uboot功能

Uboot全称 Universal Boot Loader ,一个遵循GPL协议的的开源项目,其作用是引导操作系统,支持引导Linux、VxWorks、Solaris等操作系统;其源码组织形式和Linux源码很相似,编译也可参照Linux源码编译,且包含许多Linux源码中的驱动源码,所以Uboot实际上可以算作一个微型的操作系统,可以做一些简单工作。

01
Uboot完成的工作


Uboot需要完成的工作有:读Flash、初始化sdram、启动内核。 总结起来的话就是:

Uboot主要作用是用来启动操作系统内核;

Uboot还要负责部署整个计算机系统;

Uboot中还要操作Flash等板子上硬盘的驱动;
Uboot还得提供一个命令行界面供人来操作。


注意: 在从Flash读出内核写到sdram之前,需要先关闭看门狗,再初始化sdram、初始化系统时钟。


为了完成这个工作,且便于调试,还要开发一下其他功能:例如设置Uboot的一些参数,再把设置好的参数写入到Flash,还需要用到网卡、usb及串口等以便调试。



02
Uboot的工作模式


大多数的Uboot都包含两种不同的操作模式:“下载模式”和“启动模式”。


下载模式 是指Uboot将通过串口或网络等通信手段从主机下载文件,然后控制启动流程。

启动模式 是指Uboot从目标机上的某个固态存储设备上将操作系统自动加载到RAM中运行。


在典型的嵌入式Linux系统中


部署: Uboot程序部署在Flash(能作为启动设备的Flash)上、OS部署在FLash(嵌入式系统中用Flash代替了硬盘)上、内存在掉电时无作用,CPU在掉电时不工作。

启动:嵌入式系统上电后先执行Uboot、然后Uboot负责初始化DDR、初始化Flash,然后将OS从Flash中读取到DDR中,然后启动OS(OS启动后Uboot就无用了)。


在Android系统中


  • Android系统的启动和Linux系统(典型的嵌入式系统启动)几乎一样。几乎一样意思就是前面完全一样,只是在内核启动后加载根文件系统后就不同了。

  • 可以认为启动分为2个阶段:第一个阶段是Uboot到OS启动;第二个阶段是OS启动后到rootfs加载到命令行执行;现在我们说的是第一个阶段,Android的启动和Linux的差别在第二阶段。




03
命令和环境变量


Uboot在使用中的两个关键点:命令和环境变量


命令 就是Uboot的shell中可以识别的各种命令。

Uboot中有几十个命令,其中有一些常用另一些不常用(我们还可以自己给Uboot添加命令)。


Uboot启动后大部分时间和工作都是在shell下完成的(譬如Uboot部署系统在shell下输命令、设置环境变量也得在命令行底下,启动内核也要在命令行底下敲命令)。


环境变量 就是运行时的配置属性。
Uboot的环境变量和操作系统的环境变量工作原理和方式几乎完全相同。Uboot在设计时借助了操作系统的设计理念(命令行工作方式借鉴了Linux终端命令行,环境变量借鉴了操作系统的环境变量,Uboot的驱动管理几乎完全照抄了Linux的驱动框架)。


环境变量可以被认为是系统的全局变量,环境变量名都是系统内置的(譬如PATH;但是也有一部分环境变量是自己添加的)。


系统或者我们自己的程序在运行时可以通过读取环境变量来指导程序的运行。这样设计的好处就是灵活,譬如我们要让一个程序更改运行方法,不用去重新修改程序代码再重新编译运行,而只要修改相应的环境变量就可以了。


注意: 修改完环境变量后一定要保存,否则下次开机更改的就没有了。


04
Uboot常用命令



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中环境变量的分区。


第三个命令: ping
 网络测试指令, 用法: ping IP地址
注意: ping是测试开发板和主机之间的网络链接。先要插上网线,试图ping通主机windows,再确认开发板中uboot里几个网络相关的环境变量的值对不对。


第四个命令: 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命令行中调用这个指令就会启动内核(不管成功与否)。


请使用浏览器的分享功能分享到微信等