《uboot基础命令记录①》

《uboot基础命令记录①》

之前学习了uboot的一些基础命令,这里想写一篇博客记录一下

参考文档:<正电原子驱动开发指南>


1.信息查询命令

  1. bdinfo

    这里会打印一些开发板的基本信息,如:

    DRAM 的起始地址和大小、启动参数保存起始地址、波特率、sp(堆栈指针)起始地址等信息。

    => bdinfo
    
    arch_number = 0x00000000
    boot_params = 0x80000100
    DRAM bank   = 0x00000000
    -> start    = 0x80000000
    -> size     = 0x20000000
    eth0name    = FEC1
    ethaddr     = (not set)
    current eth = FEC1
    ip_addr     = <NULL>
    baudrate    = 115200 bps
    TLB addr    = 0x9FFF0000
    relocaddr   = 0x9FF55000
    reloc off   = 0x18755000
    irq_sp      = 0x9EF52EA0
    sp start    = 0x9EF52E90
    
    
  2. printenv

    打印开发板的一些环境变量

    => printenv 
    
    author=Yunes
    baudrate=115200
    board_name=EVK
    board_rev=14X14
    boot_fdt=try
    bootcmd=run findfdt;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
    bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
    bootdelay=5
    bootscript=echo Running bootscript from mmc ...; source
    console=ttymxc0
    ethact=FEC1
    ethprime=FEC
    fdt_addr=0x83000000
    fdt_file=imx6ull-14x14-emmc-4.3-480x272-c.dtb
    fdt_high=0xffffffff
    findfdt=if test $fdt_file = undefined; then if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
    image=zImage
    initrd_addr=0x83800000
    initrd_high=0xffffffff
    ip_dyn=yes
    loadaddr=0x80800000
    loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
    loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
    loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
    logo_file=alientek.bmp
    mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused 
    mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
    mmcautodetect=yes
    mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
    mmcdev=0
    mmcpart=1
    mmcroot=/dev/mmcblk0p2 rootwait rw
    netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
    netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
    panel=ATK-LCD-4.3-480x272
    script=boot.scr
    splashimage=0x88000000
    splashpos=m,m
    stderr=serial
    stdin=serial
    stdout=serial
    
    Environment size: 2598/8188 bytes
    

    我们可以看到有两个信息:

    1. author=Yunes
    2. bootdelay=5

    这两个信息都是我之前添加过的,一个是添加作者名字,一个是启动延迟,也就是开发板reset之后倒计时。

  3. version

    打印uoot版本号

    => version 
    
    U-Boot 2016.03 (Dec 27 2025 - 21:01:51 +0800)
    arm-linux-gnueabihf-gcc (Linaro GCC 4.9-2017.01) 4.9.4
    GNU ld (Linaro_Binutils-2017.01) 2.24.0.20141017 Linaro 2014_11-3-git
    

2.环境变量操作命令

环境变量操作涉及到两个命令setenvsaveenv,这两个很好理解吧,一个是设置一个是保存

setenv是修改DRAM中的环境变量值,而saveenv是将修改后的环境变量存放到flash中,否则下次重启还是之前的变量


2.1添加or修改环境变量

回想第一小节的version下两个变量,具体操作如下

setenv bootdelay 5
saveenv

serenv aothor Yunes
saveenv

遇到修改环境变量出现空格的情况,需要增加引号

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv

2.2删除环境变量

setenv author
saveenv
#后面加空值即可

3.内存操作命令

内存操作命令就是用于直接对 DRAM 进行读写操作的,常用的内存操作命令有 md、nm、mm、mw、cp 和 cmp


3.1、md

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

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

