uboot基础与常用命令

1. bootloader 与 uboot的区别

BootLoader是嵌入式设备中用来启动操作系统内核的一段程序。
uboot(universal bootloader)是一种可以用于多种嵌入式CPU的BootLoader程序,换言之,uboot是bootloader的一个子集。
uboot的核心作用就是启动操作系统内核,uboot的本质就是一段裸机程序。

2. uboot的特性

2.1 硬件管理

uboot要能够进行Soc级(Soc内部外设)和板级(Soc外部外设)硬件管理。

uboot中实现了一部分硬件的控制能力(uboot中初始化了一部分硬件),因为uboot为了完成一些任务必须让这些硬件工作。譬如uboot要实现刷机必须能驱动iNand,譬如uboot要在刷机时LCD上显示进度条就必须能驱动LCD,譬如uboot能够通过串口提供操作界面就必须驱动串口。譬如uboot要实现网络功能就必须驱动网卡芯片。

2.2 能够完成镜像烧录(刷机)

uboot要能够被借助完成刷机操作。参考下SD卡刷机的步骤:

  1. 烧录uboot到SD卡中。
    有2种烧写方法:一种是在windows中用刷卡工具去制作启动SD卡;另一种是在linux中用dd命令。制作完SD后将SD卡插入开发板,然后开机就可以进入uboot界面。
  2. 使用uboot的fastboot命令,并借助PC中的fastboot软件完成包括uboot、kernel、rootfs等的镜像的烧录。

从上面就可以看出,刷机依靠的是uboot的fastboot命令,将镜像写到相应的FLASH中。

2.3 uboot的“生命周期”

uboot的入口就是开机自动启动,uboot的唯一出口就是启动内核。uboot还可以执行很多别的任务(譬如烧录系统),但是其他任务执行完后都可以回到uboot的命令行继续执行uboot命令,而启动内核命令一旦执行就回不来了。

2.4 uboot要提供命令式shell界面

shell是用户操作接口的意思。shell有命令行的shell,如windows下的cmd,如linux下的终端;也有GUI式的shell,比如常用的windows下的各种界面。shell是一种封装后留出来的接口,uboot也要有这样的一个接口。

shell的原理是:由消息接收、解析、执行构成的一个死循环。我之前用过3D打印机的固件(firmware)也是这样的模式。

uboot的shell使用的也是行缓冲的模式。也就是以回车键(换行键)作为一个命令输入的结束。对应的其他缓冲模式还有无缓冲和全缓冲:无缓冲就是输入一个字符就当做一个命令处理;全缓冲就是无论输入什么都缓冲起来知道缓冲区满了才做一次处理。

3. uboot的常用命令

3.1 环境变量介绍与操作命令

环境变量:就是整个系统的一个全局变量。其余全局变量不同的就是,全局变量在一次程序结束后下一次要重新开始;而全局变量可以保存在FLASH中,继续使用上次修改的值。

  • printenv(或print)
    打印出环境变量。
  • setenv(或set)
    新建一个环境变量,使用 set var value
    更改一个环境变量,使用set var value
    删除一个环境变量,使用 set var
  • saveenv(或save)
    保存环境变量。保存环境变量这一指令的意义在于用set指令更改了环境变量之后,只是在DDR内存中做了改变,用save即命令将环境变量从DDR中写入FLASH。从这里也可以看出,环境变量在整个系统中是有两套的,FLASH中一套,DDR中一套。

具体的uboot的各项环境变量的意思在后面详细讲述。

3.2 网络测试指令:ping命令

ping是测试开发板和主机之间的网络链接,其使用格式为:ping ip地址


uboot基础与常用命令_第1张图片

如上图所示,ping指令要想成功,三个环节要做好:

  1. 主机IP地址设置正确;
  2. 网线连接正常;
  3. 开发板IP地址设置正确。注意,主机IP和开发板IP应该位于同一网段才可以(如下图,子网掩码相同的IP地址位于同一网段)。设置开发板IP地址的方法就是更改uboot中的环境变量ipaddr。

uboot基础与常用命令_第2张图片
值得一提的是当主机使用的是linux虚拟机时,设置其IP地址的方式如下:

  1. 虚拟机设置成桥接方式。虚拟机的网卡设置可以选择好几种方式,常用的就是NAT和桥接(bridged)。虚拟机要和开发板进行网络通信,只能通过桥接方式连接。
  2. 虚拟机的菜单“虚拟网络编辑器”,设置为“桥接到有线网卡”。(默认是自动的,自动的一般会影响ping通。因为电脑一般都有2个网卡:一个有线的,一个无线的。如果选了自动,那么虚拟机会自动桥接到无线网卡上)
  3. 在虚拟机ubuntu中设置IP地址(可以通过/etc/network/interfaces文件来设置静态的然后重启;也可以直接命令行ifconfig去设置)。

