linux系统移植篇(二)—— Uboot使用介绍

linux系列目录:
linux基础篇(一)——GCC和Makefile编译过程
linux基础篇(二)——静态和动态链接
ARM裸机篇(一)——i.MX6ULL介绍
ARM裸机篇(二)——i.MX6ULL启动过程
ARM裸机篇(三)——i.MX6ULL第一个裸机程序
ARM裸机篇(四)——重定位和地址无关码
ARM裸机篇(五)——异常和中断
linux系统移植篇(一)—— linux系统组成
linux系统移植篇(二)—— Uboot使用介绍
linux系统移植篇(三)—— Linux 内核使用介绍
linux系统移植篇(四)—— 根文件系统使用介绍
linux驱动开发篇(一)—— Linux 内核模块介绍
linux驱动开发篇(二)—— 字符设备驱动框架
linux驱动开发篇(三)—— 总线设备驱动模型
linux驱动开发篇(四)—— platform平台设备驱动


一、Uboot介绍

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 使用最为广泛。

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 相当于是他们定制的。

NXP 就 维 护 的 2016.03 这 个 版 本 的 uboot , 下 载 地 址 为 :
https://source.codeaurora.org/external/imx/uboot-imx/

如果是我们自己做的板子就需要修改 NXP 官方的 uboot,使其支持我们自己做的板子,这三种 uboot的区别如表所示:
在这里插入图片描述

二、uboot烧录与启动

1. 获取uboot

野火提供的 uboot 下载链接:
https://gitee.com/Embedfire/ebf_linux_uboot

git clone https://gitee.com/Embedfire/ebf_linux_uboot.git
//切换 ebf_v2020_10_imx 分支
git checkout ebf_v2020_10_imx

2. uboot目录结构

在这里插入图片描述
其中与移植官方uboot需要修改的文件夹有以下几个:

  1. board
    不同开发板的代码,移植uboot的时候新建开发板bsp也是在这里对应的芯片厂商下面新建。其中的mx6ullfire就是野火开发板的文件
    在这里插入图片描述
    2.configs
    存放不同开发板的uboot配置文件,命名规则统一为xxx_defconfig,xxx表示为开发板名称。其中mx6ull_fire_mmc_defconfig就是野火开发板的配置文件。
    在这里插入图片描述

3. 编译uboot

  1. 安装编译工具和依赖:
sudo apt install make git gcc-arm-none-eabi gcc bison flex libssl-dev dpkg-dev lzop libncurses5-dev
  1. 编译
//清除上次生成的编译环境,避免之前的环境干扰影响编译结果
sudo make distclean
//加载板级配置文件,具体的板级配置文件在 uboot 根目录下的 configs 目录下
sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi- mx6ull_fire_mmc_defconfig
//设置编译架构为 arm 编译工具链为arm-none-eabi- 然后开始编译
sudo make ARCH=arm CROSS_COMPILE=arm-none-eabi-

编译出的文件:

  • 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. 烧写uboot到 SD 卡

插上读卡器,使用 lsblk 命令查看磁盘设备,如下所示
在这里插入图片描述

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

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

烧录成功提示:
在这里插入图片描述

三、uboot常用命令使用

将SD卡插入板子,选择从SD卡启动,查看串口日志:
在这里插入图片描述

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

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

1. 帮助命令

当不清楚 uboot 支持什么命令时,可输入 help 或 ? 可查看 uboot 支持的命令列表,如下所示:
在这里插入图片描述
当需要具体使用哪个命令时,可使用 “help 命令” 或 “? 命令” 的方式查看具体命令的使用说明。

2. 信息查询命令

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

  1. bdinfo 命令,此命令用于查看板子信息
    在这里插入图片描述

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

  3. 命令 version 用于查看 uboot 的版本号
    在这里插入图片描述

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
  1. mm命令
    mm 命令也是修改指定地址内存值的,使用 mm 修改内存值的时候地址会自增。
  2. mw 命令
    命令 mw 用于使用一个指定的数据填充一段内存,命令格式如下:
