文章目录
- 前言
- 一、信息查询命令
- 1.bdinfo用于查看板子的信息
- 2.printenv 打印环境变量
- 3.version查看uboot版本
- 二、环境变量操作命令
- 1.setenv修改环境变量
- 2.setenv新建环境变量
- 3.setenv删除环境变量
- 三、内存操作命令
- 1.md 命令
- 2.nm命令
- 3.mm命令
- 4.mw命令
- 四、网络操作命令
- 1.ping命令
- 2.dhcp 命令
- 3.nfs 命令-数据下载到DRAM
- 4.ftp 命令-数据下载到DRAM
- 五、EMMC 和 SD 卡操作命令
- 1.mmc info 命令
- 2.mmc list 命令
- 3.mmc dev 命令
- 4.mmc part 命令
- 5.mmc read 命令-将MMC数据读到DRAM中
- 6.mmc write 命令-将DRAM数据写入MMC设备
- 7.SD卡分区介绍-补充
- 8.mmc erase 命令
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
一、信息查询命令
💦 常用的信息查询有关的命令有 3 个:
1.bdinfo用于查看板子的信息
2.printenv 打印环境变量
3.version查看uboot版本
二、环境变量操作命令
1.setenv修改环境变量
💦 环境变量的操作涉及到两个命令:setenv 和 saveenv,命令 setenv 用于设置或者修改环境变量的值。
💦 命令 saveenv 用于保存修改后的环境变量。
💦 注意:一般环境变量是存放在外部 flash 中的,当uboot 启动的时候会将环境变量从 flash 读取到 DRAM 中。所以使用命令 setenv 修改的是 DRAM中的环境变量值,修改以后要使用 saveenv 命令将修改后的环境变量保存到 flash 中,否则的话uboot 下一次重启会继续使用以前的环境变量值。
指令实例:将bootdelay由3秒修改成5秒
setenv bootdelay 5
saveenv
💦 因为uboot中的环境变量都是字符串,在我们修改的环境变量可能会有多个值并且相互之间会有空格,比如 bootcmd、bootargs 等,这个时候环境变量值就得用单引号括起来,比如下面修改环境变量 bootargs 的值。
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
💦 解析:
上面命令设置 bootargs 的值为“console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw”,
其中“console=ttymxc0,115200”、“root=/dev/mmcblk1p2”、“rootwait”和“rw”相当于四组“值”,
这四组“值”之间用空格隔开,所以需要使用单引号‘…’将其括起来,表示这四组“值”都属
于环境变量 bootargs。
注意:当使用saveenv的时候,会提示保存在哪里(EMMC,SD卡等外边flash)
2.setenv新建环境变量
💦 命令 setenv 也可以用于新建命令,用法和修改环境变量一样,比如我们新建一个环境变量text,text的值为1,那么就可以使用如下命令:
💦 结果:
3.setenv删除环境变量
💦 删除环境变量也是使用命令 setenv,要删除一个环境变量只要给这个环境变量赋空值即可,比如我们删除text这个环境变量,命令如下:
setenv text
saveenv
三、内存操作命令
💦 内存操作命令就是用于直接对 DRAM 进行读写操作的,常用的内存操作命令有 md、nm、
mm、mw、cp 和 cmp。
1.md 命令
💦 md 命令用于显示内存值,格式如下:
md[.b, .w, .l] address [# of objects]
💦 命令中的[.b .w .l]对应 byte、word 和 long,也就是分别以 1 个字节、2 个字节、4 个字节
来显示内存值。address 就是要查看的内存起始地址,[# of objects]表示要查看的数据长度,这个数据长度单位不是字节,而是跟你所选择的显示格式有关。比如你设置要查看的内存长度为20(十六进制为 0x14),如果显示格式为.b 的话那就表示 20 个字节;如果显示格式为.w 的话就表示 20 个 word,也就是 202=40 个字节;如果显示格式为.l 的话就表示 20 个 long,也就是204=80 个字节。另外要注意:
💦 注意:uboot 命令中的数字都是十六进制的!不是十进制的!
2.nm命令
💦 nm 命令用于修改指定地址的内存值,命令格式如下:
nm [.b, .w, .l] address
💦 nm 命令同样可以以.b、.w 和.l 来指定操作格式.
💦 举例说明:比如现在以.l 格式修改 0x80000000 地址的数据为 0x12345678
💦 第一个“?”后面跟要修改的内容,输入完成后按下回车键,第二后面输入q退出。
使用md命令查看是否修改成功。
3.mm命令
💦 mm 命令也是修改指定地址内存值的,使用 mm 修改内存值的时候地址会自增,而使用命令 nm 的话地址不会自增。
💦 举例说明:
以.l 格式修改从地址 0x80000000 开始的连续 3 个内存块(3*4=12个字节)的数据为0X12345678,使用md命令查看结果如下。
4.mw命令
💦命令 mw 用于使用一个指定的数据填充一段内存,命令格式如下
mw [.b, .w, .l] address value [count]
💦mw 命令同样可以以.b、.w 和.l 来指定操作格式,address 表示要填充的内存起始地址,value为要填充的数据,count 是填充的长度。
💦举例说明:比如使用.l 格式将以 0X80000000 为起始地址的 0x10 个内存块(0x10 * 4=64 字节)填充为 0X01010101,命令如下
mw.l 80000000 01010101 10
四、网络操作命令
💦uboot 是支持网络的,在移植 uboot 的时候一般都要调通网络功能,因为在移植 linux 的时候需要使用到 uboot 的网络功能做调试。
💦u在uboot中与网络相关的环境变量如下:
setenv ipaddr 192.168.1.50
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.255
saveenv
💦注意:网络地址环境变量的设置要根据自己的实际情况,确保== Ubuntu 主机和开发板的 IP地址在同一个网段内==,比如我现在的开发板和电脑都在 192.168.1.0 这个网段内,所以设置开发板的 IP 地址为 192.168.1.50,我的 Ubuntu 主机的地址为 192.168.1.20,因此 serverip 就是192.168.1.20。ethaddr 为网络 MAC 地址,是一个 48bit 的地址,如果在同一个网段内有多个设备的话一定要保证每个开发板的 ethaddr 是不同的,否则通信会有问题。
1.ping命令
💦Ubuntu系统的IP为192.168.1.20
💦alive状态可以看出192.168.1.20这个主机存在,说明 ping 成功,uboot 的网络工作正
常。
💦注意:只能在 uboot 中 ping 其他的机器,其他机器不能 ping uboot,因为 uboot 没有对 ping命令做处理,如果用其他的机器 ping uboot 的话会失败!
2.dhcp 命令
💦dhcp 用于从路由器获取 IP 地址,前提得开发板连接到路由器上的,如果开发板是和电脑直连的,那么 dhcp 命令就会失效。直接输入 dhcp 命令即可通过路由器获取到 IP 地址。
3.nfs 命令-数据下载到DRAM
💦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 目录中。
💦格式如下:
nfs [loadAddress] [[hostIPaddr:]bootfilename]
💦loadAddress 是要保存的 DRAM 地址,[[hostIPaddr:]bootfilename]是要下载的文件地址,这
里我们将正点原子官方编译出来的 Linux 镜像文件 zImage 下载到开发板 DRAM 的 0x80800000这个地址处。
💦准备好以后就可以使用 nfs 命令来将 zImage 下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
nfs 80800000 192.168.1.20:/home/che/linux/nfs/zImage
💦注意:如果nfs使用报错,请查看博主另外一个文章,已经帮助各位踩过坑了。
4.ftp 命令-数据下载到DRAM
💦步骤:
💦创建tfpt文件夹
💦修改文件夹权限
💦配置 tftp,安装完成以后新建文件/etc/xinetd.d/tftp,如果没有/etc/xinetd.d 目录的话自行 创建,然后在里面输入如下内容:
💦tftp文件内容:
💦打开/etc/default/tftpd-hpa 文件
💦TFTP_DIRECTORY 就是我们上面创建的 tftp 文件夹目录,以后我们就将所有需要通过TFTP 传输的文件都放到这个文件夹里面,并且要给予这些文件相应的权限。
💦最后重启服务
sudo service tftpd-hpa start
💦uboot 中的 tftp 命令格式如下:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
💦看 起来 和 nfs 命令格 式一 样的 , loadAddress 是文 件在 DRAM 中的 存放 地址 ,[[hostIPaddr:]bootfilename]是要从 Ubuntu 中下载的文件。但是和 nfs 命令的区别在于,tftp 命令不需要输入文件在 Ubuntu 中的完整路径,只需要输入文件名即可。比如我们现在将 tftpboot 文件夹里面的 zImage 文件下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
tftp 80800000 zImage
五、EMMC 和 SD 卡操作命令
💦uboot 支持 EMMC 和 SD 卡,所以提供 EMMC 和 SD 卡的操作命令。在Linux中,一般认为 EMMC和 SD 卡属于用一类型存储设备(mmc设备),所以可以使用 MMC 来代指 EMMC 和 SD 卡。
💦boot 中常用于操作 MMC 设备的命令为“mmc”。
💦mmc 是一系列的命令,其后可以跟不同的参数,输入“?mmc”即可查看 mmc 有关的命令。
1.mmc info 命令
💦当前选中的 MMC 设备是SD卡,版本为 3.0,容量为 14.4GiB,速度为 50000000Hz=50MHz,4 位宽的总线。
2.mmc list 命令
💦mmc list 命令用于来查看当前开发板一共有几个 MMC 设备,输入“mmc list”
3.mmc dev 命令
💦mmc dev 命令用于切换当前 MMC 设备,命令格式如下
mmc dev [dev] [part]
💦[dev]用来设置要切换的 MMC 设备号,[part]是分区号。如果不写分区号的话默认为分区 0。
mmc dev 1 //切换到 emmc ,0 为 SD 卡,1 为 eMMC
4.mmc part 命令
💦有时候 SD 卡或者 EMMC 会有多个分区,可以使用命令“mmc part”来查看其分区,比如
查看 EMMC 的分区情况,输入如下命令:
mmc dev 1 //切换到 EMMC
mmc part //查看 EMMC 分区
💦此时 EMMC 有两个分区,第一个分区起始扇区为 20480,长度为 262144 个扇区;第二个分区起始扇区为 282624,长度为 14594048 个扇区。
💦如果 EMMC 里面烧写了 Linux 系统的话,EMMC 是有 3 个分区的,第 0 个分区存放 uboot,第 1 个分区存放Linux 镜像文件和设备树,第 2 个分区存放根文件系统。但是在上图只有两个分区,那是因为第 0 个分区没有格式化,所以识别不出来,实际上第 0 个分区是存在的。
💦一个新的 SD卡默认只有一个分区,那就是分区 0,所以前面讲解的 uboot 烧写到 SD 卡,其实就是将 u-boot.bin烧写到了 SD 卡的分区 0 里面。当Linux 内核移植的时候在 SD 卡中创建并格式化第二个分区,并将 Linux 镜像文件和设备树文件存放到第二个分区中。
如果要将 EMMC 的分区 2 设置为当前 MMC 设备,可以使用如下命令:
mmc dev 1 2
5.mmc read 命令-将MMC数据读到DRAM中
💦mmc read 命令用于读取 mmc 设备的数据,命令格式如下:
mmc read addr blk# cnt
💦addr 是数据读取到 DRAM 中的地址,blk 是要读取的EMMC块起始地址(十六进制),一个块是 512字节,这里的块和扇区是一个意思,在 MMC 设备中我们通常说扇区,cnt 是要读取的块数量(十六进制)。
💦举例:比如从 EMMC 的第 1536(0x600)个块开始,读取 16(0x10)个块的数据到 DRAM 的0X80800000 地址处,命令如下:
mmc dev 1 0 //切换到 MMC 分区 0
mmc read 80800000 600 10 //读取数据
💦查看下读取是否正确,通过 md.b 命令查看 0x80800000 处的数据,查
看 16*512=8192(0x2000)个字节的数据,命令如下:
md.b 80800000 2000
💦可以看到“baudrate=115200.board_name=EVK.board_rev=14X14.”等字样,
这个就是 uboot 中的环境变量。EMMC 核心板 uboot 环境变量的存储起始地址就是
1536*512=786432。
6.mmc write 命令-将DRAM数据写入MMC设备
💦要将数据写到 MMC 设备里面,可以使用命令“mmc write”,格式如下:
mmc write addr blk# cnt
addr 是要写入 MMC 中的数据在 DRAM 中的起始地址,blk 是要写入 MMC 的块起始地址
(十六进制),cnt 是要写入的块大小,一个块为 512 字节。我们可以使用命令“mmc write”来升
级 uboot,也就是在 uboot 中更新 uboot。这里要用到 nfs 或者 tftp 命令,通过 nfs 或者 tftp 命令将新的 u-boot.bin 下载到开发板的 DRAM 中,然后再使用命令“mmc write”将其写入到 MMC
设备中。我们就来更新一下 SD 中的 uboot,先查看一下 SD 卡中的 uboot 版本号,注意编译时间,输入命令:
mmc dev 0 //切换到 SD 卡
version //查看版本号
💦可以看出当前 SD 卡中的 uboot 是 2024 年 4 月 5日 编译的。我们现在重新编译一下 uboot,然后将编译出来的 u-boot.imx(u-boot.bin 前面加了一些头文件)拷贝到 Ubuntu 中的tftpboot 目录下。最后使用 tftp 命令将其下载到 0x80800000 地址处,命令如下:
tftp 80800000 u-boot.imx
💦u-boot.imx 大小为 363520 字节,363520/512=710,所以我们要向 SD 卡中写入710个块,如果有小数的话就要加 1 个块。使用命令“mmc write”从 SD 卡分区 0 第 2 个块(扇区)开始烧写,一共烧写 710(0x2C6)个块,命令如下:
mmc dev 0 0
mmc write 80800000 2 2E6
💦重启开发板验证,可以看到日期是晚上8点多,与上述日期不一致,更新成功。
💦要更新 EMMC 中的 uboot 也是一样的。
如果要在 uboot 中更新 EMMC 对应的 uboot,可以使用如下所示命令:
mmc dev 1 0 //切换到 EMMC 分区 0
tftp 80800000 u-boot.imx //下载 u-boot.imx 到 DRAM
mmc write 80800000 2 32E //烧写 u-boot.imx 到 EMMC 中
mmc partconf 1 1 0 0 //分区配置,EMMC 需要这一步!
💦注意:千万不要写 SD 卡或者 EMMC 的前两个块(扇区),里面保存着分区表!
7.SD卡分区介绍-补充
8.mmc erase 命令
💦如果要擦除 MMC 设备的指定块就是用命令“mmc erase”,命令格式如下:
mmc erase blk# cnt
💦blk 为要擦除的起始块,cnt 是要擦除的数量。没事不要用 mmc erase 来擦除 MMC 设备。