uboot 使用
uboot 简介
uboot(Universal Boot Loader) 是一个综合的裸机程序。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。
uboot 最主要的工作是初始化 DDR,linux 是运行在 DDR 里的。因此在启动 linux 内核前,就要初始化完成 DDR。对于 6u 芯片,DDR 的初始化代码在芯片 rom 中。因此在 imx 系列芯片,uboot 的代码并不需要去初始化 DDR。但是大部分的芯片都需要在 uboot 中去初始化 DDR。
linux 镜像(zImage, uImage)和设备树(*.dtb)存放在 EMMC,NAND,Flash等,因此系统要想运行,还需要把代码从持久化存储设备中复制到RAM中,因此 uboot 还需要初始化完成这些设备。
uboot 会做为了linux系统启动需要准备的所有东西,启动后,uboot就消失了。操作系统接手后面的事情。
uboot 本身是个通用的 bootloader,支持不同的板子、不同的操作系统。
不同的板子外设不同,使用时先要配置成我们需要的样子,然后编译成和板子匹配的可执行文件,一般是 uboot.bin,对于 i.mx 芯片,还要加上ivt dcd 等,就可以正常启动了。
系统启动时,会输出各种信息,属于 uboot 阶段的:
U-Boot 2020.10-g92bbb671 (Feb 10 2022 - 02:36:31 +0000)
CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 41C
Reset cause: POR
Model: Freescale i.MX6 UltraLiteLite 14x14 EVK Board
Board: MX6ULL 14x14 EVK
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In: serial
Out: serial
Err: serial
Net: eth1: ethernet@20b4000 [PRIME]Could not get PHY for FEC0: addr 2
Hit any key to stop autoboot: 0
Unknown command 'lhf' - try 'help'
switch to partitions #0, OK
mmc1(part 0) is current device
loading [mmc 1:1] /uEnv.txt ...
2584 bytes read in 13 ms (193.4 KiB/s)
Importing environment from mmc ...
loading vmlinuz-4.19.35-imx6 ...
10138912 bytes read in 459 ms (21.1 MiB/s)
loading imx6ull-mmc-npi.dtb ...
38529 bytes read in 69 ms (544.9 KiB/s)
5164702 bytes read in 242 ms (20.4 MiB/s)
debug: [console=ttymxc0 root=/dev/mmcblk1p2 rw rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 vt.global_cursor_default=0] ...
debug: [bootz] ...
Kernel image @ 0x80800000 [ 0x000000 - 0x9ab520 ]
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 83000000, end 8303cfff
Starting kernel ...源码编译
编译工具链
对于 fish 这个 shell,在 ~/.config/fish/config.fish 中保存了配置文件,每次启动时都会执行。等同 ~/.bashrc
将工具链路径添加到环境变量
source code 在哪里?
uboot 的源码
u-boot 项目
支具体的某款芯片的驱动不完善,但是不断有人会贡献代码,修复bug
芯片厂商适配的 uboot
芯片厂商会基于某个版本的 uboot,深度适配自己的 evk 评估板,如 i.mx6ull evk 板
二级开发板厂商的 uboot
如野火、正点原子、飞凌等公司开发板的 uboot
开发板厂商会参考芯片厂商的 evk ,定制自己的开发板,在芯片厂商 uboot 的基础上适配开发板的功能
所以 uboot 移植,实际上是适配自己的板子,真正的最复杂的移植部分厂商的工程师已经解决掉了。
对于 nxp imx6ull 这个芯片,uboot 源码里由这个配置。
源码编译
不论是从哪里得到的源码,编译过程:
编译 uboot 需要的一些额外的工具
工程清理。
ARCH=arm设置目标为 arm 架构,CROSS_COMPILE指定所使用的交叉编译器。第一条命令相当于“make distclean”,清除工程配置 uboot。
make mx6ull_14x14_ddr512_emmc_defconfig,使用默认配置文件,把配置项写到.config里编译。最后一条指令相当于
make -j12也就是使用 12 核来编译 uboot,V=1输出中间信息
makefile 里要判断架构,相当于传入参数里设置了架构。以及使用的交叉编译器。
可以直接在 makefile 里定义 ARCH 和 CROSS_COMPILE 两个变量,这样以后在输命令的时候会快一点。
编译完成后,会出来一些文件。
uboot.bin编译完成无法启动,需要添加其他信息(imx系列)。这里从编译信息可以看到最后一步
这里能看出用了 tools 里的 mkimage 这个工具完成的。最终可以用的是 u-boot.imx,这个文件可以使用 NXP 官方的 mfgtools 来烧写。
uboot 烧录
USB-OTG 烧写用到的工具是 mfgtools,
firmware 先下载到 DDR 里的中间系统
files 最终下载到 mmc 里的系统。
想要烧写替换成自己的文件即可。用这个东西烧写会重新烧录所有东西进去,烧写完成设置 emmc 启动,在此启动就能看到编译编译时间。
想要方便一点可以用读卡器烧写到 SD 卡,对于 uboot 来说,自己手动在 uboot.bin 前加上 IVT 和 DCD,(imxdownload 工具源码使用 C 语言实现)。
imxdownload 编译成可执行文件后,可以将路径添加在环境变量,方便 flash 命令的使用。~/.config/fish/config.fish 里加一条命令
SD 卡连接到 ubuntu 虚拟机,可以使用 lsblk 查看块设备,或者在 ls /dev/sd* 看到多出来的 SD 卡设备。
烧写指令
flash u-boot.bin /dev/sdb
自动化脚本
再精简一下整个流程。
通过图形化界面配置后,就不可以 distclean 了。
此外,还可以直接给 Makefile 里的传入的变量赋值,就不用每次输这么多指令了。
make : 自动化编译工具
git : 版本管理工具
gcc-arm-none-eabi : 交叉编译的工具链
gcc : 本地编译的工具链
bison :
为了方便,学习 uboot 期间可以把 uboot 烧到 SD 卡中启动。
SD 卡插到 imxdownload 中,和裸机下载程序一样。比较方便。
u-boot 命令使用
基本信息
helphelp [具体命令]bdinfoprintenvversion
含义
boot 参数存放地址 0x80000100
DDR 的起始地址 0x80000000
有的板子会配置成两个 bank,两个不连续的地址空间
串口波特率
各种地址,先不关注
环境变量操作
printenv有很多。关注 bootcmd 和 bootargs
setenv/saveenv
设置环境变量
比如设置boot延时时间。
setenv bootdelay 5saveenv
对于比较长的环境变量,带空格的,要加上字符串引用
setenv bootcmd 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
设置一个控制台串口,以及挂载根文件系统的设备。
新建一个没有的环境变量也用此命令
setenv xymenv xym
删除环境变量,即给环境变量一个空的值
setenv xymenv
内存操作
具体的操作,可以看 uboot 中的帮助
mdnmmmmwcpcmp
md(memory display)
查看指定位置的内存值
md[.b .w .l] {address} {length}md.b 80000000 64md.w 80000000 128md.l 80000000 256
nm()
修改指定位置的值
nm[.b .w .l] {address}nm.b 80000000nm.w 80000000nm.l 80000000
可以多次修改,按 q 退出。
mm(memory modify (auto-incrementing address))
mw(memory write (fill))
mw[.b .w .l] {address} {value} {count}
cp
cp[.b .w .l] {source} {target} {count}
DRAM 中复制,或者NOR FLASH向DRAM复制。
网络操作
在网络操作前,先要联网,用环境变量设置一些信息
pingnfs
主要是从网络上下载文件到 DRAM 中。如编译好的 linux 内核加载到 RAM 的 0x80800000 上
nfs 80800000 192.168.1.201:/home/xym/ws_linux/kernel/zImage
mmc sd 卡操作
mmc list列出可选的 mmc 设备
mmc rescan扫描mmc设备
mmc dev 1切换设备1
如果切换设备1的分区2
mmc dev 1 2
mmc info查看设备信息
mmc part查看分区情况
分区0,存放uboot,未格式化,所以看不到
分区1,存放 linux 镜像和设备树
分区2,存放根文件系统
mmc read addr blk# cnt按块读取到 DRAM 中
mmc dev 1 0mmc read 80800000 600 10
FAT 文件系统操作
fatinfo
fatls
fstype
fatload
fatwrite
ext4 文件系统操作
指令类似
boot 操作
最核心的功能。
bootzbootmboot
启动 linux 核前,先要将镜像加载到 DDR 中,如果用到设备树的话也要加载到 DDR 中。
可以从 EMMC、NAND、中复制到 DDR 中,也可以通过 nfs、tftp 复制到 DDR 中。最终只要 DDR 中有这些东西就行。
bootz 用来启动 zImage,命令格式
bootz [addr [initrd[:size]] [fdt]]addr: 镜像在 DDR 中的地址
initrd: initrd文件在 DDR 中的地址,不使用的话用
-代替fdt: 设备树在 DRAM 中的地址
nfs 网络启动
mmc 启动
bootm 和 bootz 类似。
boot 命令会读取环境变量 bootcmd 来启动系统。即启动命令的集合。
uboot 倒计时结束,执行的就是 bootcmd 中的启动命令。
这时候在启动内核时会遇到下面的错误
其他常用命令
reset复位
go跳转指定地址执行
go addr [arg...]
runmtest
go 命令,可以编译裸机程序,然后 nfs 挂载到 DDR 中,使用此命令运行。uboot 初始化好了 IVT 等,直接就能运行。
run 用来运行定义在环境变量中的命令。如 run bootcmd
最后更新于
这有帮助吗?