U-Boot命令解析

U-Boot命令解析

第一节 U-Boot中命令的定义方式

        uboot中使用U_BOOT_CMD来定义命令,宏U_BOOT_CMD定义在文件include/command.h中,定义如下:

#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)            \

       U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)

       U_BOOT_CMD命令以dhcp命令为例:

dhcp命令宏定义

U_BOOT_CMD(dhcp,3,1,do_dhcp,”boot image via network using DHCP/TFTP protocol”,”[localAddress] [[hostIPaddr:]bootfilename]”);

       展开以后的模样:

dhcp命令展开

U_BOOT_CMD(dhcp,3,1,do_dhcp,”boot image via network using DHCP/TFTP protocol”,”[localAddress] [[hostIPaddr:]bootfilename]”);

1.U_BOOT_CMD展开后为:

U_BOOT_CMD_COMPLETE(dhcp,3,1,do_dhcp,”boot image via network using DHCP/TFTP protocol”,”[localAddress] [[hostIPaddr:]bootfilename]”,NULL);

2.U_BOOT_CMD_COMPLETE展开后为:

ll_entry_declare(cmd_tbl_t,dhcp,cmd) = \

U_BOOT_CMD_MKENT_COMPLETE(dhcp,3,1,do_dhcp,”boot image via network using DHCP/TFTP protocol”,”[localAddress] [[hostIPaddr:]bootfilename]”,NULL);

3.ll_entry_declareU_BOOT_CMD_MKENT_COMPLETE展开后为:

cmd_tbl_t u_boot_list_2_cmd_2_dhcp __aligned(4) \

 __attribute__((unused,section(.u_boot_list_2_cmd_2_dhcp))) \

{ dhcp,3,1,do_dhcp,”boot image via network using DHCP/TFTP protocol”,”[localAddress] [[hostIPaddr:]bootfilename]”,NULL}

       最终展开结果:

dhcp命令最终结果

1    cmd_tbl_t u_boot_list_2_cmd_2_dhcp __aligned(4) \

2    __attribute__((unused,section(.u_boot_list_2_cmd_2_dhcp))) \

3    { dhcp,3,1,do_dhcp, \

4    ”boot image via network using DHCP/TFTP protocol”, \

5    ”[localAddress] [[hostIPaddr:]bootfilename]”, \

6    NULL}

       第1行定义了一个cmd_tbl_t类型的变量,变量名为u_boot_list_2_cmd_2_dhcp,此变量4字节对齐。

  第2行,使用__attribute__关键字设置变量u_boot_list_2_cmd_2_dhcp存储在.u_boot_list_2_cmd_2_dhcp段中。u-boot.lds链接脚本中有一个名为“.u_boot_list”的段,所有.u_boot_list开头的段都存放到.u_boot.list中。

       总结:

(1)在command目录下有很多cmd_name.c类似的文件。每个文件都传建一个cmd_tbl_t结构体并存在.u_boot_list段中。主要指定名字和所要执行的函数do_name

(2)run_command函数接受参数,解析,然后根据参数第一个单词,遍历.u_boot_list段,找到name相同的结构体,调用该结构体的do_name函数。

第二节 U-Boot命令的使用

2.1 help命令

输入help或问号,即可查看某一个命令帮助信息。

使用方法:(1)help或? 命令名;(2)help或?

如help boot或? boot,即可查看boot命令的帮助信息。

2.2 信息查询

1.bdinfo

       打印板子信息。

2.printenv

       查看当前板子的环境变量。

2.3 setenv命令

设置环境变量,也可以自定义环境变量,也可以删除环境变量。

如更改倒计时时间bootdelay为3秒,可使用命令setenv bootdelay 3,然后输入命令saveenv保存环境变量回eMMC即可。

而如果要设置复杂的环境变量,如一串字符串时,则需要使用命令 setenv 环境变量名 ‘字符串’.

setenv一个不存在的环境变量,如setenv author yky,即可创造一个环境变量author,值为yky。

setenv环境变量,即可删除这个环境变量。

