目录
网络操作命令
uboot是支持网络的,我们在移植uboot的时候一般都要调通网络功能,因为在移植linuxkernel的时候需要使用到uboot的网络功能做调试。uboot支持大量的网络相关命令,比如dhcp、ping、nfs 和 tftpboot,接下来依次学习一下这几个和网络有关的命令。
设置开发板IP地址
注意,网络地址环境变量的设置要根据自己的实际情况,确保Ubuntu主机和开发板的IP地址在同一个网段内,比如我现在的开发板和电脑都在192.168.31.0这个网段内,所以设置开发板的IP地址为192.168.31.131,我的Ubuntu主机的地址为192.168.31.131,因此serverip就192.168.31.131.ethaddr为网络MAC地址,是一个48bit的地址,如果在同一个网段内有多个开发板的话一定要保证每个开发板的ethaddr是不同的,否则通信会有问题!设置好网络相关的环境变量以后就可以使用网络相关命令了。
ping命令
开发板的网络能否使用,是否可以和服务器(Ubuntu主机)进行通信,通过ping命令就可以验证,直接ping服务器的IP地址即可,比如我的服务器IP地址为192.168.31.130,命令如下:
ping 192.168.31.130
从图30.4.4.2可以看出, 192.168.31.130这个主机存在,说明ping成功, uboot的网络工作正常。
注意!只能在uboot中ping其他的机器,其他机器不能ping uboot,因为uboot 没有对ping命令做处理,如果用其他的机器ping uboot的话会失败!
nfs 命令
nfs(Network File System)网络文件系统,通过nfs可以在计算机之间通过网络来分享资源,比如我们将linux镜像和设备树文件放到Ubuntu中,然后在uboot中使用nfs命令将Ubuntu中的linux镜像和设备树下载到开发板的DRAM中。这样做的目的是为了方便调试linux镜像和设备树,也就是网络调试,通过网络调试是Linux开发中最常用的调试方法。原因是嵌入式linux开发不像单片机开发,可以直接通过JLINK或STLink等仿真器将代码直接烧写到单片机内部的flash中,嵌入式Linux通常是烧写到EMMC、NAND Flash、SPI Flash等外置flash中,但是嵌入式Linux开发也没有MDK, IAR这样的IDE,更没有烧写算法,因此不可能通过点击一个“download”按钮就将固件烧写到外部flash中。虽然半导体厂商一般都会提供一个烧写固件的软件,但是这个软件使用起来比较复杂,这个烧写软件一般用于量产的。其远没有MDK、IAR的一键下载方便,在Linux内核调试阶段,如果用这个烧写软件的话将会非常浪费时间,而这个时候网络调试的优势就显现出来了,可以通过网络将编译好的linux镜像和设备树文件下载到DRAM中,然后就可以直接运行。
我们一般使用uboot中的nfs命令将Ubuntu中的文件下载到开发板的DRAM中,在使用之前需要开启Ubuntu主机的NFS服务,并且要新建一个NFS使用的目录,以后所有要通过NFS访问的文件都需要放到这个NFS目录中。Ubuntu的NFS服务开启uboot中的nfs命令格式如下所示:
nfs [loadAddress] [[hostiPaddr:]bootfilename]
loadAddress是要保存的DRAM地址, [[hostlPaddr:]bootfilename]是要下载的文件地址。这里我们将正点原子官方编译出来的Linux镜像文件zImage下载到开发板DRAM的0x80800000这个地址处。将文件zImage通过FileZilla发送到Ubuntu 中的NFS 目录下, 比如我的就是放到/home/ygh/linux/nfs这个目录下,完成以后的NFS目录如图所示:
准备好以后就可以使用nfs命令来将zImage下载到开发板DRAM的0X80800000地址处,命令如下:
nfs 80800000 192.168.31.130:/home/ygh/linux/nfs/zImage
其中的80800000表示zImage保存地址"192.168.1.253:/home/ygh/linux/nfs/zImage"表示zImage在192.168.31.130这个主机中,路径为/home/ygh/linux/nfs/zImage。下载过程如图所示:
在图中会以“#”提示下载过程,下载完成以后会提示下载的数据大小,这里下载的 5636216字节(出厂系统在不断的更更新中,因此以实际的zImage大小为准),而zImage的大小就是 6785272字节,如图 所示:
下载完成以后查看0x80800000地址处的数据,使用命令md.b来查看前0x100个字节的数据,如图所示:
在使用vscode HexEditor插件来查看zImage,检查一下前面的数据是否和图的一致,结果如图所示:
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/ygh/linux/tftpboot
chmod 777 /home/zuozhongkai/linux/tftpboot
这样我就在我的电脑上创建了一个名为tftpboot的目录(文件夹),路径为/home/ygh/linux/tftpboot。注意!我们要给tftpboot文件夹权限,否则的话uboot不能从tftpboot文件夹里面下载文件。
最后配置tftp,安装完成以后新建文件/etc/xinetd.d/tftp,如果没有/etc/xinetd.d目录的话自行创建,然后在里面输入如下内容:
完了以后启动tfp服务,命令如下:
sudo service tftpd-hpa start
打开/etc/default/tftpd-hpa文件,将其修改为如下所示内容:
TFTP_DIRECTORY就是我们上面创建的tftp文件夹目录,以后我们就将所有需要通过,TFTP传输的文件都放到这个文件夹里面,并且要给予这些文件相应的权限。
最后输入如下命令,重启tftp服务器:
sudo service tftpd-hpa restart
tftp服务器已经搭建好了,接下来就是使用了。将zImage镜像文件拷贝到tfpboot文件夹中,并且给予zimage相应的权限,命令如下:
cp zImage /home/ygh/linux/tftpboot/
cd /home/ygh/linux/tftpboot/
chmod 777 zImage
uboot中的tftp命令格式如下:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
看起来和nfs命令格式一样的,loadAddress是文件在DRAM中的存放地址,[[hostIPaddr:]bootfilename]是要从Ubuntu中下载的文件。但是和nfs命令的区别在于,tftp命令不需要输入文件在Ubuntu中的完整路径,只需要输入文件名即可。比如我们现在将tftpboot文件夹里面的zImage文件下载到开发板DRAM的0X80800000地址处,命令如下:
tftp 80800000 zImage
下载过程如图所示:
从图可以看出, zImage下载成功了,网速为1.1MibB/s,文件大小为5636216字节。同样的,可以使用md.b命令来查看前100个字节的数据是否和图中的相等。有时候使用tftp命令从Ubuntu中下载文件的时候会出现如图所示的错误提示:
在图中可以看到"TFTPerror: "Permission denied' (0)”这样的错误提示,提示没有权限,出现这个错误一般有两个原因:
1.在Ubuntu中创建tftpboot目录的时候没有给予tftboot相应的权限。
2.tftpboot目录中要下载的文件没有给予相应的权限。
针对上述两个问题,使用命令“chmod 777 xxx”来给予权限,其中“xxx”就是要给予权限的文件或文件夹。
EMMC和SD卡操作命令
uboot支持EMMC和SD卡,因此也要提供EMMC和SD卡的操作命令。一般认为EMMC和 SD卡是同一个东西,所以没有特殊说明统一使用MMC来代指EMMC和SD卡。uboot 中常用于操作MMC设备的命令为“mmc”。mmc是一系列的命令,其后可以跟不同的参数,输入“? mmc”即可查看 mmc 有关的命令,如图所示:
mmc info命令
mmc info命令用于输出当前选中的mmc info设备的信息,输入命令“mmc info”即可,如图所示:
从图可以看出,当前选中的MMC设备是SD卡,版本为3.0,容量为29.1GiB(EMMC为32GB),速度为50000000Hz=50MHz, 4位宽的总线。还有一个与mmc info命令相同功能的命令: mmcinfo, "mmc”和"info”之间没有空格。
mmc rescan命令
mmc rescan命令用于扫描当前开发板上所有的MMC设备,包括EMMC和SD卡,输入"mmc rescan”即可。
mmc list 命令
mme list命令用于来查看当前开发板一共有几个MMC设备,输入"mmc list”,结果如图所示:
可以看出当前开发板有两个MMC设备: FSL-SDHC:0和FSL-SDHC:1 (eMMC),这是因为我现在用的是EMMC版本的核心板,加上SD卡一共有两个MMC设备, FSL-SDHC:0是SD卡, FSL-SDHC:1(eMMC)是EMMC,。默认会将EMMC设置为当前MMC设备,这就是为什么输入"mme info”查询到的是SD卡设备信息,而不是EMMC。要想查看 EMMC信息,就要使用命令“mme dev”来将EMMC卡设置为当前的MMC设备。
mmc dev 命令
mmc dev命令用于切换当前MMC设备,命令格式如下:
mmc dev [dev] [part]
[dev]用来设置要切换的MMC设备号,[part]是分区号。如果不写分区号的话默认为分区0。使用如下命令切换到SD卡:
mmc dev 1//切换到EMMC卡,0为SD卡,1为eMMC
从图可以看出,当前选中的MMC设备是EMMC,版本为4.0,容量为7.3GiB(EMMC为8GB),速度为52000000Hz=52MHz, 8位宽的总线。
mmc part命令
有时候SD卡或者EMMC会有多个分区,可以使用命令"mme part”来查看其分区,比如查看EMMC的分区情况,输入如下命令:
从图中可以看出,此时EMMC有两个分区,第一个分区起始扇区为20480,长度为262144个扇区;第二个分区起始扇区为282624,长度为14987264个扇区。如果EMMC里面烧写了Linux系统的话, EMMC是有3个分区的,第0个分区存放uboot,第1个分区存放Linux镜像文件和设备树,第2个分区存放根文件系统。但是在图中只有两个分区,那是因为第0个分区没有格式化,所以识别不出来,实际上第0个分区是存在的。
mmc read 命令
mmc read命令用于读取mmc设备的数据,命令格式如下:
mmc read addr blk# cnt
addr是数据读取到DRAM中的地址,blk是要读取的块起始地址(十六进制),一个块是512字节,这里的块和扇区是一个意思,在MMC设备中我们通常说扇区,cnt 是要读取的块数量(十六进制)。比如从EMMC的第 1536(0x600)个块开始,读取16(0x10)个块的数据到DRAM的0X80800000地址处,命令如下:
mmc read 80800000 600 10//读取数据
这里我们还看不出来读取是否正确,通过md.b命令查看0x80800000处的数据就行了,查看 16*512=8192(0x2000)个字节的数据,命令如下:
md.b 80800000 2000
mmc write 命令
要将数据写到MMC设备里面,可以使用命令"mme write",格式如下:
mmc write addr blk# cnt
addr是要写入MMC中的数据在DRAM中的起始地址, blk是要写入MMC的块起始地址(十六进制), cnt是要写入的块大小,一个块为512字节。我们可以使用命令“mmc write”来升级 uboot,也就是在uboot中更新uboot。这里要用到nfs或者tftp命令,通过nfs或者tfp命令将新的u-boot.bin下载到开发板的DRAM中,然后再使用命令"mmc write"将其写入到MMC设备中。我们就来更新一下SD中的uboot,先查看一下SD卡中的uboot版本号,注意编译时间,输入命令:
Version
可以看出当前SD卡中的uboot是2020年3月12日15:11:51编译的。我们现在重新编译一下uboot,然后将编译出来的u-boot.imx(u-boot.bin前面加了一些头文件)拷贝到Ubuntu 中的tftpboot目录下。最后使用tftp命令将其下载到0x80800000地址处,命令如下:
tftp 80800000 u-boot.imx
可以看出, u-boot.imx大小为379904字节, 379904/512=742,所以我们要向SD卡中写入742个块,如果有小数的话就要加1个块。使用命令"mme write”从SD卡分区0第2个块(扇区)开始烧写,一共烧写742(0x2E6)个块,命令如下:
mmc write 80800000 2 2E6
烧写成功,重启开发板(从SD卡启动),重启以后再输入version来查看版本号,结果如图所示:
从图可以看出,此时的uboot是2020年10月27号11:44:31编译的,说明uboot更新成功。这里我们就学会了如何在uboot中更新uboot了,如果要更新EMMC中的uboot t是一样的。
同理,如果要在uboot中更新EMMC对应的uboot,可以使用如下所示命令:
mmc erase 命令
如果要擦除MMC设备的指定块就是用命令"mmc erase”,命令格式如下:
mmc erase blk# cnt
blk为要擦除的起始块,cnt是要擦除的数量。没事不要用mmc erase来擦除MMC设备!!!
FAT 格式文件系统操作命令
有时候需要在uboot中对SD卡或者EMMC中存储的文件进行操作,这时候就要用到文件操作命令,跟文件操作相关的命令有: fatinfo、fatls、fstype、fatload和fatwrite,但是这些文件操作命令只支持FAT格式的文件系统!
fatinfo 命令
fatinfo命令用于查询指定MMC设备分区的文件系统信息,格式如下:
fatinfo <interface> [<dev[:part]>]
interface表示接口,比如mmc, dev是查询的设备号, part是要查询的分区。比如我们要查询EMMC分区1的文件系统信息,命令如下:
fatinfo mmc 1:1
从上图可以看出,EMMC分区1的文件系统为FAT32格式的。
fatls 命令
fatls 命令用于查询FAT格式设备的目录和文件信息,命令格式如下:
fatls <interface> [<dev[:part]>] [directory]
interface是要查询的接口,比如mmc, dev是要查询的设备号,part是要查询的分区,directory是要查询的目录。比如查询EMMC分区1中的所有的目录和文件,输入命令:
fatls mmc 1:1
从上图可以看出, emmc的分区1中存放着8个文件。
fstype 命令
fstype用于查看MMC设备某个分区的文件系统格式,命令格式如下:
fstype <interface> <dev>:<part>
正点原子EMMC核心板上的EMMC默认有3个分区,查看一下这三个分区的文件系统格式,输入命令:
fstype mmc 1:0
fstype mmc 1:1
fstype mmc 1:2
从上图可以看出,分区0格式未知,因为分区0存放的uboot,并且分区0没有格式化,所以文件系统格式未知。分区1的格式为fat,分区1用于存放linux镜像和设备树。分区 2的格式为 ext4,用于存放Linux的根文件系统(rootfs)。
fatload 命令
fatload命令用于将指定的文件读取到DRAM中,命令格式如下:
fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]
interface为接口,比如mmc, dev是设备号, part是分区, addr是保存在DRAM中的起始地址, filename是要读取的文件名字。bytes表示读取多少字节的数据,如果bytes为0或者省略的话表示读取整个文件。pos是要读的文件相对于文件首地址的偏移,如果为0或者省略的话表示从文件首地址开始读取。我们将EMMC分区1中的zImage文件读取到DRAM中的0X80800000地址处,命令如下:
fatload mmc 1:1 80800000 zImage
从上图可以看出在225ms内读取了6785272个字节的数据,速度为28.8MiB/s,速度是非常快的,因为这是从EMMC里面读取的,而EMMC是8位的,速度肯定会很快的。
fatwrite 命令
注意!uboot默认没有使能fatwrite命令,需要修改板子配置头文件,比如mx6ullevk.h、mx6ull_alientek_emmc.h等等,板子不同,其配置头文件也不同。找到自己开发板对应的配置头文件然后添加如下一行宏定义来使能fatwrite命令:
#define CONFIG FAT WRITE /*使能fatwrite命令*/
fatwirte命令用于将DRAM中的数据写入到MMC设备中,命令格式如下:
fatwrite <interface> <dev[:part]> <addr> <filename> <bytes>
interface为接口,比如mmc, dev是设备号,part是分区,addr是要写入的数据在DRAM中的起始地址,filename是写入的数据文件名字,bytes表示要写入多少字节的数据。我们可以通过fatwrite命令在uboot中更新linux镜像文件和设备树。我们以更新linux镜像文件zImage为例,首先将正点原子IMX6U-ALPHA开发板提供的zImage镜像文件拷贝到Ubuntu中的tftnboot且录下。
拷贝完成以后使用命令tftp将zImage下载到DRAM的0X80800000地址处,命令如下:
tftp 80800000 zImage
zImage大小为6785272(0X6788f8)个字节(注意,由于开发板系统在不断的更新中,因此zImage大小不是固定的,一切以实际大小为准),接下来使用命令fatwrite将其写入到EMMC 的分区1中,文件名字为zImage,命令如下:
fatwrite mmc 1:1 80800000 zImage 6788f8
完成以后使用"fatls”命令查看一下EMMC分区1里面的文件,结果如图所示:
EXT 格式文件系统操作命令
uboot有ext2和ext4这两种格式的文件系统的操作命令,常用的就四个命令,分别为:ext2load、ext2ls、ext4load、ext4ls和 ext4write。这些命令的含义和使用与fatload、fatls 和fatwrite一样,只是ext2和ext4都是针对ext文件系统的。比如ext4ls命令,EMMC的分区 2就是ext4格式的,使用ext4ls就可以查询EMMC的分区2中的文件和目录,输入命令:
ext4ls mmc 1:2