目录
1.U-Boot 简介
Linux
系统要启动就必须需要一个
bootloader
程序,也就说芯片上电以后先运行一段
bootloader
程序。
这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,
NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核
。当然了,
bootloader
的实
际工作要复杂的多,但是它
最主要的工作就是启动 Linux 内核
,
bootloader
和
Linux
内核的关系
就跟
PC
上的
BIOS
和
Windows
的关系一样,
bootloader
就相当于
BIOS
。所以我们要先搞定
bootloader
,很庆幸,有很多现成的
bootloader
软件可以使用,比如
U-Boot
、
vivi
、
RedBoot
等
等,其中以
U-Boot
使用最为广泛,为了方便书写,本书会将
U-Boot
写为
uboot
。
uboot
的全称是
Universal Boot Loader
,
uboot
是一个遵循
GPL
协议的开源软件,
uboot
是一
个
裸机代码
,可以看作是一个
裸机综合例程
。现在的
uboot
已经支持液晶屏、网络、
USB
等高
级功能。
uboot
官网为
http://www.denx.de/wiki/U-Boot/。
但是我们一般不
会直接用
uboot
官方的
U-Boot
源码的。
uboot
官方的
uboot
源码是给半导体厂商准备的,半导
体厂商会下载
uboot
官方的
uboot
源码,然后将自家相应的芯片移植进去。也就是说半导体厂
商会自己维护一个版本的
uboot
,这个版本的
uboot
相当于是他们定制的。既然是定制的,那么
肯定对自家的芯片支持会很全,虽然
uboot
官网的源码中一般也会支持他们的芯片,但是绝对
是没有半导体厂商自己维护的
uboot
全面。
那么这三种
uboot
该如何选择呢?首先
uboot
官方的基本是不会用的,因为支持太弱了。
最常用的就是半导体厂商或者开发板厂商的
uboot
,如果你用的半导体厂商的评估板,那么就使
用半导体厂商的
uboot
,如果你是购买的第三方开发板,比如正点原子的
I.MX6ULL
开发板,
那么就使用正点原子提供的
uboot
源码(也是在半导体厂商的
uboot
上修改的)。当然了,你也
可以在购买了第三方开发板以后使用半导体厂商提供的
uboot
,只不过有些外设驱动可能不支
持,需要自己移植,这个就是我们常说的
uboot
移植。
2.U-Boot编译
解压源码压缩包编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
这三条命令中
ARCH=arm
设置目标为
arm
架构,
CROSS_COMPILE
指定所使用的交叉编
译器。第一条命令相当于“
make distclean
”,目的是清除工程,一般在第一次编译的时候最好清
理一下工程。第二条指令相当于“
make mx6ull_14x14_ddr512_emmc_defconfig
”,用于配置
uboot
, 配置文件为 mx6ull_14x14_ddr512_emmc_defconfig
。最后一条指令相当于 “
make -j12
”也就是 使用 12
核来编译
uboot
。当这三条命令执行完以后
uboot
也就编译成功了。
编译完成以后
uboot
源码多了一些文件,其中
u-boot.bin
就是编译出来的
uboot 二进制文件。uboot
是个裸机程序,因此需要在其前面加上头部
(IVT
、
DCD
等数据
)
才能在
I.MX6U 上执行,图 30.2.4
中的
u-boot.imx
文件就是添加头部以后的
u-boot.bin
,
u-boot.imx
就是我们最
终要烧写到开发板中的
uboot
镜像文件。
U-Boot烧写
chmod 777 imxdownload //给予 imxdownload 可执行权限,一次即可
./imxdownload u-boot.bin /dev/sdd //烧写到 SD 卡,不能烧写到/dev/sda 或 sda1 设备里面!
U-Boot更新
sd卡更新
mmc dev 0
tftp 80800000 u-boot.imx
mmc dev 0 0
mmc write 80800000 3 32E
emmc更新
mmc dev 1 0 //切换到 EMMC 分区 0
tftp 80800000 u-boot.imx //下载 u-boot.imx 到 DRAM
mmc write 80800000 2 32E //烧写 u-boot.imx 到 EMMC 中
mmc partconf 1 1 0 0 //分区配置,EMMC 需要这一步!
千万不要写
SD
卡或者
EMMC
的前两个块
(
扇区
)
,里面保存着分区表!
FAT 格式文件系统操作命令
fatload 命令
fatload 命令用于将指定的文件读取到 DRAM 中,命令格式如下:
fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
interface
为接口,比如
mmc
,
dev
是设备号,
part
是分区,
addr
是保存在
DRAM
中的起始
地址,
filename
是要读取的文件名字。
bytes
表示读取多少字节的数据,如果
bytes
为
0
或者省
略的话表示读取整个文件。
pos
是要读的文件相对于文件首地址的偏移,如果为
0
或者省略的
话表示从文件首地址开始读取。我们将
EMMC
分区
1
中的
zImage
文件读取到
DRAM
中的
0X80800000
地址处,命令如下:
fatload mmc 1:1 80800000 zImage
fatwrite 命令
注意!
uboot
默认没有使能
fatwrite
命令,需要修改板子配置头文件,比如
mx6ullevk.h
、
mx6ull_alientek_emmc.h
等等,板子不同,其配置头文件也不同。找到自己开发板对应的配置头
文件然后添加如下一行宏定义来使能
fatwrite
命令:
#define CONFIG_FAT_WRITE /* 使能 fatwrite 命令 */
fatwirte
命令用于将
DRAM
中的数据写入到
MMC
设备中,命令格式如下:
fatwrite <interface> <dev[:part]> <addr> <filename> <bytes>
interface
为接口,比如
mmc
,
dev
是设备号,
part
是分区,
addr
是要写入的数据在
DRAM
中的起始地址,
filename
是写入的数据文件名字,
bytes
表示要写入多少字节的数据。我们可以
通过
fatwrite 命令在 uboot 中更新 linux 镜像文件和设备树
。我们以更新
linux
镜像文件
zImage
为例
tftp 80800000 zImage
fatwrite mmc 1:1 80800000 zImage 6788f8
EXT
格式文件系统操作命令
同FAT 格式文件系统操作命令一致
BOOT 操作命令
bootz
uboot
的本质工作是引导
Linux
,所以
uboot
肯定有相关的
boot(
引导
)
命令来启动
Linux
。常
用的跟
boot
有关的命令有:
bootz、bootm 和 boot
。
要启动
Linux
,需要先将
Linux
镜像文件拷贝到
DRAM
中,如果使用到设备树的话也需要
将设备树拷贝到
DRAM
中。可以从
EMMC
或者
NAND
等存储设备中将
Linux
镜像和设备树文
件拷贝到
DRAM
,也可以通过
nfs
或者
tftp
将
Linux
镜像文件和设备树文件下载到
DRAM
中。
不管用那种方法,只要能将
Linux
镜像和设备树文件存到
DRAM
中就行,然后使用
bootz
命令
来启动,
bootz 命令用于启动 zImage 镜像文件
,
bootz
命令格式如下
bootz [addr [initrd[:size]] [fdt]]
命令
bootz
有三个参数,
addr
是
Linux
镜像文件在
DRAM
中的位置,
initrd
是
initrd
文件在
DRAM
中的地址,如果不使用
initrd
的话使用‘
-
’代替即可,
fdt
就是设备树文件在
DRAM
中
的地址。
网络启动
chmod 777 imx6ull-14x14-emmc-7-1024x600-c.dtb
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
bootz 80800000 - 83000000
EMMC启动
fatload mmc 1:1 80800000 zImage
fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
bootz 80800000 - 83000000
bootm 命令
bootm
和
bootz
功能类似,但是
bootm
用于启动
uImage
镜像文件。如果不使用设备树的话
启动
Linux
内核的命令如下:
bootm addr
addr
是
uImage
镜像在
DRAM
中的首地址。
如果要使用设备树,那么
bootm
命令和
bootz
一样,命令格式如下:
bootm [addr [initrd[:size]] [fdt]]
其中
addr
是
uImage
在
DRAM
中的首地址,
initrd
是
initrd
的地址,
fdt
是设备树
(.dtb)
文件
在
DRAM
中的首地址,如果
initrd
为空的话,同样是用“
-
”来替代
boot 命令
boot
命令也是用来启动
Linux
系统的,只是
boot
会读取环境变量
bootcmd
来启动
Linux
系
统,
bootcmd
是一个很重要的环境变量!其名字分为“
boot
”和“
cmd
”,也就是“引导”和“命
令”,说明这个环境变量保存着引导命令,其实就是启动的命令集合,具体的引导命令内容是可
以修改的。比如我们要想使用
tftp
命令从
网络启动
Linux
那么就可以设置
bootcmd
为“
tftp
80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 -
83000000
”,然后使用
saveenv
将
bootcmd
保存起来。然后直接输入
boot
命令即可从网络启动
Linux
系统,命令如下:
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb;
bootz 80800000 - 83000000'
saveenv
boot
如果想从
EMMC 启动
那就设置
bootcmd
为“
fatload mmc 1:1 80800000 zImage; fatload mmc
1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000
”,然后使用
boot
命令启动即可,命令如下:
setenv bootcmd 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-14x14-
emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000'
savenev
boot
其他常用命令
比如
reset
、
go
、
run
和
mtest
等。
run
命令用于运行环境变量中定义的命令,比如可以通过“
run bootcmd
”来运行
bootcmd
中
的启动命令,但是
run 命令最大的作用在于运行我们自定义的环境变量
。在后面调试
Linux
系
统的时候常常要在网络启动和
EMMC/NAND
启动之间来回切换,而
bootcmd
只能保存一种启
动方式,如果要换另外一种启动方式的话就得重写
bootcmd
,会很麻烦。这里我们就可以通过
自定义环境变量来实现不同的启动方式,比如定义环境变量
mybootemmc
表示从
emmc
启动,
定义
mybootnet
表示从网络启动,定义
mybootnand
表示从
NAND
启动。如果要切换启动方式
的话只需要运行“
run mybootxxx(xxx
为
emmc
、
net
或
nand)
”即可。
setenv mybootemmc 'fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-
14x14-emmc-7-1024x600-c.dtb;bootz 80800000 - 83000000'
setenv mybootnand 'nand read 80800000 4000000 800000;nand read 83000000 6000000
100000;bootz 80800000 - 83000000'
setenv mybootnet 'tftp 80800000 zImage; tftp 83000000imx6ull-14x14-emmc-7-1024x600-c.dtb;
bootz 80800000 - 83000000'
saveenv
run mybootemmc
或
run mytoobnand
或
run mybootnet
mtest
命令是一个简单的内存读写测试命令