2.4 saveenv命令

       保存环境变量。

2.5 内存操作命令

1.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,也就是20*2=40个字节;如果显示格式为.l就表示20个long,也就是80个字节。另外要注意:uboot命令中的数字都是十六进制的,不是十进制的!

       如想查看已0x80000000开始的20个字节的内存值,显示格式为.b的话,应该使用如下所示命令:

       md.b 80000000 14而不是md.b 80000000 20

2.nm

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

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

       nm命令同样可以以.b、.w和.l来指定操作格式,比如现在以.l格式修改0x80000000地址的数据为0x12345678。输入命令:

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

       此时会弹出 80000000: ffffff00 ?。ffffff00表示0x80000000现在的数据,?后面就可以输入要修改后的数据0x12345678,输入完成后按下回车,然后在输入’q’即可退出,即:

80000000: ffffff00 ? 12345678

80000000:12345678 ? q

3.mm

       mm命令也是修改指定地址内存值的,使用mm修改内存值的时候地址会自增,而使用命令nm的话地址不会自增。比如以.l格式修改地址0x80000000开始的连续3个内存块(3*4=12个字节)的数据为0x05050505,操作如图1所示。

图1 mm命令

4.mw

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

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

       mw命令同样可以以.b、.w和.l来指定操作格式,address表示要填充的内存起始地址,value为要填充的数据,count是填充的长度 。比如使用.l格式将以0x80000000为起始地址的0x10个内存块(0x10*4=64字节)填充为0x0A0A0A0A,命令如下:

mw.l 80000000 0A0A0A0A 10

5.cp

       cp是数据拷贝命令,用于将DRAM中的数据从一段内存拷贝到另一段内存中,或者把Nor Flash中的数据拷贝到DRAM中。命令格式如下:

cp[.b,.w,.l] source target count

       cp命令同样可以以.b、.w和.l来指定操作格式,source为源地址,target为目的地址,count为拷贝的长度。我们使用.l格式将0x80000000处的地址拷贝到0x80000100处,长度为0x10个内存块(0x10*4=64字节),命令如下所示:

cp.l 80000000 80000100 10

6.cmp

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

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

       cp命令同样可以以.b、.w和.l来指定操作格式,addr1为第一段内存首地址,addr2为第二段内存首地址,count为要比较的长度。我们使用.l格式来比较0x80000000和0x80000100这两个地址数据是否相等,比较长度为0x10个内存块(0x10*4=64字节),命令如下所示:

cmp.l 80000000 80000100 10

2.6 网络操作命令

1.ping

       测试网络是否连通

2.dhcp

       由系统自动分配ip地址。

       注意:通过DHCP命令获取到的IP地址仅本次有效,不会修改环境变量中ipaddr的值,下次重启以后依旧用的ipaddr里面的地址!除非使用saveenv将地址保存会eMMC中存储的环境变量方可永久保存。

3.nfs

       也就是网络文件系统,可通过nfs命令将文件系统挂载到指定ip地址的指定目录。其实目的就是为了调试代码。

用法:nfs [localAddress] [[hostIPaddr:]bootfilename]

如:nfs 80800000 192.168.31.80:/home/yky/nfs_rootfs

4.tftp

       用于到指定ip地址的指定目录下载指定文件到开发板的指定地址中。

       注意:在指定ip地址上需要先按照tftp-hpatftpd-hpa

2.7 EMMC和SD卡操作命令

1.mmc info

显示当前mmc设备的信息

2.mmc rescan

重新扫描mmc设备

3.mmc part

列出当前mmc设备的分区情况

4.mmc dev [dev] [part]

显示或设置当前mmc设备

5.mmc list

列出所有可用的mmc设备

6.mmc read

用于读取mmc设备的数据,命令格式如下:

mmc read addr blk# cnt

       addr是数据读取到DRAM中的地址,blk是要读取的块起始地址(十六进制),一个块是512字节,这里的块和扇区是一个意思,cnt是要读取的块数量(十六进制)。比如从EMMC的第1536(0x600)个块开始,读取16(0x10)个块的数据到DRAM的0x80800000地址处,命令如下:

