[架构之路-26]:目标系统 - 系统软件 - bootloader uboot使用方法常用命令

Posted 文火冰糖的硅基工坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[架构之路-26]:目标系统 - 系统软件 - bootloader uboot使用方法常用命令相关的知识,希望对你有一定的参考价值。

目录

第1章 uboot简介

1.1 uboot与Linux的关系

1.2 bootloader的类型

1.3 uboot的主要版本

1.4 uboot的作用与功能

1.5 SoC支持的启动方式

第2章 uboot的目录结构

第3章 编译Uboot

第4章 通过Linux server烧制uboot到用于启动的SD卡上

第5章 uboot常用命令使用

5.1 帮助命令

5.2 信息查询命令

5.3 内存操作命令

5.4 EMMC 和 SD 卡操作命令

5.5 文件系统操作命令

第6章 网络操作命令

6.1 dhcp命令

6.2 ping 命令

6.3 nfs 命令

6.4 tftp命令

第7章 BOOT 操作命令

第8章 其他常用命令


第1章 uboot简介

  • uboot是SourceForge上的开源项目。
  • uboot项目的作者:一个德国人最早发起的项目。
  • uboot就是由一个人发起,然后由整个网络上所有感兴趣的人共同维护发展而来的一个bootloader。

1.1 uboot与Linux的关系

在一个复杂的带Linux操作系统的嵌入式系统中,Linux 系统的启动必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段 bootloader 程序,然后才能运行操作系统程序,uboot就是其中一种这样的bootloader程序

bootloader 程序主要的职责有:

  • (1)先,初始化 CPU和DDR 等外设。
  • (2)然后,将 Linux 内核从 flash(NAND, NOR FLASH,SD, MMC 等) 拷贝到 DDR 中。
  • (3)最后,启动 Linux 内核。

当然了, bootloader 的实际工作要复杂的多,但是它最主要的工作就是启动 Linux 内核, bootloader 和 Linux 内核的关系就跟 PC 上的 Bios 和Windows 的关系一样, bootloader 就相当于 BIOS,所以我们要先搞定 bootloader。

uboot 的全称是 Universal Boot Loader, 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPSx8668k、Nios与MicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。uboot 是一个遵循 GPL 协议的开源软件, uboot 是一个裸机(无操作系统)代码,可以看作是一个裸机综合例程。

除了上述三个主要的职责外,现在的 uboot 已经支持液晶屏、网络、 USB 等高级功能。 

1.2 bootloader的类型

有很多现成的 bootloader 软件可以使用,比如 U-Boot、 vivi、 RedBoot 等等,其中以 U-Boot 使用最为广泛。

1.3 uboot的主要版本

(1)开源官方版本: U-Boot | DENX

(2)半导体厂家维护的版本

uboot 官方的 uboot 源码是给半导体厂商准备的,半导体厂商会下载 uboot 官方的 uboot 源码,然后将自家相应的芯片移植进去。也就是说半导体厂商会自己维护一个版本的 uboot,这个版本的 uboot 相当于是他们定制的。

如NLP:uboot-imx - i.MX U-Boot

(3)开发版本厂家公开版本

开发板厂家根据自身开发板的需要,进行了部分修改,生成自己的版本。

野火提供的 uboot 下载链接:
ebf_linux_uboot: 野火所有Linux系列产品使用的uboot源码仓库

git clone https://gitee.com/Embedfire/ebf_linux_uboot.git

//切换 ebf_v2020_10_imx 分支

git checkout ebf_v2020_10_imx

(4)设备厂家私有版本

设备厂家一般不会直接用 uboot 官方的 U-Boot 源码, 不同的设备厂家,其底层硬件是不相同的,设备厂家可能会基于前面提到的版本,再进一步对uboot进行修改,生成自己的私有版本 。

1.4 uboot的作用与功能

  • uboot主要作用是用来启动操作系统内核。
  • uboot还要负责部署整个计算机系统。
  • uboot中还有操作Flash等板子上硬盘的驱动。
  • uboot还得提供一个命令行界面供人来操作。

1.5 SoC支持的启动方式

  • 譬如SD卡启动
  • NorFlash启动
  • NandFlash启动等。

第2章 uboot的目录结构

 其中,与移植官方uboot需要修改的文件夹有以下几个:

(1)board

不同开发板的代码,移植uboot的时候,新建开发板bsp也是在这里对应的芯片厂商下面新建。

其中的mx6ullfire就是野火开发板的文件

(2)configs

存放不同开发板的uboot配置文件,命名规则统一为xxx_defconfig,xxx表示为开发板名称。

