u-boot介绍

u-boot是一种主要应用于嵌入式系统的bootloader,可以支持多种不同的计算机架构,包括x86、arm、mips等。可以在x86架构上交叉编译出用于arm架构的u-boot。u-boot负责硬件资源的初始化和加载OS。也可以通过u-boot更新固件,linux内核崩溃后的内存信息查看等。

u-boot启动Linux大概过程

u-boot的详细运行代码这里不做分析。u-boot中有两个关键的环境变量,bootcmd和bootargs。bootcmd是自动启动时默认执行的一些命令。针对不同的Linux镜像,有不同的跳转语句。zImage使用的go addr,uImage使用的是bootm addr。bootargs则是u-boot要传递给Linux的参数集合。在u-boot阶段可以用过输入回车打断,然后输入一些指令对环境进行一些操作。首先以两条典型的u-boot下的指令进行分析

1
setenv bootargs 'mem=64M console=ttyAMA0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 mtdparts=hi_sfc:768K(Uboot),1728K(kernel),13888K(rootfs)';setenv bootcmd 'sf probe 0;sf read 0x82000000 0xC0000 0x1B0000;bootm 0x82000000';saveenv;reset

printenv, setenv and saveenv

这三条分别是打印环境变量,设置环境变量,保存环境变量。

reset

重启设备

root

通过root可以指定rootfs的位置,根据情况,如果是flash一类的块设备,一般是root=/dev/mtdblock rw,处的数字根据实际rootfs存放位置来定,rw则表示这个分区是可读可写的,如果是ro则是只读。

rootfstype

指定rootfs的文件系统格式,比如可以jffs2,或者cramfs

mtdparts

mtd分区信息,包括分区大小和分区名字,如果你想添加新的自定义分区那就需要同时在这里添加对应的分区信息,u-boot将这些参数传给linux内核后,内核才能知晓新的分区。

mem

表示Linux可用的RAM大小。为什么说是Linux可用呢,如果是Hi3516这样的片子,需要将部分内存提供给MPP(Media Process Platform)子系统来使用,在这里,虽然用的是128MB的RAM,但是提供给Linux的是64M,剩余64M是给MPP的。这个数字是可调的,保证总和不超过实际RAM大小即可。

console

指定串口控制台通过哪个串口设备进行交互,以及通信波特率。

sf probe 0

表示切换到spi flash 0 进行操作

sf read 0x82000000 0xC0000 0x1B0000

从flash地址0x1B0000处读取长度为0xC0000字节的内容到RAM的0x82000000处。

bootm 0x82000000

从RAM的0x82000000处运行linux。
u-boot启动完成之后会调用环境变量bootcmd中的指令去启动Linux内核。

固化启动参数

上述方法是在现场调试时设置用的,如果我们需要应用在产品中,就需要提前固化好启动参数。跟踪一下u-boot的代码,发现在hi3516cv300.h里面有如下相关的宏定义:

1
2
3
#define CONFIG_BOOTCOMMAND	"sf probe 0;sf read 0x82000000 0xC0000 0x1E0000;bootm 0x82000000"
#define CONFIG_BOOTDELAY 1
#define CONFIG_BOOTARGS "mem=64M console=ttyAMA0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 mtdparts=hi_sfc:768K(Uboot),1920K(kernel),13184K(rootfs),512K(config)"

我们将其修改成所需的参数即可