【北京迅为】i.MX6ULL终结者Uboot编译及移植U-Boot介绍

1 u-boot的使用

uboot是一段裸机代码,它的实现非常复杂,主要是初始化一些硬件,部署整个计算机系统,将内核读到内存,根据环境变量去启动内核,并向内核传递参数。它的目标就是启动内核,内核启动后它的生命也随之结束。
u-boot是SourceForge上的开源项目,由一个人发起,然后由整个世界所有感兴趣的人共同维护发展而来的一个bootloader,bootloader是用来引导和加载内核,向内核传递参数的,是内核引导程序的统称,bootloader除了u-boot还有bios,LilO,redboot,vivi等。

1.1 环境变量

在uboot命令行输入printenv,打印出环境变量(使用的 NAND flash版本):
在这里插入图片描述

图 1.1.1

1.baudrate=115200,波特率为115200。
2.bootargs=console=ttymxc0,115200 root=ubi0:rootfs rootfstype=ubifs ubi.mtd=5 mtdparts=gpmi-nand:4m(u-boot),2m(-boot-env),4m(logo),10m(kernel),2m(dtb),-(rootfs) rootwait rw
参数说明:.bootargs后面的变量是传递给linux内核的参数,主要用来告诉内核启动信息,分区信息和根文件系统所在的分区,console=ttymxc0代表串口节点ttymxc0实现内核和PC的交互。波特率是115200,root=ubi0:rootfs文件系统的名字叫做rootfs,分区依次是uboot,uboot环境变量,开机logo,内核,设备树,文件系统。进入内核可以在/proc/mtd看到分区信息:
在这里插入图片描述

图 1.1.2

通过bootargs可以设置文件系统的挂载方式,可以挂载flash中的根文件系统,还可以通过NFS挂载网络文件系统。
3.bootcmd=nand read ${loadaddr} 0xa00000 0xa00000; nand read ${fdt_addr} 0x144B000 0xc800;bootz ${loadaddr} - ${fdt_addr}
bootcmd后面是系统自启动参数,在启动参数由一些uboot命令组成,在倒计时结束后uboot会依次执行设置好的命令,
NAND read ${loadaddr} 0xa00000 0xa00000:将nand flash的偏移地址0xa00000开始,读大小为0xa00000的内核镜像到内存的开始地址为loadaddr处,loadaddr为0x80800000,如图 1.1.3。
在这里插入图片描述

图 1.1.3

nand read ${fdt_addr} 0x144B000 0xc800:将设备树从flash的偏移地址0x144B000读0xC800大小到内存的fdt_addr处,fdt_addr为0x83000000

在这里插入图片描述

图 1.1.4

然后从内存的{loadaddr}读取Linux内核,从{fdt_addr}读设备树。
在这里插入图片描述

图 1.1.5

可以看出最后内核是从内存中启动的,我们可以从flash中获取内核,也可以用tftp服务从网络中下载内核,最后在内存中启动。
4.bootdelay=3代表uboot启动后倒计时的秒数。
5.此外还有网络相关的环境变量,比如服务器地址serverip,网关gatewayip,开发板IP ipaddr,子网掩码netmask等,设置了这些参数才能使用tftp服务。
关于uboot的环境变量还有很多,这里只列出了常用的几个,还可以根据需要自定义环境变量。

1.2 常用命令

进入uboot命令行,输入help查看帮助信息,会弹出很多命令和介绍:
在这里插入图片描述

图 1.2.1

U-Boot的命令有很多,而且还可以自定义进行添加,下面介绍常用的几个。
1.printenv:查看环境变量:
2.setenv:修改环境变量:setenv 环境变量名 环境变量值
删除环境变量:setenv 环境变量名
例如设置自启动倒计时环境变量bootdelay,设置前为3秒:
在这里插入图片描述

图 1.2.2

输入命令setenv bootdelay 10,
然后输入printenv查看环境变量,发现环境变量已经改变。但是重新启动后新设置的环境失效,这是因为环境变量没有保存到flash。
在这里插入图片描述

图 1.2.3

3.保存环境变量: saveenv,将环境变量保存到flash,重启后依然存在。
4.启动内核:boot,按照环境变量bootcmd启动内核。
在这里插入图片描述

图 1.2.4

5.重新启动:reset。
6.nand命令介绍:
nand info :查看nand 信息
nand read addr offset count:读命令;
nand erase:擦除整片NAND;
nand erase offset count:擦除指定NAND指定的区域;
nand write addr offset count:将内存的数据写到NAND指定区域;
addr是内存基地址,offset是 NAND的偏移地址,count是写入字节数。
7.eMMC命令,
mmc info:打印mmc的信息,
mmc list :查看mmc设备,
mmc read addr blk# cnt:从eMMC读cnt个块数据到内存addr处;
mmc write addr blk# cnt:把内存addr处的cnt个块数据写到eMMC。
mmc erase blk# cnt:擦除blk#开始的cnt个数据块
addr为内存地址,blk#是mmc的块号,cnt是设备块的个数,块的单位是512字节。