mw [.b, .w, .l] address value [count]
  1. 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 为要比较的长度。

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:
mmc dev 1
可以看到切换到了mmc1的分区0,输入命令“mmcinfo”即可查看emmc的信息:
在这里插入图片描述
emmc的容量为7.3G。

  1. mmc part 命令
    有时候 SD 卡或者 EMMC 会有多个分区,可以使用命令“mmc part”来查看其分区,比如查看 当前EMMC 的分区情况
    在这里插入图片描述
    可以看出,此时 EMMC 有两个分区, 第一个分区起始扇区为 8192,长度
    为 81920个扇区; 第二个分区起始扇区为 90112,长度为 15179776个扇区。
  2. mmc 操作命令
    可使用read、write、erase指令对 mmc 存储介质以 block 为操作单位进行读、写、擦除操作。命令格式如下:
 mmc read addr blk# cnt # 读
 mmc write addr blk# cnt # 写
 mmc erase blk# cnt # 擦除

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

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 根文件系统。

  1. fatinfo 命令
    fatinfo 命令用于查询指定 MMC 设备分区的文件系统信息,格式如下:
fatinfo <interface> [<dev[:part]>]

interface 表示接口,比如 mmc, dev 是查询的设备号, part 是要查询的分区。比如我们要查询 EMMC 分区 1 的文件系统信息,命令如下:
在这里插入图片描述
可以看出:EMMC 分区 1 的文件系统为 FAT16 格式的。

  1. fatls 命令
    fatls 命令用于查询 FAT 格式设备的目录和文件信息,命令格式如下:
fatls <interface> [<dev[:part]>] [directory]

interface 是要查询的接口,比如 mmc, dev 是要查询的设备号, part 是要查询的分区, directory是要查询的目录。比如查询 EMMC 分区 1 中的所有的目录和文件,输入命令:
在这里插入图片描述
若想要查看其它目录下的文件列表,只要加上文件路径即可,如下
在这里插入图片描述

  1. 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地址的环境变量:
在这里插入图片描述

  1. dhcp命令
    dhcp 用于从路由器获取 IP 地址,前提得开发板连接到路由器上的,如果开发板是和电脑直连的,那么 dhcp 命令就会失效。直接输入 dhcp 命令即可通过路由器获取到 IP 地址:
    在这里插入图片描述

  2. ping 命令
    开发板的网络能否使用,是否可以和服务器(Ubuntu 主机)进行通信,通过 ping 命令就可以验证,直接 ping 服务器的 IP 地址即可,
    在这里插入图片描述
    可以看出, 192.168.1.6 这个主机存在,说明 ping 成功, uboot 的网络工作正
    常。注意!只能在 uboot 中 ping 其他的机器,其他机器不能 ping uboot,因为 uboot 没有对 ping命令做处理,如果用其他的机器 ping uboot 的话会失败!

  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 地址处,命令如下:
在这里插入图片描述

  1. tftp命令
    tftp 命令的作用和 nfs 命令一样,都是用于通过网络下载东西到 DRAM 中,只是 tftp 命令使用的 TFTP 协议, Ubuntu 主机作为 TFTP 服务器。
    Ubuntu 上搭建 TFTP 服务器,需要安装 tftp-hpa 和 tftpd-hpa,命令如下:
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd

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

mkdir /home/kk/imx6ull/tftpboot/
chmod 777 /home/kk/imx6ull/tftpboot/

最后配置 tftp,安装完成以后新建文件/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
}

完了以后启动 tftp 服务,命令如下:

sudo service tftpd-hpa start

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

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/kk/imx6ull/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"

TFTP_DIRECTORY 就是我们上面创建的 tftp 文件夹目录,以后我们就将所有需要通过TFTP 传输的文件都放到这个文件夹里面,并且要给予这些文件相应的权限。
最后输入如下命令, 重启 tftp 服务器:

sudo service tftpd-hpa restart

uboot 中的 tftp 命令格式如下:

tftpboot [loadAddress] [[hostIPaddr:]bootfilename]

将zImage 文件复制到 tftpboot 文件夹里面的,然后下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
在这里插入图片描述

7. BOOT 操作命令

uboot 的本质工作是引导 Linux,所以 uboot 肯定有相关的 boot(引导)命令来启动 Linux。常用的跟 boot 有关的命令有: bootz、 bootm 和 boot。

  1. bootz 命令
    bootz 命令用于启动 zImage 镜像文件, bootz 命令格式如下:
bootz [addr [initrd[:size]] [fdt]]

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

  1. 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 为空的话,同样是用“-”来替代。

  1. boot 命令
    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 命令最大的作用在于运行我们自定义的环境变量。

  • 9
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WALI-KANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值