3.3 SD卡/iNand操作指令:movi

movi指令是movi read和movi write一组的,movi read用来读取iNand到DDR上,movi write用来将DDR中的内容写入iNand中。理解这些指令时一定要注意涉及到的2个硬件:iNand和DDR内存。

如movi read的使用方法为:movi read {u-boot | kernel} {addr}

其中,{u-boot | kernel}代表的是SD卡或iNAND中的一个分区。 {addr}代表DDR中的地址。上面的意思就是把uboot的某一个分区写到DDR的地址addr处。

这里也插播一个小知识:uboot是把iNAND分区管理的,一般有以下几个分区:

  • uboot分区:uboot必须从Flash起始地址开始存放,一般设计为512KB或者1MB;
  • 环境变量分区:环境变量分区一般紧贴着uboot来存放,大小为32KB或者更多一点。
  • kernel分区:kernel可以紧贴环境变量存放,大小一般为3MB或5MB或其他。
  • rootfs分区:剩下的就是自由分区,一般kernel启动后将自由分区挂载到rootfs下使用

一般分区规律如下:

  • 各分区彼此相连,前面一个分区的结尾就是后一个分区的开头。
  • 整个flash充分利用,从开头到结尾。
  • uboot必须在Flash开头,其他分区相对位置是可变的。
  • 各分区的大小由系统移植工程师自己来定;
  • 分区在系统移植前确定好,在uboot中和kernel中使用同一个分区表。

3.4 内存操作指令

内存操作指令主要有三个:md(memory display 显示内存)、mw(memory write 写内存)、mm(memory modify 内存修改)
使用help查看各个指令的用法:
md [.b, .w, .l] address [# of objects]
mw [.b, .w, .l] address value [count]
mm [.b, .w, .l] address
其中,可选项[.b .w .l]的意思是使用字节(b,8位,一个内存地址内容)还是字(w,16位,两个内存地址内容),还是长整型(l,32位,4个内存地址内容)来操作内存。[# of objects]、count 代表要操作内存的数目。

3.5 启动内核指令

uboot的终极目标就是启动操作系统内核,其指令为bootm addr

4 uboot环境变量详解

使用print命令打印出uboot环境变量如下所示:

bootcmd=movi read kernel 30008000; movi read rootfs 30B00000 300000; bootm 30008000 30B00000
mtdpart=80000 400000 3000000
baudrate=115200
ethaddr=00:40:5c:26:0a:5b
ipaddr=192.168.1.88
serverip=192.168.1.102
gatewayip=192.168.0.1
netmask=255.255.0.0
bootdelay=3

4.1 bootdelay 与 bootcmd

在uboot开启之后,会有一个倒计时的操作,如果检测到按键输入就进入到uboot命令行下执行各种命令,否则将执行 bootcmd 这个环境变量中保存的命令集,而这个倒计时的秒数就是由环境变量 bootdelay 表示的。

分析一下bootcmd环境变量的内容,首先将内核和根文件系统读进内存中,然后使用bootm启动内核。在自己修改这个环境变量的时候,命令如下:
set bootcmd 'movi read kernel 30008000; movi read rootfs 30B00000 300000; bootm 30008000 30B00000'
注意两点,一是需要用单引号把值给引起来,表示是一个整体;二是单引号之间的命令间要有空格隔开!

4.2 网络相关

  • ipaddr是开发板的本地IP地址
  • serverip是开发板通过tftp指令去tftp服务器下载东西时,tftp服务器的IP地址。
  • gatewayip是开发板的本地网关地址
  • netmask是子网掩码
  • ethaddr是开发板的本地网卡的MAC地址。

4.3 内核传参

linux内核启动时可以接收uboot给他传递的启动参数,这些启动参数是uboot和内核约定好的形式、内容,linux内核在这些启动参数的指导下完成启动过程。这样的设计是为了灵活,为了内核在不重新编译的情况下可以用不同的方式启动。
我们要做的事情就是:在uboot的环境变量中设置bootargs,然后bootm命令启动内核时会自动将bootargs传给内核。

在我的环境变量中没有看到bootargs这个环境变量,但是mtdpart、baudrate都是bootargs的一部分。

你可能感兴趣的:(uboot与内核移植)