参考链接:https://blog.csdn.net/qq_46079439/article/details/125474461
uboot 属于bootloader的一种,是用来引导启动内核的,它的最终目的就是:从flash中读出内核,放到内存中,启动内核。
它刚开始被放到flash上,然后上电以后先执行它,它会完成硬件初始化,设置处理器模式,关闭看门狗,屏蔽中断,初始化sdram,设置栈,设置时钟,从flash引导内核到内存,就好像我们PC上的BIOS一样。最终将系统的软硬件带到一个合适的状态。
直接使用help或“?”可以查看当前uboot支持的命令
使用 help +其他命令可以查看命令的使用说明
=> bdinfo
arch_number = 0x00000000 # 架构的编号
boot_params = 0x80000100 # boot参数的地址
DRAM bank = 0x00000000
-> start = 0x80000000 # DDR起始地址
-> size = 0x20000000 # DDR大小==>512M
eth0name = FEC1 # 网卡名字
ethaddr = (not set) # 网卡地址(目前未设置)
current eth = FEC1 # 当前使用的网卡名称
ip_addr = # ip地址
baudrate = 115200 bps # 波特率
TLB addr = 0x9FFF0000
relocaddr = 0x9FF56000
reloc off = 0x18756000
irq_sp = 0x9EF53EA0
sp start = 0x9EF53E90
=> printenv
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
环境变量如果不存在,则自动创建,存在则修改替换
设置完环境变量记得保存!!
设置简单环境变量:
=> setenv bootdelay 5
=>
设置字符串形式的环境变量,记得用单引号(所见即所得)括起来
=> setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
=>
删除环境变量,直接设置某个值为空,如:
=> setenv aaaa
=>
=> saveenv
Saving Environment to MMC...
Writing to MMC(1)... done
=>
命令格式:
md[.b, .w, .l] address [# of objects]
命令中的[.b .w .l]对应 byte、word 和long,也就是分别以 1 个字节、2 个字节、4 个字节
如查看以0X80000000开始的20个字节的内存值,显示格式为.b(20的16进制是0x14)
=> md.b 80000000 14
80000000: 1a 01 2c 00 26 00 07 00 0e 01 22 02 76 74 31 30 ..,.&.....".vt10
80000010: 30 7c 76 74 0|vt
=>
md.w操作:
=> md.w 80000000 25
80000000: 011a 002c 0026 0007 010e 0222 7476 3031 ..,.&.....".vt10
80000010: 7c30 7476 3031 2d30 6d61 647c 6365 7620 0|vt100-am|dec v
80000020: 3174 3030 2820 2f77 6461 6176 636e 6465 t100 (w/advanced
80000030: 7620 6469 6f65 0029 0100 0000 0001 0000 video).........
80000040: 0000 0000 0000 0001 0000 ..........
=>
命令格式:
nm [.b, .w, .l] address
如修改地址 80000000 的内容为 11111112,
它会先读取地址里面原来的内容,在?后面修改新值,输入q退出修改
=> nm.l 80000000
80000000: 002c011a ? 11111112
80000000: 11111112 ? q
=>
=> mm.l 80000000
80000000: 11111111 ? 11111111 # 修改为11111111
80000004: 00070026 ? 22222222 # 修改为22222222
80000008: 0222010e ? 33333333 # 修改为33333333
8000000c: 30317476 ? q # 退出
=>
验证:
=> md.l 80000000 3
80000000: 11111111 22222222 33333333 ....""""3333
=>
命令格式:
mw [.b, .w, .l] address value [count]
如将 80000000 地址后面的10个l长度都修改为ffffffff
=> mw.l 80000000 ffffffff 10
验证:
=> md.l 80000000 10
80000000: ffffffff ffffffff ffffffff ffffffff ................
80000010: ffffffff ffffffff ffffffff ffffffff ................
80000020: ffffffff ffffffff ffffffff ffffffff ................
80000030: ffffffff ffffffff ffffffff ffffffff ................
=>
将 DRAM 中的数据从一段内存拷贝到另一段内存中,或者把NorFlash 中的数据拷贝到DRAM 中
命令格式:
cp [.b, .w, .l] source target count #从哪里到哪里,多长
现在 80000000 ~ 8000003f 都是 ffffffff,将其拷贝到80000040 ~ 8000007f
=> md.l 80000000 20
80000000: ffffffff ffffffff ffffffff ffffffff ................
80000010: ffffffff ffffffff ffffffff ffffffff ................
80000020: ffffffff ffffffff ffffffff ffffffff ................
80000030: ffffffff ffffffff ffffffff ffffffff ................
80000040: 00000000 00010000 00000000 00010001 ................
80000050: 00000000 00000000 00000000 00500100 ..............P.
80000060: 00180008 ffffffff 0003ffff 0000ffff ................
80000070: 00040002 001a0015 002e0026 ffffffff ........&.......
=>
=> cp.l 80000000 80000040 10
=>
验证:80000000 ~ 8000007f都是 ffffffff
=> md.l 80000000 20
80000000: ffffffff ffffffff ffffffff ffffffff ................
80000010: ffffffff ffffffff ffffffff ffffffff ................
80000020: ffffffff ffffffff ffffffff ffffffff ................
80000030: ffffffff ffffffff ffffffff ffffffff ................
80000040: ffffffff ffffffff ffffffff ffffffff ................
80000050: ffffffff ffffffff ffffffff ffffffff ................
80000060: ffffffff ffffffff ffffffff ffffffff ................
80000070: ffffffff ffffffff ffffffff ffffffff ................
=>
cmp 是比较命令,用于比较两段内存的数据是否相等
命令格式
cmp [.b, .w, .l] addr1 addr2 count
=> md.l 80000000 2
80000000: ffffffff ffffffff ........
=> cmp.l 80000000 80000004 1
Total of 1 word(s) were the same
uboot 是支持网络的,我们在移植 uboot 的时候一般都要调通网络功能,因为在移植 linux kernel 的时候需要使用到uboot 的网络功能做调试。
在测试前一定需要设置ethaddr(网卡地址),地址自己瞎写一个吧
=> setenv ethaddr 00:11:22:33:44:55
=> saveenv
Saving Environment to MMC...
Writing to MMC(1)... done
=>
=> dhcp
BOOTP broadcast 1
*** Unhandled DHCP Option in OFFER/ACK: 213
DHCP client bound to address 192.168.3.22 (48 ms)
*** Warning: no boot file name; using 'C0A80316.img'
Using FEC1 device
TFTP from server 0.0.0.0; our IP address is 192.168.3.22; sending through gateway 192.168.3.1
Filename 'C0A80316.img'.
Load address: 0x80800000
Loading: T T T T T T T T T T
Retry count exceeded; starting again
=>
测试存在的IP地址
=> ping 192.168.3.1
Using FEC1 device
host 192.168.3.1 is alive
=>
测试不存在的IP地址
=> ping 192.168.3.100
Using FEC1 device
ARP Retry count exceeded; starting again
ping failed; host 192.168.3.100 is not alive
=>
前提是先配置nfs服务器
命令格式:
nfs [loadAddress] [[hostIPaddr:]bootfilename]
loadAddress 是要保存的 DRAM 地址,[[hostIPaddr:]bootfilename]是要下载的文件地址。
如将文件下载到 80800000 地址:
nfs 80800000 192.168.2.25:/home/fourth/linux/nfs/zImage
安装:
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
设置共享位置并授权:
mkdir /home/fourth/linux/tftpboot
chmod 777 /home/fourth/linux/tftpboot
要共享的文件也要设置权限
chmod 777 zImage
修改tftp配置
vim /etc/xinetd.d/tftp
server tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /home/fourth/linux/tftpboot/
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
vim /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/fourth/linux/tftpboot/"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"
启动tftp服务器
sudo service tftpd-hpa start
uboot命令格式:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
loadAddress 是文件在 DRAM 中的存放地址,[[hostIPaddr:]bootfilename]是要从Ubuntu 中下载的文件。
但tftp 命令不需要输入文件在Ubuntu 中的完整路径,只需要输入文件名即可。
如获取服务器上的zImage:
=> tftp 80800000 zImage
Using FEC1 device
TFTP from server 192.168.3.25; our IP address is 192.168.3.22
Filename 'zImage'.
Load address: 0x80800000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#########################################################
1.4 MiB/s
done
Bytes transferred = 5600408 (557498 hex)
=>
若提示serverip 没有设置,设置就好了
=> setenv serverip 192.168.3.25
=> saveenv
Saving Environment to MMC...
Writing to MMC(1)... done
=>
=> mmc info
Device: FSL_SDHC # 当前选中设备
Manufacturer ID: 15 # 制造商ID
OEM: 100 # 原始制造商
Name: 8GTF4 # 名称
Tran Speed: 52000000 # 传输速度
Rd Block Len: 512 # 最大读取数据块长
MMC version 4.0 # MMC版本
High Capacity: Yes # 是都高容量
Capacity: 7.3 GiB # 容量大小
Bus Width: 8-bit # 总线宽度(8位)
Erase Group Size: 512 KiB # 擦除块大小
=>
查看mmc信息【rescan、list、dev】
重新加载mmc设备
=> mmc rescan
=>
查看mmc设备
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1 (eMMC)
=>
切换为dev 0
=> mmc dev 0
switch to partitions #0, OK
mmc0 is current device
=> mmc list
FSL_SDHC: 0 (SD)
FSL_SDHC: 1 (eMMC)
=>
查看 mmc 分区情况
=> mmc part
Partition Map for MMC device 0 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 1957888 13276486 e7563509-01 83
2 196608 1761280 e7563509-02 83
=>
切换为dev 1 的分区0
=> mmc dev 1 0
switch to partitions #0, OK
mmc1(part 0) is current device
=>
读取分区中第600个块开始的 10个块的数据到DDR的 80800000 地址
=> mmc read 80800000 600 10
MMC read: dev # 1, block # 1536, count 16 ... 16 blocks read: OK
然后读取DDR的数据
=> md.l 80800000 10
80800000: 6c5bac96 64756162 65746172 3531313d ..[lbaudrate=115
80800010: 00303032 72616f62 616e5f64 453d656d 200.board_name=E
80800020: 62004b56 6472616f 7665725f 5834313d VK.board_rev=14X
80800030: 62003431 5f746f6f 3d746466 00797274 14.boot_fdt=try.
1、切换到emmc 的第0分区
=> mmc dev 1 0
switch to partitions #0, OK
mmc1(part 0) is current device
=>
2、从tftp下载 u-boot.imx 到内存 80800000
=> tftp 80800000 u-boot.imx
Using FEC1 device
TFTP from server 192.168.3.25; our IP address is 192.168.3.22
Filename 'u-boot.imx'.
Load address: 0x80800000
Loading: #########################
1.7 MiB/s
done
Bytes transferred = 363520 (58c00 hex)
=>
3、将内存的数据写到emmc的第0分区第2个块
//为什么是 2C6 ?上一步骤我们下载的u-boot.imx为 363520 个字节,353520/512=710块,十六进制为2C6 (如果有小数需要+1)
=> mmc write 80800000 2 2C6
MMC write: dev # 1, block # 2, count 710... 710blocks written: OK
=>
4、分区设置
=> mmc partconf 1 1 0 0
=>
5、重启
=> reset
resetting ...
命令格式:
fstype :
如:查询第0-1-2个分区信息
=> fstype mmc 1:0
Failed to mount ext2 filesystem...
** Unrecognized filesystem type **
=> fstype mmc 1:1
fat
=> fstype mmc 1:2
ext4
=>
命令格式如下:
fatinfo []
interface 表示接口,比 mmc,dev 是查询的设备号,part 是要查询的分区。
如:查询emmc分区1的文件系统信息
=> fatinfo mmc 1:1
Interface: MMC
Device 1: Vendor: Man 000015 Snr 754c46ce Rev: 0.6 Prod: 8GTF4R
Type: Removable Hard Disk
Capacity: 7456.0 MB = 7.2 GB (15269888 x 512)
Filesystem: FAT32 "NO NAME "
=>
命令格式如下:
fatls [] [directory]
interface 表示接口,比 mmc,dev 是查询的设备号,part 是要查询的分区;
directory是要查询的目录
如查询 EMMC 分区1 中的所有的目录和文件
=> fatls mmc 1:1
6785568 zimage
39299 imx6ull-14x14-emmc-4.3-480x272-c.dtb
39299 imx6ull-14x14-emmc-4.3-800x480-c.dtb
39299 imx6ull-14x14-emmc-7-800x480-c.dtb
39299 imx6ull-14x14-emmc-7-1024x600-c.dtb
39299 imx6ull-14x14-emmc-10.1-1280x800-c.dtb
39299 imx6ull-14x14-emmc-hdmi.dtb
40043 imx6ull-14x14-emmc-vga.dtb
8 file(s), 0 dir(s)
=>
命令格式:
fatload [ [ [ [bytes [pos]]]]]
ddr 是保存在DRAM 中的起始地址,filename 是要读取的文件名字。
bytes 表示读取多少字节的数据,如果 bytes 为 0 或者省略的话表示读取整个文件
如读取zImage到 80800000
=> fatload mmc 1:1 80800000 zImage
reading zImage
6785568 bytes read in 222 ms (29.1 MiB/s)
=>
命令格式:
fatwrite
addr 是要写入的数据在 DRAM中的起始地址,filename 是写入的数据文件名字,bytes 表示要写入多少字节的数据
fatwrite mmc 1:1 80800000 zImage 6788f8
ext2load、ext2ls、ext4load、ext4ls 和ext4write
略
略
BOOT 操作命令
uboot 的本质工作是引导 Linux,所以uboot 肯定有相关的boot(引导)命令来启动 Linux。常用的跟boot 有关的命令有:bootz、bootm 和 boot。
命令格式:
bootz [addr [initrd[:size]] [fdt]]
addr 是Linux 镜像文件在 DRAM 中的位置,
initrd 是initrd 文件在DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可,
fdt 就是设备树文件在 DRAM 中的地址
前提:在DRAM中有相应的文件如zImage、dtb(设备树),可通过fatload、tftp、nfs加载文件到DRAM
操作如下:
=> tftp 80800000 zImage
=> tftp 83000000 imx6ull-14x14-emmc-hdmi.dtb
=> bootz 80800000 - 83000000
实例如下:
=> tftp 80800000 zImage
Using FEC1 device
TFTP from server 192.168.3.25; our IP address is 192.168.3.22
Filename 'zImage'.
Load address: 0x80800000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
########
2 MiB/s
done
Bytes transferred = 6785568 (678a20 hex)
=>
=> tftp 83000000 imx6ull-14x14-emmc-hdmi.dtb
Using FEC1 device
TFTP from server 192.168.3.25; our IP address is 192.168.3.22
Filename 'imx6ull-14x14-emmc-hdmi.dtb'.
Load address: 0x83000000
Loading: ###
1.4 MiB/s
done
Bytes transferred = 39299 (9983 hex)
=>
=> bootz 80800000 - 83000000
Kernel image @ 0x80800000 [ 0x000000 - 0x678a20 ]
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 83000000, end 8300c982
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.1.15-g59913b0 (alientek@ubuntu) (gcc version 5.3.
先确定emmc存在该文件
=> fatls mmc 1:1
6785568 zimage #这个是我们要的
39299 imx6ull-14x14-emmc-4.3-480x272-c.dtb
39299 imx6ull-14x14-emmc-4.3-800x480-c.dtb
39299 imx6ull-14x14-emmc-7-800x480-c.dtb
39299 imx6ull-14x14-emmc-7-1024x600-c.dtb
39299 imx6ull-14x14-emmc-10.1-1280x800-c.dtb
39299 imx6ull-14x14-emmc-hdmi.dtb #设备树按需获取
40043 imx6ull-14x14-emmc-vga.dtb
8 file(s), 0 dir(s)
=>
操作如下:
=> fatload mmc 1:1 80800000 zImage
=> fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
=> bootz 80800000 - 83000000
实例如下:
=> fatload mmc 1:1 80800000 zImage
reading zImage
6785568 bytes read in 222 ms (29.1 MiB/s)
=> fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
reading imx6ull-14x14-emmc-7-1024x600-c.dtb
39299 bytes read in 23 ms (1.6 MiB/s)
=> bootz 80800000 - 83000000
Kernel image @ 0x80800000 [ 0x000000 - 0x678a20 ]
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 83000000, end 8300c982
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.1.15-g59913b0 (alientek@ubuntu) (gcc version 5.3.0 (GCC) ) #1 SMP PREEMPT Thu Jun 16 10:43:09 CST 2022
启动uImage 镜像文件【bootm】
命令格式如下:
bootm [addr [initrd[:size]] [fdt]]
操作方法与bootz是一样的
启动 Linux 系统【boot】
boot 其实是读取环境变量bootcmd 来启动Linux系统。
bootcmd 环境变量保存着引导命令,是启动的命令集合。
相当于在倒计时后自动执行boot命令,加载环境变量,启动Linux系统。
所以我们通过修改bootcmd 来改变系统的启动方式。
如:
=> setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000'
=> saveenv
=> boot
其中设置变量的时候记得使用单引号‘ ’括起来,命令与命令之间使用分号;
就是重启的意思
go 命令用于跳到指定的地址处执行应用。
命令格式如下:
go addr [arg ...]
如使用go 命令启动 printf.bin 这个应用
=> tftp 87800000 printf.bin
=> go 87800000
将命令挡在一个集合,设置环境变量,然后通过run执行