编译 u-boot
u-boot,全称 Universal Boot Loader,是遵循 GPL 条款的开放源码项目。u-boot 的作用是系统引导。u-boot 的工作模式有启动加载模式和下载模式。启动加载模式是 Bootloader 的正常工作模式,嵌入式产品发布时,Bootloader 必须工作在这种模式下,Bootloader 将嵌入式操作系统从 FLASH 中加载到 SDRAM 中运行,整个过程是自动的。下载模式就是 Bootloader 通过某些通信手段将内核映像或根文件系统映像等从 PC 机中下载到目标板的 FLASH 中。用户可以利用 Bootloader 提供的一些命令接口来完成自己想要的操作。
下载与编译
git clone "https://gitee.com/thead-linux/u-boot.git" -b master make ice_evb_xxx_defconfig make -j ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu-
编译过程如下:
...... LD u-boot OBJCOPY u-boot.srec OBJCOPY u-boot-nodtb.bin SYM u-boot.sym COPY u-boot.bin CC spl/lib/display_options.o LD spl/lib/built-in.o LD spl/u-boot-spl OBJCOPY spl/u-boot-spl-nodtb.bin COPY spl/u-boot-spl.bin CAT u-boot-with-spl.bin
编译完成后,生成 u-boot-with-spl.bin 文件,接下来将u-boot-with-spl.bin 烧写到开发板中。
烧写
方法一:在开发板的 Linux 环境下直接烧写:
# 将 u-boot-with-spl.bin 传到开发板 scp u-boot-with-spl.bin root@192.168.1.100:~/ # 打开 boot 分区的写权限 ssh root@192.168.1.100 "echo 0 > /sys/block/mmcblk0boot0/force_ro" # 将 u-boot-with-spl.bin 写入boot分区 ssh root@192.168.1.100 "dd if=u-boot-with-spl.bin of=/dev/mmcblk0boot0" # 重启开发板 ssh root@192.168.1.100 "reboot"
u-boot命令使用
u-boot 提供众多命令,输入 help 或 ? 可以查看 u-boot 有哪些命令
xxxx # help ? - alias for 'help' base - print or set address offset bdinfo - print Board Info structure bmode - sd1|sd2|qspi1|normal|usb|sata|ecspi1:0|ecspi1:1|ecspi1:2|ecspi1:3|esdhc1|esdhc2|esdhc3|esdhc4 [noreset] bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol bootvx - Boot vxWorks from an ELF image bootz - boot Linux zImage image from memory clocks - display clocks clrlogo - fill the boot logo area with black cmp - memory compare ...
信息查询相关命令
bdinfo
该命令用来查询当前板子的相关信息:
< xxxx # bdinfo boot_params = 0x0000000000000000 DRAM bank = 0x0000000000000000 -> start = 0x0000000000000000 -> size = 0x0000000100000000 relocaddr = 0x00000000fff96000 reloc off = 0x000000003ff96000 ethaddr = 6a:af:e8:c6:23:ff IP addr = 192.168.1.100 baudrate = 115200 bps /pre>
printenv
查询当前板子的一些相关环境变量:
xxxx # print arch=riscv avail_addr=0x10000000 baudrate=115200 board=ice-xxxx board_name=ice-xxxx bootargs=console=ttyS0,115200 rdinit=/sbin/init rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b rootfstype=ext4 clk_ignore_unused loglevel=7 crashkernel=256M-:128M xxxx_mmu_v1 eth=6a:af:e8:c6:23:ff bootcmd=ext4load mmc 0:2 0x0 fw_jump.bin; ext4load mmc 0:2 0x01f00000 hw.dtb; ext4load mmc 0:2 0x02000000 uImage; bootm 0x02000000 - 0x01f00000 bootdelay=2 cpu=c9xx dtb_addr=0x01f00000 dtb_emmc_size=0x100 dtb_emmc_start=0x1000 ethact=ethernet@3fffc0000 ethaddr=6a:af:e8:c6:23:ff fdtcontroladdr=fffe4630 ipaddr=192.168.1.100 kernel_addr=0x02000000 kernel_emmc_size=0xa000 kernel_emmc_start=0x2000 opensbi_addr=0x0 opensbi_emmc_size=0x280 opensbi_emmc_start=0x800 partitions=name=table,size=2031KB;name=boot,size=60MiB,type=bc13c2ff-59e6-4262-a352-b275fd6f7172;name=root,uuid=80a5a8e9-c744-491a-93c1-4f4194fd690b,size=-,type=linux stderr=serial@3fff73000 stdin=serial@3fff73000 stdout=serial@3fff73000 uuid_rootfs=80a5a8e9-c744-491a-93c1-4f4194fd690b vendor=thead Environment size: 1072/131068 bytes
version
该命令用于查询uboot版本和交叉编译工具的相关信息
xxxx # version U-Boot 2020.01-g6cc5d59b0d (Dec 20 2020 - 08:37:37 +0000) riscv64-unknown-linux-gnu-gcc (T-HEAD RISCV Tools V1.10.2 B20201104) 8.4.0 GNU ld (GNU Binutils) 2.32
环境变量相关命令
环境变量常用的命令主要有两个,分别是setenv和saveenv,setenv命令用来设置或者修改当前环境变量的值,saveenv用来保存环境变量的值,一般环境变量是存放在外部的Flash中的,例如Nand Flash中,当uboot启动的时候,会将环境变量读取的DRAM中,当我们使用setenv修改了环境变量的值后,需要使用saveenv命令将修改后的环境变量的值保存到Flash中,否则修改无效。setenv命令的格式如下:
setenv env value
查看当前的bootdelay环境变量值为:
print cpu
当前的bootdelay为3,我们要将bootdelay环境变量的值设置为5,可以使用下面的命令:
setenv bootdelay 5 saveenv
清除环境变量:
# 恢复所有变更的默认值 env default -a
内存操作相关命令
内存操作的相关命令用于对DRAM内存进行读写操作,常用的内存操作命令有md、nm、mm、mw、cp、cmp。
emmc和sd卡相关操作命令
对于uboot来说是支持emmc或者sd卡,因此也需要提供给用户emmc和sd卡的相关操作命令,uboot中常用于操作mmc设备的命令为”mmc”,mmc是一系列的命令,它的后面可以跟不同的参数,在uboot命令行中,输入下面的命令可以查看详细的用法:
xxxx # ? mmc
mmc - MMC sub system
Usage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
mmc hwpartition [args...] - does hardware partitioning
arguments (sizes in 512-byte blocks):
[user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes
[gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition
[check|set|complete] - mode, complete set partitioning completed
WARNING: Partitioning is a write-once setting once it is set to complete.
Power cycling is required to initialize partitions after set to complete.
mmc setdsr - set DSR register value
mmc后跟不同的参数可以实现不同的功能,如下:
| 命令 | 功能 |
|---|---|
| mmc info | 输出mmc设备的信息 |
| mmc read | 读取mmc设备中的数据 |
| mmc write | 向mmc设备中写入数据 |
| mmc rescan | 扫描当前存在的mmc设备 |
| mmc part | 列出mmc设备的分区 |
| mmc dev | 切换mmc设备 |
| mmc list | 列出当前的mmc设备 |
| mmc hwpartition | 设置mmc设备的分区 |
| mmc bootbus | 设置指定mmc设备的BOOT_BUS_WIDTH的值 |
| mmc bootpart | 设置指定mmc设备的boot和RPMB分区大小 |
| mmc partconf | 设置指定mmc设备的PARTITION_CONFIG的值 |
| mmc rst | mmc设备复位 |
| mmc setdsr | 设置mmc设备DSR寄存器的值 |
mmc info
mmc info命令用来显示当前选中的mmc设备的信息:
xxxx # mmc info Device: mmc0@3fffb0000 Manufacturer ID: 11 OEM: 100 Name: 004GA Bus Speed: 25000000 Mode: MMC High Speed (52MHz) Rd Block Len: 512 MMC version 5.0 High Capacity: Yes Capacity: 3.7 GiB Bus Width: 8-bit Erase Group Size: 512 KiB HC WP Group Size: 4 MiB User Capacity: 3.7 GiB WRREL Boot Capacity: 2 MiB ENH RPMB Capacity: 512 KiB ENH
mmc rescan
mmc rescan命令用于扫描当前目标板上所有的mmc设备,包括eMMC和SD卡,命令输入如下:
xxxx # mmc rescan
mmc list
mmc list命令可用于查看当前目标板共有多少个mmc设备,输入命令如下:
xxxx # mmc list mmc0@3fffb0000: 0 (eMMC)
mmc dev
mmc dev命令可以用来切换当前的mmc设备,命令格式如下:
mmc dev [dev] [part]
其中[dev]表示要切换的mmc设备号,[part]是mmc设备的分区号,如果不写分区号,则默认为分区0。
例如,使用命令切换到eMMC设备:
#当0为SD卡,1为eMMC时 => mmc dev 1
mmc part
mmc part命令可以用来查看当前mmc设备的分区,例如查看当前sd卡中的分区:
xxxx # mmc part
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name
Attributes
Type GUID
Partition GUID
1 0x00000022 0x00000fff "table"
attrs: 0x0000000000000000
type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
type: data
guid: 72fd13fc-2c69-42f4-9f02-d19dd22ecd0e
2 0x00001000 0x0001efff "boot"
attrs: 0x0000000000000000
type: bc13c2ff-59e6-4262-a352-b275fd6f7172
guid: 02382dbd-94d7-435f-ace0-598b4a5acb5e
3 0x0001f000 0x0075ffde "root"
attrs: 0x0000000000000000
type: 0fc63daf-8483-4772-8e79-3d69d8477de4
type: linux
guid: 80a5a8e9-c744-491a-93c1-4f4194fd690b
mmc read
mmc read命令可用于读取mmc设备的数据,它的使用格式如下所示:
mmc read addr blk# cnt
其中addr是将数据读取到DRAM中的地址,blk是要读取的块起始地址,一块为512字节,cnt则是要读取的块的数量。
例如,从当前的SD卡设备的第2048块开始,读取20个块数据到DRAM的0x10000100地址处,该命令如下:
xxxx # mmc list xxxx # mmc dev 0 xxxx # mmc read 10000100 800 14
读取成功后,如下所示:
MMC read: dev # 0, block # 2048, count 20 ... 20 blocks read: OK
mmc write
mmc write命令可以将DRAM中的数据写入到mmc设备里面,其命令的格式如下所示:
mmc write addr blk# cnt
其中addr是要写入到mmc设备中的数据在DRAM中的起始地址,blk是要写入mmc的块起始地址,cnt是要写入的块数量,一个块的大小为512字节。
例如,将DRAM地址0x10000100开始的数据,从mmc设备的2048个块开始烧写,烧写20个块,命令如下:
xxxx # mmc read 10000100 800 14
写入成功后,如下所示:
MMC write: dev # 0, block # 8264, count 20 ... 20 blocks written: OK
U-Boot下的命令很详细
技术干货👍,u-boot 编译、烧写和常用命令整理得很清楚,收藏慢慢看了