b(byte)、w(word)、l(long) 分别对应1、2、4个字节,address 就是要查看的内存起始地址,[# of objects]表示要查看的数据长度

Ps:uboot命令中的数字都是十六进制的!

例如:

=> md.b 80000000 10
80000000: 9f 77 ff fb df bf bf b2 ff fb fa ff ff bf be 7f    .w..............
=> md.w 80000000 10
80000000: 779f fbff bfdf b2bf fbff fffa bfff 7fbe    .w..............
80000010: 7ffe 5fff eab6 fff4 fbdd f5fc faef eafd    ..._............
=> md.l 80000000 10
80000000: fbff779f b2bfbfdf fffafbff 7fbebfff    .w..............
80000010: 5fff7ffe fff4eab6 f5fcfbdd eafdfaef    ..._............
80000020: 3fbff47e aabcbebf fef17dce e8eaffde    ~..?.....}......
80000030: fd7efdf3 bf8b6eab df6d7f5f eabedaee    ..~..n.._.m.....

分析一下这三个命令

=> md.b 80000000 10 #起始地址0x80000000 ,大小16*1=16字节
=> md.w 80000000 10 #起始地址0x80000000 ,大小16*2=32字节
=> md.l 80000000 10 #起始地址0x80000000 ,大小16*4=64字节

3.2、nm

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

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

例如:

=> nm.l 80000000
80000000: fbff779f ?

?后面写你要改成的内容,我们就写0x123456678,再q退出

=> nm.l 80000000
80000000: fbff779f ? 12345678
80000000: 12345678 ? q

修改完成之后,我们在使用md命令查看一下,一共四个字节

=> md.l 80000000 1
80000000: 12345678                               xV4.

3.3 、mm

mm命令会自增

=> mm.l 80000000
80000000: 12345678 ? 01010101
80000004: b2bfbfdf ? 02020202 
80000008: fffafbff ? 03030303 
8000000c: 7fbebfff ? q

=> md.l 80000000 3
80000000: 01010101 02020202 03030303             ............

3.4、mw

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

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

例如:

=> mw.l 80000000 0a0a0a0a 10

=> md.l 80000000 10
80000000: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................
80000010: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................
80000020: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................
80000030: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................


3.5、cp

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

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

例如:

=> cp.l 80000000 80000100 10

=> md.l 80000100 10
80000100: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................
80000110: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................
80000120: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................
80000130: 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a    ................

3.6、cmp

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

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

例如:

=> cmp.l 80000000 80000100 10
Total of 16 word(s) were the same

4.总结

这些基础命令简单了解掌握,本来还有一个网络操作命令的,由于缺少路由器,uboot下的网络比较难搞,打算在后续linux篇章再介绍


4.网络操作命令


uboot 是支持网络的,我们在移植 uboot 的时候一般都要调通网络功能,因为在移植 linuxkernel 的时候需要使用到 uboot 的网络功能做调试。uboot 支持大量的网络相关命令,比如 dhcp、ping、nfs 和 tftpboot,我们接下来依次学习一下这几个和网络有关的命令。

记得进行以下步骤

  1. 查看主机网卡(网线),再去修改虚拟机网络适配器桥接模式下的网卡
  2. 修改ubuntu下的IP,将其设置为静态,这样不会因为后续开机dhcp导致不必要的麻烦
环境变量描述
ipaddr开发板 ip 地址,可以不设置,使用 dhcp 命令来从路由器获取 IP 地址。
ethaddr开发板的 MAC 地址,一定要设置。
gatewayip网关地址。
netmask子网掩码。
serverip服务器 IP 地址,也就是 Ubuntu 主机 IP 地址,用于调试代码。
=> setenv ipaddr 10.135.25.24
=> setenv ethaddr b8:ae:1d:01:00:00
=> setenv gatewayip 10.135.25.1
=> setenv netmask 255.255.255.0
=> setenv serverip 10.135.25.24
=> saveenv
Saving Environment to MMC...
Writing to MMC(0)... done

修改完我们就重启,来测试一个最基本命令


4.1、ping

=> ping 10.135.25.24
Using FEC1 device
host 10.135.25.24 is alive