mmc dev 1 0  //切换到MMC分区0

mmc read 80800000 600 10  //读取数据

7.mmc write

用于将数据写到mmc设备里面,命令格式如下:

mmc write addr blk# cnt

       addr是要写入mmc中的数据在DRAM中的起始地址,blk是要写入mmc的块起始地址(十六进制),一个块是512字节,这里的块和扇区是一个意思,cnt是要读取的块数量(十六进制)。我们可以使用命令“mmc write”来升级uboot,也就是在uboot中更新uboot。这里要用到nfs或者tftp命令,通过nfs或tftp命令将新的u-boot.stm32下载到开发板的DRAM中,然后再使用命令“mmc write”将其写入到mmc设备中。

8.mmc erase

如果要擦除mmc设备的指定块就是用命令“mmc erase”,命令格式如下:

mmc erase blk# cnt

       blk为要擦除的起始块,cnt是要擦除的数量。没事不要用mmc erase来擦除mmc设备!!!

2.8 文件操作命令

1.fstype命令

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

fstype <interface> <dev>:<part>

       如AHL-STM32MP157核心板上的EMMC默认有3个分区,我们可以查看这三个分区的文件系统格式,输入命令:

fstype mmc 1:1

fstype mmc 1:2

fstype mmc 1:3

       显示结果如图4-2所示。

图4-2 fstype查看开发板分区文件系统格式

2.ext4load

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

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

       interface为借口,如mmc;dev是设备号;part是分区;addr是保存在DRAM中的起始地址;filename是要读取的文件名字;bytes表示读取多少字节的数据,如果bytes为0或者省略的话表示读取整个文件;pos是要读的文件相对于文件首地址的偏移,如果为0或者省略的话表示从文件首地址开始读取。我们将EMMC分区2中的uImage文件读取到DRAM中的0xc2000000地址处,命令如下:

ext4load mmc 1:2 c2000000 uImage

3.ext4ls

       列出指定mmc设备的指定分区中的文件和目录,命令格式如下:

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

如输入命令,查看EMMC的分区2中文件和目录:

ext4ls mmc 1:2

       显示结果如图4-3所示:

图4-3 ext4ls列出EMMC的分区2中文件和目录

2.9 BOOT操作命令

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

1.bootz命令

       要启动Linux必须将zImage和dtb放到DRAM。然后使用bootz命令来启动,bootz命令用来自启动zImage镜像文件,bootz命令格式如下:

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

       addr是Linux镜像文件在DRAM中的位置,initrd是initrd文件在DRAM中的地址,如果不使用initrd的话使用’-’代替即可,fdt就是设备树文件在DRAM中的地址。现在我们使用网络和EMMC两种方法来启动Linux系统,首先通过tftp命令下载Linux镜像zImage和设备树dtb文件下载到开发板的指定地址,然后使用bootz命令启动:

bootz c2000000 – c4000000

2.go命令

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

go addr [arg…]

       addr是应用在DRAM中的首地址。

       可以使用go命令来运行DRAM指定地址上的程序,也就是可以用来运行裸机程序

3.run命令

       run命令用于运行环境变量中定义的命令,比如可以通过“run bootcmd”来运行bootcmd中的启动命令,但是run命令最大的作用在于运行我们自定义的环境变量。如运行AHL-STM32MP157开发板时,输入命令run bootcmd_stm32mp即可。

4.mtest命令

       mtest命令是一个简单的内存读写测试命令,可以用来测试自己开发板上的DDR,命令格式如下:

mtest [start [end [pattern [iterations]]]]

       start是要测试的DRAM开始地址,end是结束地址,比如我们测试0x80000000~0x80001000这段内存,输入“mtest 80000000 80001000”。

后记

        本文中仅包括U-Boot中的部分命令,更多命令欢迎各位在评论区讨论和反馈!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猿神出世

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

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

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

打赏作者

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

抵扣说明:

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

余额充值