8.网络相关命令
uboot使用网络相关命令要保证网卡能正常使用(此例程使用的uboot在网盘:终结者ULL光盘资料\i.MX6ULL终结者光盘资料\08_开发板系统镜像\01_Uboot\02_NAND FLASH核心板\u-boot.imx),启动后能够识别出网卡:
在这里插入图片描述

图 1.2.5

发现下方显示“Error: FEC1 address not set.”,这是因为没有设置MAC地址,输入命令setenv ethaddr 73:70:F4:E6:36:EA设置以太网物理地址,saveenv保存。
设置开发板IP地址:setenv ipaddr 192.168.1.120
设置服务器的IP地址(Ubuntu):setenv serverip 192.168.1.12
设置网关:setenv gatewayip 192.168.1.1
设置子网掩码:setenv netmask 255.255.255.0
这些环境变量要根据实际情况设置,设置好后测试与主机(Ubuntu)的网络连接:ping 192.168.1.12:
在这里插入图片描述

图 1.2.6

出现“host ***** is alive”即为设置成功。
9.tftp下载命令: tftp addr file,网络设置好了以后可以使用tftp命令从tftp服务器端下载镜像到内存,addr为内存地址,file为服务器端的文件,具体使用方法可参照”tftp下载和nfs网络启动”相关章节。
10.bootm -引导uImage镜像启动
11.bootz -从内存启动Linux镜像和设备
12.ping - 测试与主机的网络连接
13.loadb -通过串口Kermit协议下载二进制数据到内存指定位置。
14.loady 通过串口线下载文件到内存
15.go -跳转到内存地址处,运行程序
16.env default -a -重置环境变量。
17.run:可以执行环境变量中的命令,如输入“run bootcmd”启动内核
18.ls [<dev[:part]> [directory]]:uboot下查看文件系统结构(使用的emmc版本):
ls mmc 1:1,查看分区1:
在这里插入图片描述

图 1.2.7

ls mmc 1:2,查看分区2文件系统目录
在这里插入图片描述

图 1.2.8

ls mmc 1:2 etc,查看目录包含信息:
在这里插入图片描述

图 1.2.9

2 获取u-boot

2.1 获取源码

U-boot源码可以从官网ftp://ftp.denx.de/pub/u-boot/获取(后缀有rcx表示测试版本),但是有的芯片厂家没有把修改过的源码开源到官网中,所以有些芯片的u-boot不能直接从网站获取。NXP官方也是用的此网站的2016.03版本u-boot,他们在源码里加入自己的东西,且一直在维护此版本,本文档将使用NXP移植好的源码编译u-boot。
我们已经下载好了 NXP提供的源码,源码压缩包放在了网盘中(终结者ULL光盘资料\i.MX6ULL终结者光盘资料\05_uboot linux源码\目录下\uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2),拷贝到Ubuntu下解压。
解压:tar -jxvf uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
在这里插入图片描述

图 2.1.1

修改目录名为uboot:mv uboot-imx-rel_imx_4.1.15_2.1.0_ga uboot -f
进入解压后的目录uboot-imx-rel_imx_4.1.15_2.1.0_ga,查看README文档,里面详细介绍了源码从哪下载
在这里插入图片描述

图 2.1.2

还有如何配置到自己的处理器上(如下图),这些操作NXP已经做好了,
在这里插入图片描述

图 2.1.3

在这里插入图片描述

图 2.1.4

2.2 目录介绍

接下来分析源码目录里几个重要的文件夹和文件
与平台架构直接相关的文件夹:
/arch 不同架构芯片使用的文件,如PowerPC,ARM,x86,MIPS等。
我们只关心/arch/arm下的文件
在这里插入图片描述

图 2.2.1

/api 存放接口函数
/board 板级相关文件,主要包含一些驱动程序。
/board/freescale /我们的目标板在此目录下操作。
在这里插入图片描述

图 2.2.2

/configs 板子默认配置文件,移植过程中需要用到此目录
在这里插入图片描述

图 2.2.3

/fs 文件系统(cramfs, ext2, jffs2, etc.)
还有包含不同架构处理器通用的驱动程序或函数的文件夹:
/common 通用架构使用的代码,主要处理命令行,检测内存大小和故障。
/disk 磁盘分区代码。
/lib 通用库文件。
/net 网络相关代码,如网络协议栈,TFTP,NFS等功能。
/post 上电自检代码。
/drivers 驱动代码。
还有存放uboot说明文档,工具的文件夹:
/doc 纯英文文档。
/examples 例程.。
/include 存放着头文件。
include/configs/目录下包含着我们需要的头文件。
在这里插入图片描述

图 2.2.4

/scripts 存放脚本和生成文件。
/tools 工具,检查生成的目标文件。
重要文件:
Makefile:管理整个工程。
Kconfig:图形化配置界面的管理工具。
u-boot.imx:u-boot镜像,用mfgtools烧录工具烧写到开发板。
u-boot.lds:链接脚本。在这里插入图片描述