4.2、nfs

这里直接对原文总结并修改:

NFS(网络文件系统)是一种通过网络在不同计算机之间共享文件的机制。
在嵌入式 Linux 开发中,常利用 NFS 在 Ubuntu 主机开发板 之间共享资源。

例如:
我们可以将 Linux 内核镜像(zImage/uImage)设备树文件(.dtb) 放在 Ubuntu 主机中,然后在 U-Boot 中通过 nfs 命令,把这些文件直接下载到开发板的 DRAM 中并运行。

这种方式的主要目的在于:
方便调试 Linux 内核和设备树文件**,也称为 网络调试


为什么嵌入式 Linux 要用网络调试?

嵌入式 Linux 的开发方式与单片机开发有很大不同:

  • 单片机开发
    • 可以通过 J-Link、ST-Link 等仿真器
    • 使用 MDK、IAR 等 IDE
    • 一键下载程序到 MCU 内部 Flash
  • 嵌入式 Linux 开发
    • 系统通常存放在 eMMC / NAND / SPI Flash 等外部存储中
    • 没有类似 MDK、IAR 这种“一键下载”的 IDE
    • 固件烧写一般依赖厂家提供的烧写工具

而厂家提供的烧写工具通常:

  • 操作步骤复杂
  • 更适合 量产
  • 在内核调试阶段频繁使用会 极大浪费时间

因此,在 Linux 内核调试阶段,直接反复烧写 Flash 并不高效。


网络调试的优势

网络调试正是为了解决上述问题而出现的:

  • 内核或设备树修改后
  • 只需在 Ubuntu 上重新编译
  • 通过 U-Boot + NFS
  • 直接将文件下载到 DRAM 中运行

无需烧写 Flash,大大提高调试效率。

这也是 嵌入式 Linux 开发中最常用的调试方式之一


U-Boot 中使用 NFS

通常流程如下:

  1. 在 Ubuntu 主机上:
    • 开启 NFS 服务
    • 创建一个 NFS 共享目录
    • 所有需要通过网络加载的文件(内核、设备树等)都放在该目录中
  2. 在 U-Boot 中:
    • 使用 nfs 命令
    • 将 Ubuntu 主机 NFS 目录中的文件下载到开发板的 DRAM 中运行

但是nfs不稳定还要改很多东西,我直接上tftp


4.3、tftp

安装环境

sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd

依旧创建文件夹

mkdir /home/yunes/linux/tftpboot && chmod 777 /home/yunes/linux/tftpboot
vi /etc/xinetd.d/tftp


service tftp
{
    socket_type     = dgram
    protocol        = udp
    wait            = yes
    user            = root
    server          = /usr/sbin/in.tftpd
    server_args     = -s /home/yunes/linux/tftpboot/
    disable         = no
    per_source      = 11
    cps             = 100 2
    flags           = IPv4
}

启动tftp

sudo service tftpd-hpa start

再编写修改

vi /etc/default/tftpd-hpa

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/yunes/linux/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"

重启:

sudo service tftpd-hpa restart

zImage放到tftp文件夹里

下载

tftp 80800000 zImage

下载完毕

=> tftp 80800000 zImage
Using FEC1 device
TFTP from server 10.135.25.24; our IP address is 10.135.25.25
Filename 'zImage'.
Load address: 0x80800000
Loading: #################################################################
	 #################################################################
	 #################################################################
	 #################################################################
	 #################################################################
	 #################################################################
	 #################################################################
	 ########
	 1.9 MiB/s
done
Bytes transferred = 6785480 (6789c8 hex)


5.总结

目前还只总结了一部分,后续还要再补充,但是这个网络真的麻烦啊,没路由器只能再虚拟机网络桥接网线和无线来回摆动,浪费了很多时间,尤其是这个nfs,版本兼容问题,气死我了!!!不过好在加深了印象,继续努力😀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值