其中mx6ull_fire_mmc_defconfig就是野火开发板的配置文件

第3章 编译Uboot

(1)在Linux环境下,安装编译工具和依赖

sudo apt install make git gcc-arm-none-eabi gcc bison flex libssl-dev dpkg-dev lzop libncurses5-dev

(2)编译

//清除上次生成的编译环境,避免之前的环境干扰影响编译结果
sudo make distclean


//加载板级配置文件,具体的板级配置文件在 uboot 根目录下的 configs 目录下
sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi- mx6ull_fire_mmc_defconfig


//设置编译架构为 arm 编译工具链为arm-none-eabi- 然后开始编译整个uboot工程
sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi-

(3)编译输出

编译出的文件:

u-boot:编译出的ELF格式的uboot镜像文件
u-boot.bin:编译出来的二进制格式的uboot可执行镜像文件
u-boot.cfg:uboot的另一种配置文件
u-boot.imx:u-boot.bin添加头部信息以后的文件,NXP的CPU专用文件
u-boot.lds:链接脚本
u-boot.map:uboot映射文件
u-boot.srec:S-Record格式的镜像文件
u-boot.sym:uboot符号文件
u-boot-nodtb.bin:和u-boot.bin一样,u-boot-nodtb.bin的复制文件

第4章 通过Linux server烧制uboot到用于启动的SD卡上

(1)插上读卡器,使用 lsblk 命令查看磁盘设备,如下所示

可以通过SD卡运行uboot.

 (2)执行以下烧录命令,将 u-boot-dtb.imx 烧写到/dev/sdb 中

dd 命令用于复制文件并对原文件的内容进行转换和格式化处理。

dd 命令功能很强大的,对于一些比较底层的问题,使用 dd 命令往往可以得到出人意料的效果。

用的比较多的还是用 dd 来备份裸设备。

sudo dd iflag=dsync oflag=dsync if=u-boot-dtb.imx of=/dev/sdb seek=2

本操作的目的,就是把uboot的可执行镜像文件烧录到SD卡上。

(3)烧录成功提示:

第5章 uboot常用命令使用

将SD卡插入目标板子,目标板选择从SD卡启动,连接串口(默认波特率115200),查看串口日志:

 可以看出 uboot 打印出了板子的一些基本信息,包括 CPU、内存等信息。

uboot 支持很多的命令,功能十分强大,与 linux 类似,在执行某条 uboot 命令时,可使用tab 自动补全命令,在没有命令名冲突的情况下可以使用命令的前几个字母作为命令的输入,例如想要执行 reset 命令,输入 res 或 re 即可。

常见的命令列表如下:

5.1 帮助命令

当不清楚 uboot 支持什么命令时,可输入 help 或 ? 可查看 uboot 支持的命令列表,如下所示:

 当需要具体使用哪个命令时,可使用 “help 命令” 或 “? 命令” 的方式查看具体命令的使用说明。

5.2 信息查询命令

常用的和信息查询有关的命令有 3 个: bdinfo、 printenv 和 version。

(1)bdinfo 命令,此命令用于查看板子信息

 (2)环境变量信息

命令printenv:用于输出环境变量信息,

命令 setenv:用于设置或者修改环境变量的值。

命令 saveenv:用于保存修改后的环境变量,一般环境变量是存放在外部 flash 中的,uboot 启动的时候会将环境变量从 flash 读取到 DRAM 中。所以使用命令 setenv 修改的是 DRAM中的环境变量值,修改以后要使用 saveenv 命令将修改后的环境变量保存到 flash 中,否则的话uboot 下一次重启会继续使用以前的环境变量值。

(3)命令 version 用于查看 uboot 的版本号

5.3 内存操作命令

内存操作命令就是用于直接对 DRAM 进行读写操作的,

常用的内存操作命令有 md、 nm、mm、 mw、 cp 和 cmp。

(1)md 命令

用于显示内存值,格式如下:

md[.b, .w, .l] address [# of objects]

命令中的[.b .w .l]对应 byte、 word 和 long,也就是分别以 1 个字节、 2 个字节、 4 个字节来显示内存值。 address 就是要查看的内存起始地址, [# of objects]表示要查看的数据长度。

(2)nm 命令

用于修改指定地址的内存值,命令格式如下:

nm [.b, .w, .l] address

(3)mm命令 

mm 命令也是修改指定地址内存值的,使用 mm 修改内存值的时候地址会自增。

(4)mw 命令

命令 mw 用于使用一个指定的数据填充一段内存,命令格式如下:

mw [.b, .w, .l] address value [count]

(5)cp 命令

cp 是数据拷贝命令,用于将 DRAM 中的数据从一段内存拷贝到另一段内存中,或者把 NorFlash 中的数据拷贝到 DRAM 中。命令格式如下:
cp [.b, .w, .l] source target count
cp 命令同样可以以.b、 .w 和.l 来指定操作格式, source 为源地址, target 为目的地址, count为拷贝的长度。
(6)cmp 命令

cmp 是比较命令,用于比较两段内存的数据是否相等,命令格式如下:

cmp [.b, .w, .l] addr1 addr2 count

cmp 命令同样可以以.b、 .w 和.l 来指定操作格式, addr1 为第一段内存首地址, addr2 为第二段内存首地址, count 为要比较的长度。
 

5.4 EMMC 和 SD 卡操作命令

mmc 命令能够对如 sd 卡以及 emmc 类的存储介质进行操作,以下进行简单说明,对于 mmc 命令不熟悉可使用 help mmc 查看相关命令的帮助,常用功能如下所示:

(1)mmc list 命令

mmc list 命令用于来查看当前开发板一共有几个 MMC 设备

 可以看出当前开发板有两个 MMC 设备: FSL_SDHC:0(SD卡) 和 FSL_SDHC:1 (eMMC)

(2)mmc info 命令

mmc info 命令用于输出当前选中的 mmc info 设备的信息

可以当前选中的 MMC设备是SD卡,容量为7.4G。

 (3)mmc dev 命令

mmc dev 命令用于切换当前 MMC 设备,命令格式如下:

mmc dev [dev] [part]

[dev]用来设置要切换的 MMC 设备号, [part]是分区号。如果不写分区号的话默认为分区 0
使用如下命令切换到 emmc:

 可以看到切换到了mmc1的分区0,输入命令“mmcinfo”即可查看emmc的信息:

emmc的容量为7.3G。

(4)mmc part 命令

 有时候 SD 卡或者 EMMC 会有多个分区,可以使用命令“mmc part”来查看其分区,比如查看 当前EMMC 的分区情况

可以看出,此时 EMMC 有两个分区, 第一个分区起始扇区为 8192,长度
为 81920个扇区; 第二个分区起始扇区为 90112,长度为 15179776个扇区。

(5)mmc 操作命令

可使用read、write、erase指令对 mmc 存储介质以 block 为操作单位进行读、写、擦除操作。命令格式如下:

mmc read addr blk# cnt # 读

mmc write addr blk# cnt # 写

mmc erase blk# cnt # 擦

将 mmc 设备的的前 10 个 block 读取到 0x80000000 地址处:

5.5 文件系统操作命令

有时候需要在 uboot 中对 SD 卡或者 EMMC 中存储的文件进行操作,这时候就要用到文件操作命令,跟文件操作相关的命令有: fatinfo、 fatls、 fstype、 fatload 和 fatwrite。

(1)fstype 命令

fstype 用于查看 MMC 设备某个分区的文件系统格式,命令格式如下:

fstype <interface> <dev>:<part>

可使用 fstype 命令判断存储介质分区使用的是什么类型的文件系统。以 mmc 介质为例,判断 emmc的两个分区的文件系统类型:

 野火 linux 开发板具有 U 盘功能,能够通过 PC 以访问 U 盘的形式访问/boot 目录下的文件, /boot目录对应的即是 mmc 1:1 分区。
而 ext4 分区对应的则是 Debian 根文件系统。

(2)fatinfo 命令

fatinfo 命令用于查询指定 MMC 设备分区的文件系统信息,格式如下:

fatinfo <interface> [<dev[:part]>]

interface 表示接口,比如 mmc, dev 是查询的设备号, part 是要查询的分区。比如我们要查询 EMMC 分区 1 的文件系统信息,命令如下:

 可以看出:EMMC 分区 1 的文件系统为 FAT16 格式的。

(3)fatls 命令

fatls 命令用于查询 FAT 格式设备的目录和文件信息,命令格式如下:

fatls <interface> [<dev[:part]>] [directory]

interface 是要查询的接口,比如 mmc, dev 是要查询的设备号, part 是要查询的分区, directory是要查询的目录。比如查询 EMMC 分区 1 中的所有的目录和文件,输入命令:

 若想要查看其它目录下的文件列表,只要加上文件路径即可,如下

(4)fatload 命令

fatload 命令用于将指定的文件读取到 DRAM 中,命令格式如下:

fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]

interface 为接口,比如 mmc, dev 是设备号, part 是分区, addr 是保存在 DRAM 中的起始地址, filename 是要读取的文件名字。 bytes 表示读取多少字节的数据,如果 bytes 为 0 或者省略的话表示读取整个文件。 pos 是要读的文件相对于文件首地址的偏移,如果为 0 或者省略的话表示从文件首地址开始读取。
使用 fatload 将 FAT 文件系统的文件加载到内存中,如下所示

 (5)EXT 格式文件系统操作命令

uboot 有 ext2 和 ext4 这两种格式的文件系统的操作命令,常用的就四个命令,分别为:ext2load、 ext2ls、 ext4load、 ext4ls 和 ext4write。

这些命令的含义和使用与 fatload、 fatls 和 fatwrite一样,只是 ext2 和 ext4 都是针对 ext 文件系统的。

第6章 网络操作命令

uboot 支持大量的网络相关命令,比如 dhcp、ping、 nfs 和 tftpboot。

网络相关环境变量:

网络地址环境变量的设置要根据自己的实际情况,确保 Ubuntu 主机和开发板的 IP
地址在同一个网段内,比如,Ubuntu 主机的地址为 192.168.1.6,因此 serverip 就是192.168.1.6。 ethaddr 为网络 MAC 地址,是一个 48bit 的地址,如果在同一个网段内有多个开发板的话一定要保证每个开发板的 ethaddr 是不同的,否则通信会有问题。

置服务器ip地址的环境变量:

6.1 dhcp命令

dhcp 用于从DHCP server获取 IP 地址,前提得开发板连接到DHCP server上的。

如果开发板连接的网络中没有DHCP server,那么 dhcp 命令就会失效。

直接输入 dhcp 命令即可通过路由器获取到 IP 地址:

6.2 ping 命令

开发板的网络能否使用,是否可以和服务器(Ubuntu 主机)进行通信,通过 ping 命令就可以验证,直接 ping 服务器的 IP 地址即可,

可以看出, 192.168.1.6 这个主机存在,说明 ping 成功, uboot 的网络工作正常。

注意!

只能在 uboot 中 ping 其他的机器,其他机器不能 ping uboot,因为 uboot 没有对 ping命令做处理,如果用其他的机器 ping uboot 的话会失败!

6.3 nfs 命令

nfs(Network File System)网络文件系统,通过 nfs 可以在计算机之间通过网络来分享资源,比如我们将 linux 镜像和设备树文件放到 Ubuntu 服务器上中,然后在 uboot 中使用 nfs 命令将 Ubuntu 中的 linux 镜像设备树下载开发板的 DRAM 中。

在使用之前需要开启 Ubuntu 主机的 NFS 服务,并且要新建一个 NFS 使用的目录,以后所有要通过NFS 访问的文件都需要放到这个 NFS 目录中。

Ubuntu 使用如下命令安装 NFS 服务:

sudo apt-get install nfs-kernel-server rpcbind

自行创建 linux_nfs 文件夹供 nfs 服务器使用,以后我们可以在开发板上通过网络文件系统来访问 nfs 文件夹。

配置 nfs,使用如下命令打开 nfs 配置文件/etc/exports:
sudo vim /etc/exports

 重启 NFS 服务,使用命令如下:

sudo /etc/init.d/nfs-kernel-server restart

uboot 中的 nfs 命令格式如下所示:

nfs [loadAddress] [[hostIPaddr:]bootfilename]

loadAddress 是要保存的 DRAM 地址, [[hostIPaddr:]bootfilename]是要下载的文件地址。
比如我们将在下一节编译出的linux内核文件 zImage 下载到开发板 DRAM 的 0X80800000 地址处,命令如下:

6.4 tftp命令

tftp 命令的作用和 nfs 命令一样,都是用于通过网络下载东西到 DRAM 中,只是 tftp 命令使用的 TFTP 协议, Ubuntu 主机作为 TFTP 服务器。

(1)安装tftp server

Ubuntu 上搭建 TFTP 服务器,需要安装 tftp-hpa 和 tftpd-hpa,命令如下:

sudo apt-get install tftp-hpa tftpd-hpa

sudo apt-get install xinetd

(2)创建tftp目录

和 NFS 一样, TFTP 也需要一个文件夹来存放文件,在用户目录下新建一个目录,命令如下:

mkdir /home/kk/imx6ull/tftpboot/

chmod 777 /home/kk/imx6ull/tftpboot/

(3)最后配置 tftp server

安装完成以后新建文件/etc/xinetd.d/tftp,

如果没有/etc/xinetd.d 目录的话自行创建, 然后在里面输入如下内容:

server tftp

socket_type = dgram
protocol = udp
wait = yes
user = root
server =/usr/sbin/in.tftpd
server_args = -s /home/kk/imx6ull/tftpboot/
disable = no
per_source = 11
cps = 100 2
flags = IPv4

(4)完了以后启动 tftp 服务,命令如下:(可以省略)

sudo service tftpd-hpa start

(5)设置tftp目录

打开/etc/default/tftpd-hpa 文件,将其修改为如下所示内容:

TFTP_USERNAME="tftp"

TFTP_DIRECTORY="/home/kk/imx6ull/tftpboot"

TFTP_ADDRESS=":69"

TFTP_OPTIONS="--secure"

TFTP_DIRECTORY 就是我们上面创建的 tftp 文件夹目录,以后我们就将所有需要通过TFTP 传输的文件都放到这个文件夹里面,并且要给予这些文件相应的权限。

(6)最后输入如下命令, 重启 tftp 服务器:

sudo service tftpd-hpa restart

(7)Copy zImage

将Linux的zImage 文件复制到 tftpboot 文件夹里面的。

(8)在uboot 中的 tftp 命令格式如下:

tftpboot [loadAddress] [[hostIPaddr:]bootfilename]

通过TFTP把zImage 下载到开发板 DRAM 的 0X80800000 地址处,命令如下:

第7章 BOOT 操作命令

uboot 的本质工作是引导 Linux,

vmlinuz通过Linux压缩得到zImage,zImage通过uboot加头信息得到uImage

uboot中可以支持zImage启动,是否支持,就看x210_sd.h中是否定义LINUX_ZIMAGE_MAGIC这个宏。CONFIG_ZIMAGE_BOOT宏,用来支持zImage格式的内核启动。

常用的跟 boot 有关的命令有: bootz、 bootm 和 boot。

(1)bootz 命令启动zImage

bootz 命令用于启动 zImage 镜像文件, bootz 命令格式如下:

bootz [addr [initrd[:size]] [fdt]]

命令 bootz 有三个参数, addr 是 Linux 镜像文件在 DRAM 中的位置, initrd 是 initrd 文件在DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可, fdt 就是设备树文件在DRAM 中的地址。

(2)bootm 命令启动uImage

bootm 和 bootz 功能类似,但是 bootm 用于启动内存中的uImage 镜像文件。

如果不使用设备树启动 Linux 内核的命令如下:

bootm addr

addr 是 uImage 镜像在 DRAM 中的首地址。

如果使用设备树启动 Linux 内核的命令如下:

bootm [addr [initrd[:size]] [fdt]]

其中 addr 是 uImage 在 DRAM 中的首地址, initrd 是 initrd 的地址, fdt 是设备树(.dtb)文件在 DRAM 中的首地址,如果 initrd 为空的话,同样是用“-”来替代。

(3)boot 命令启动bootcmd

boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系统,

bootcmd 是一个很重要的环境变量!其名字分为“boot”和“cmd”,也就是“引导”和“命令”,说明这个环境变量保存着引导命令,其实就是启动的命令集合,具体的引导命令内容是可以修改的。bootargs 环境变量用来存储根文件系统的路径。

uboot 倒计时结束以后就会启动 Linux 系统,其实就是执行的 bootcmd 中的启动命令

第8章 其他常用命令

uboot 中还有其他一些常用的命令,比如 reset、 go、 run 和 mtest 等。

(1)reset 命令

reset 命令顾名思义就是复位的,输入“reset”即可复位重启。

(2)go 命令

go 命令用于跳到指定的地址处执行应用,命令格式如下:

go addr [arg …]

(3)run 命令

run 命令用于运行环境变量中定义的命令,比如可以通过“run bootcmd”来运行 bootcmd 中的启动命令,但是 run 命令最大的作用在于运行我们自定义的环境变量。

以上是关于[架构之路-26]:目标系统 - 系统软件 - bootloader uboot使用方法常用命令的主要内容,如果未能解决你的问题,请参考以下文章

[架构之路-56]:目标系统 - 平台软件 - 总体架构概述

[架构之路-28]:目标系统 - 系统软件 - Linux OS内核功能架构图解内核构建内核启动流程

[架构之路-25]:目标系统 - 系统软件 - bootloader uboot内存映射与启动流程

[架构之路-21]:目标系统 - 系统软件 - 计算机系统架构计算机指令系统结构化程序与分层编程。

[架构之路-29]:目标系统 - 系统软件 - Linux OS内核以及内核驱动的调试技术

[架构之路-54]:目标系统 - 系统软件 - Linux下的网络通信-9-ADSLVDSLPPPOE