ARM uboot的常用命令

一、uboot 的常用命令1

1、类似 linux 终端的行缓冲命令行

(1) 行缓冲的意思就是:当我们向终端命令行输入命令的时候,这些命令没有立即被系统识别,而是被缓冲到一个缓存区(也就是系统认为我们还没有输入完),当我们按下回车键(换行)后系统就认为我们输入完了,然后将缓冲区中所有刚才输入的作为命令拿去分析处理。

(2) linux 终端设计有 3 种缓冲机制:无缓冲、行缓冲、全缓冲。


2、有些命令有简化的别名

(1) 譬如 printenv 命令可以简化为 print,譬如 setenv 可以简化为 set。


3、有些命令会带参数(注意格式是固定的)

(1) uboot 的每个命令都有事先规定好的各种格式。有些命令就是不带参数的,譬如 printenv/print 命令;有些命令带可选的参数(可以带也可以不带,当然带不带参数的执行结果是不同的);有些命令带必须的参数(譬如 setenv/set 命令)。


4、命令中的特殊符号(譬如单引号)

(1) uboot 的有些命令带的参数非常长,为了告诉 uboot 这个非常长而且中间有好多个空格的东西是给他的一整个参数,所以用单引号将这个很长且中间有空格隔开的参数引起来。

(2) 别的符号也许也有,而且有特定的意义。当碰到 uboot 的命令行有特殊符号时,要注意不是弄错了,而是可能有特别的含义。


5、有些命令是一个命令族(譬如 movi)

(1) 命令族意思就是,好多个命令开头都是用同一个命令关键字的,但是后面的参数不一样,这些命令的功能和作用也不同。这就叫一个命令族。

(2) 同一个命令族中所有的命令都有极大的关联,譬如 movi 开头的命令族都和 moviNand (moviNand 也就是 EMMC、iNand)操作有关。


6、第一个命令:printenv/print

(1) print 命令不用带参数,作用是打印出系统中所有的环境变量。

(2) 环境变量就好像程序的全局变量一样。程序中任何地方都可以根据需要去调用,或者更改环境变量(一般都是调用),环境变量和全局变量不同之处在于:全局变量的生命周期是在程序的一次运行当中,开始运行时诞生,程序结束时死亡;下次运行程序时从头开始;但是环境变量被存储在 Flash 的另一块专门区域( Flash 上有一个环境变量分区),一旦我们在程序中保存了该环境变量,那么下次开机时该环境变量的值将维持上一次更改保存后的值。


二、uboot 的常用命令2

1、设置(添加/更改)环境变量:setenv/set

(1) 用法:set name value


2、保存环境变量的更改:saveenv/save

(1) saveenv/save 命令不带参数,直接执行,作用是将内存中的环境变量的值,同步保存到 Flash 中环境变量的分区。注意:环境变量的保存是整体的覆盖保存,也就是说内存中所有的环境变量都会整体的将 Flash 中环境变量分区中原来的内容整体覆盖。

总结:彻底更改一个环境变量的值,需要 2 步:第一步 set 命令来更改内存中的环境变量,第二步用 save 命令将其同步到 Flash 中环境变量的分区。

有时候我们只是想测试下这个环境变量,不希望影响到下一次开机,那就只 set 不 save;这样 set 后当前本次运行的 uboot 已经起效果了,只不过没 save ,下一次开机还是会恢复到原来的状况。


3、网络测试指令:ping

(1) 命令用法: ping ip地址

注意:ping 是测试开发板和主机之间的网络链接,注意以下步骤:

  1. 首先要插上网线。
  2. 先试图 ping 通主机 windows(开发板能 ping 通虚拟机 ubuntu,就一定能 ping 通主机 Windows;开发板能 ping 通主机 Windows,不一定能 ping 通虚拟机 ubuntu;)。注意 Windows 中有线网卡的地址设置(设置本地连接)。设置主机 windows 的本地连接 IPv4地址为:192.168.1.10。
    在这里插入图片描述
    点击设置有线网卡。
    在这里插入图片描述

设置 IP地址和子网掩码。

在这里插入图片描述

  1. 第三步确认开发板中 uboot 里几个网络相关的环境变量的值对不对。最重要的是 ipaddr(这个环境变量表示当前开发板的 IP 地址),这个地址必须和主机 windows 的 IP 地址在同一个网段。

在这里插入图片描述

网段的概念:一个 IP 地址分为 2 部分,一部分是网段地址,另一部分是网段内的主机地址(由子网掩码来区分哪一部分是网段地址,哪一部分是 IP 地址)。在子网掩码是 255.255.255.0 的情况下,192.168.1.10 这个 IP 地址的前三部分(192.168.1.)属于网段地址,第 4 部分(10)属于主机地址。


三、开发板和主机的 ping 通

上节课最后的结果是:uboot 中的 ipaddr 和主机 windows 本地连接地址已经设置到一个网段,但是实际还 ping 不通。

还发现了这样的现象:1、我把 2 个的网段都从 192.168.1.x 改到 192.168.0.x 时会 ping 通一次,第二次开始就 ping 不通了;2、有同学说 ping 不通可能是因为 uboot 中 gatewayip 没设置,我就实际测试设置网管为同网段 .1,再次测试结论是第一次 ping 通了,第二次开始又不通了。

1、开发板运行 linux 下,和主机Windows的ping通

(1) 先将开发板刷机成 linux+QT 镜像(刷机见裸机教程第三部分),然后启动,进入 linux 命令行终端下。

(2) 在 linux 下使用 ifconfig 命令将开发板中 linux 系统的 IP 地址设置为,和主机 windows 同一网段(为了上课方便,以后就固定:主机windows地址 192.168.1.10,开发板 uboot 或 linux 的地址为 192.168.1.20,虚拟机 ubuntu 地址为 192.168.1.141)。

(3) 此时开发板端 ping windows 通的。

(4) windows 中 ping 开发板也是通的。

说明:首先开发板和主机的网络部分的硬件都是好的,网络连接也是好的,主机windows 中的网络软件设置是好的。


2、开发板运行 linux 下,和虚拟机ubuntu的ping通

(1) 在 linux 基础课中讲过:虚拟机的网卡设置可以选择好几种方式,常用的就是:NAT 和桥接(bridged)。

在这里插入图片描述

(2) 虚拟机要和开发板进行网络通信,只能通过桥接方式连接。

(3) 虚拟机要想被开发板 ping 通,设置步骤如下:
第一步:虚拟机设置成桥接方式。

在这里插入图片描述


在这里插入图片描述


第二步:虚拟机的菜单中有个“虚拟网络编辑器”,这里面要设置为桥接到有线网卡。(默认是自动的,自动的一般会影响 ping 通。因为电脑现在一般都有 2 个网卡:一个有线的,一个无线的。如果选了自动,那么虚拟机会自动桥接到无线网卡上,但是我们却是通过有线网卡来连接开发板的,自然ping不通)

“自动”,虚拟机网卡就会选择连接到无线网卡(能够上网的网卡),但是虚拟机和开发板的 ping 通道,是选择有线网卡。于是在网络配置为“自动”的情况下,虚拟机无法 ping 通开发板。

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


第三步:在虚拟机 ubuntu 中设置 IP 地址为 192.168.1.141(可以通过 /etc/network/interfaces 文件来设置静态的然后重启;也可以直接命令行 ifconfig 去设置)

root@ubuntu:/home/aston#  cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.141
netmask 255.255.255.0
gateway 192.168.1.1
root@ubuntu:/home/aston# ifconfig  eth0 down
root@ubuntu:/home/aston# ifconfig  eth0 up
root@ubuntu:/home/aston# ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:0c:29:5f:95:ee  
          inet addr:192.168.1.141  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe5f:95ee/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:134 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:360 (360.0 B)  TX bytes:18469 (18.4 KB)
          Interrupt:19 Base address:0x2000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:184 errors:0 dropped:0 overruns:0 frame:0
          TX packets:184 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:14208 (14.2 KB)  TX bytes:14208 (14.2 KB)

root@ubuntu:/home/aston# 

(4) 此时开发板 ping 虚拟机 ubuntu 应该就通了。

(5) 此时虚拟机 ubuntu 中 ping 开发板也是通的。


3、开发板运行 uboot 下,和主机Windows的ping通

(1) 刚才开发板运行 linux 时,和主机windows、虚拟机 ubuntu 都 ping 通了,说明硬件和连接和主机设置没错。

(2) 此时开发板重启进入 uboot,设置好 ipaddr、gatewayip,然后去 ping windows发现还是不通。 怀疑 uboot 本身网络驱动有问题。

(3)然后同样情况下尝试去 ping 通虚拟机 ubuntu,理论分析应该也不通,但是实际发现是通的。


4、开发板运行 uboot 下,和虚拟机ubuntu的ping通

(1) uboot 和虚拟机 ubuntu 互相 ping 通(前提是虚拟机 ubuntu 设置为桥接,且桥接到有线网卡,且 ip 地址设置正确的情况下)

结论:开发板中运行的 uboot 有点小 bug,ping windows 就不通,ping 虚拟机 ubuntu 就通。


在这里插入图片描述


四、uboot 常用命令3

1、tftp下载指令:tftp

(1) uboot 本身主要目标是启动内核,为了完成启动内核,必须要能够部署内核,uboot 为了部署内核就需要将内核镜像从主机中下载过来,然后烧录到本地 flash 中。uboot 如何从主机(windows 或者虚拟机ubuntu)下载镜像到开发板上?有很多种方式,主流方式是:fastboot 和 tftp。
fastboo t的方式是通过 USB 线进行数据传输。
tftp 的方式是通过有线网络的。典型的方式就是通过网络,fastboot 是近些年才新发展的。

(2) tftp方式下载时,实际上 uboot 扮演的是 tftp 客户端程序的角色,主机 windows 或虚拟机ubuntu 中必须有一个 tftp 服务器, 然后将要下载的镜像文件放在服务器的下载目录中,然后开发板中使用 uboot 的 tftp 命令去下载即可。

(3) 有些人习惯在 windows 中搭建 tftp 服务器,一般是用一些软件来搭建(譬如 tftpd32,使用起来比较简单);有些人习惯在 linux 下搭建 tftp 服务器,可以参考网盘中的虚拟机下载目录下的一个教程《嵌入式开发环境搭建-基于14.04.pdf》,这里面有 ubuntu 中搭建 tftp 服务器的教程,也可以自己上网搜索教程尝试。(如果你直接就用我的虚拟机,那就已经搭建好了,不用再搭建了;如果是自己新装的那就参考文档搭建;如果你的版本和我的不一样那搭建过程可能不一样)

(4) 我的虚拟机搭建的时候设置的 tftp 下载目录是 /tftpboot, 将要被下载的镜像复制到这个目录下。

(5) 检查开发板 uboot 的环境变量,注意 serverip 必须设置为虚拟机ubuntu的 ip 地址。(serverip 这个环境变量的意义就是主机 tftp 服务器的 ip 地址)

(6) 然后在开发板的 uboot 下先 ping 通虚拟机ubuntu,然后再尝试下载:tftp 0x30000000 zImage-qt(意思是将服务器上名为 zImage-qt 的文件下载到开发板内存的 0x30000000 地址处。)

(7) 镜像下载到开发板的 DDR 中后,uboot 就可以用 movi 指令进行镜像的烧写了。

注意:
1)如果你是用的 windows 下的 tftp 服务器,那 uboot 的 serverip 就要设置为和 windwos 下 tftp 服务器的 ip 地址一样(windows 下的 tftp 服务器软件设置的时候就有个步骤是让你设置服务器的 ip 地址,这个 ip 地址和主机 windows 必须在一个网段)。
2)整个过程中间环节比较多,实际做的时候可能最后会下载不下来。这时候可能的问题非常多,不要问我,自己对照视频课程讲的思路来排查。(譬如:第一步应该先保证 uboot 和 ubuntu 可以 ping 通;第二步再保证 ubuntu 中 tftp 服务器搭建没错;第三步再实现 tftp 下载。如果第一步有问题参考网络设置部分,第二步有问题(tftp 本地测试下载 ok,但是开发板就是不行),有一个解决方案就是使用 windows 下的 tftp 服务器)

从 Windows 主机 192.168.1.10 上 tftp 服务端传输文件:
在这里插入图片描述
从虚拟机 ubuntu 192.168.1.141 上 tftp 服务端传输文件:
在这里插入图片描述


2、nfs 启动内核命令:nfs

(1) uboot 中也支持 nfs 命令,但是我基本没用过。


五、uboot 的常用命令4

1、SD卡/iNand 操作指令 movi

(1) 开发板如果用 SD卡/EMMC/iNand 等作为 Flash,则在 uboot 中操作 flash 的指令为 movi(或mmc)。

(2) movi 指令是一个命令集,有很多子命令,具体用法可以 help movi 查看。

(3) movi 的指令都是 movi read 和 movi write 一组的,movi read 用来读取 iNand 到 DDR 上,movi write 用来将 DDR 中的内容写入 iNand 中。理解这些指令时一定要注意涉及到的 2 个硬件: iNand 和 DDR 内存。

(4) movi read {u-boot | kernel} {addr} 这个命令使用了一种通用型的描述方法来描述:movi 和 read 外面没有任何标记,说明每一次使用这个指令都是必选的;一对大括号 {} 括起来的部分必选 1 个,大括号中的竖线表是多选一。中括号 [] 表示可选参数(可以有也可以没有)。

(5) 指令有多种用法,譬如 movi read u-boot 0x30000000,意思就是把 iNand 中的 u-boot 分区读出到 DDR 的 0x30000000 起始的位置处。(uboot 代码中将 iNand 分成了很多个分区,每个分区有地址范围和分区名,uboot 程序操作中可以使用直接地址来操作 iNand 分区,也可以使用分区名来操作分区。);注意这里的 0x30000000 也可以直接写作 30000000,意思是一样的(uboot 的命令行中所有数字都被默认当作十六进制处理,不管你加不加 0x 都一样)。

在这里插入图片描述


2、NandFlash 操作指令 nand

(1) 理解方法和操作方法完全类似于 movi 指令


3、内存操作指令:mm、mw、md

(1) DDR 内存中是没有分区的(只听说过对硬盘、Flash 进行分区,没听说过对内存进行分区····),但是内存使用时要注意,千万不能越界踩到别人了。因为 uboot 是一个裸机程序,不像操作系统会由系统整体管理所有内存,系统负责分配和管理,系统会保证内存不会随便越界。然而裸机程序中 uboot 并不管理所有内存,内存是散的随便用的,所以如果程序员(使用 uboot 的人)自己不注意就可能出现自己把自己的数据给覆盖了。

(2) md 就是 memory display,用来显示内存中的内容。

在这里插入图片描述

(3) mw 就是 memory write,将内容写到内存中。

在这里插入图片描述

(4) mm 就是 memory modify,修改内存中的某一块,说白了还是写内存(如果需要批量的逐个单元的修改内存,用 mm 最合适)。

在这里插入图片描述


4、启动内核指令:bootm、go

(1) uboot 的终极目标就是启动内核,启动内核在 uboot 中表现为一个指令,uboot 命令行中调用这个指令就会启动内核(不管成功与否,所以这个指令是一条死路)。

(2) 差别:bootm 启动内核同时给内核传参,而 go 命令启动内核不传参。 bootm 其实才是正宗的启动内核的命令,一般情况下都用这个; go 命令本来不是专为启动内核设计的,go 命令内部其实就是一个函数指针指向一个内存地址,然后直接调用那个函数,go 命令的实质就是 PC 指针直接跳转到一个内存地址去运行而已。go 命令可以用来在 uboot 中执行任何的裸机程序(有一种调试裸机程序的方法就是事先启动 uboot ,然后在 uboot 中去下载裸机程序,用 go 命令去执行裸机程序)


六、uboot 的常用环境变量1

1、环境变量如何参与程序运行

(1) 环境变量有 2 份,一份在 Flash 中,另一份在 DDR 内存中。uboot 开机时,一次性从 Flash 中读取全部环境变量到DDR 内存中,作为环境变量的初始化值,然后使用过程中都是用 DDR 中的这一份;用户可以用 saveenv 指令将 DDR 中的环境变量重新写入 Flash 中,去更新Flash中环境变量。下次开机时又会从Flash中再读一次。

(2) 环境变量在 uboot 中是用字符串表示的,也就是说 uboot 是按照字符匹配的方式来区分各个环境变量的。因此用的时候一定要注意不要打错字了。


2、自动运行倒数时间:bootdelay

3、网络设置:ipaddr serverip

(1) ipaddr 是开发板的本地 IP 地址。

(2) serverip 是开发板通过 tftp 指令,去 tftp 服务器下载东西时,tftp 服务器的 IP 地址。

(3) gatewayip 是开发板的本地网关地址。

(4) netmask 是子网掩码。

(5) ethaddr 是开发板的本地网卡的 MAC 地址。


七、uboot 的常用环境变量2

1、自动运行命令设置:bootcmd

(1) uboot 启动后会开机自动倒数 bootdelay 秒,如果没有人按下回车打断启动,则 uboot 会自动执行启动命令来启动内核。

(2) uboot 开机自动启动时,实际就是在内部执行了 bootcmd 这个环境变量的值所对应的命令集。

在这里插入图片描述

(3) bootcmd=movi read kernel 30008000; bootm 30008000 意思是:将 iNand 的 kernel 分区读取到 DDR 内存的 0x30008000 地址处,然后使用 bootm 启动命令从内存 0x30008000 处去启动内核。

(4) set bootcmd printenv,然后 saveenv;然后重启则会看到启动倒数后自动执行 printenv 命令打印出环境变量。这个小实验说明开机自动执行了 bootcmd。

(5) set bootcmd ‘movi read kernel 30008000; bootm 30008000’


2、uboot 给 kernel 传参:bootargs

(1) linux 内核启动时,可以接收 uboot 给他传递的启动参数,这些启动参数是 uboot 和内核约定好的形式、内容,linux 内核在这些启动参数的指导下完成启动过程。这样的设计是为了灵活,为了内核在不重新编译的情况下可以用不同的方式启动。

(2) 我们要做的事情就是:在 uboot 的环境变量中设置 bootargs,然后 bootm 命令启动内核时,会自动将 bootargs 传给内核。

(3) bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3 意义解释:
console=ttySAC2,115200 —— 控制台使用串口2,波特率115200.
root=/dev/mmcblk0p2 rw —— 根文件系统在 SD 卡端口 0 设备( iNand )第 2 分区,根文件系统是可读可写的.
init=/linuxrc —— linux的进程1(init进程)的路径.
rootfstype=ext3 —— 根文件系统的类型是ext3.

(4) 内核传参非常重要。在内核移植的时候,新手经常因为忘记给内核传参,或者给内核传递的参数不对,造成内核启动不起来。


3、新建、更改、删除一个环境变量的方法

(1 )新建一个环境变量,使用 set var value
(2) 更改一个环境变量,使用 set var value
(3) 删除一个环境变量,使用 set var


4、注意:环境变量更改后的保存

(1) 修改完成环境变量后一定要保存,否则下次开机更改就又没了。


八、uboot 中对 Flash 和 DDR 的管理

1、uboot 阶段 Flash 的分区

(1) 所谓分区,就是说对 Flash 进行分块管理。

(2) PC 机等产品中,因为大家都是在操作系统下使用硬盘的,整个硬盘由操作系统统一管理,操作系统会使用文件系统帮我们管理硬盘空间。(管理保证了文件之间不会互相堆叠),于是乎使用者不用自己太过在意分区问题。

(3) 在 uboot 中是没有操作系统的,因此我们对 Flash(相当于硬盘)的管理必须事先使用分区界定(实际上在 uboot 中和 kernel 中都有个分区表,分区表就是我们在做系统移植时对 Flash 的整体管理分配方法)。有了这个界定后,我们在部署系统时按照分区界定方法来部署,uboot 和 kernel 的软件中也是按照这个分区界定来工作,就不会错。

(4) 分区方法不是一定的,不是固定的,是可以变动的。但是在一个移植中必须事先设计好定死,一般在设计系统移植时就会定好,定的标准是:

uboot : uboot 必须从 Flash 起始地址开始存放(也许是扇区 0,也许是扇区 1,也许是其他,取决于 SoC 的启动设计),uboot 分区的大小必须保证 uboot 肯定能放下,一般设计为 512KB 或者 1MB(因为一般 uboot 肯定不足 512KB,给再大其实也可以工作,但是浪费);

环境变量 :环境变量分区一般紧贴着 uboot 来存放,大小为 32KB 或者更多一点。

kernel :kernel 可以紧贴环境变量存放, 大小一般为 3MB 或 5MB 或其他。

rootfs :同理。

剩下的就是自由分区,一般 kernel 启动后将自由分区挂载到 rootfs 下使用。


总结:一般规律如下:
(1) 各分区彼此相连,前面一个分区的结尾就是后一个分区的开头。
(2) 整个 flash 充分利用,从开头到结尾。
(3) uboot 必须在 Flash 开头,其他分区相对位置是可变的
(4) 各分区的大小由系统移植工程师自己来定,一般定为合适大小(不能太小,太小了容易溢出;不能太大,太大了浪费空间)
(5) 分区在系统移植前确定好,在 uboot 中和 kernel 中使用同一个分区表。将来在系统部署时和系统代码中的分区方法也必须一样。


2、uboot 阶段 DDR 的分区

(1) DDR 的分区和 Flash 的分区不同,主要是因为 Flash 是掉电存在的,而 DDR 是掉电消失,因此可以说 DDR 是每次系统运行时才开始部署使用的。

(2) 内存的分区主要是在 linux 内核启动起来之前;linux 内核启动后,内核的内存管理模块会接管整个内存空间,那时候就不用我们来管了。

(3) 注意内存分区关键就在于,内存中哪一块用来干什么必须分配好,以避免各个不同功能使用了同一块内存造成的互相踩踏。 譬如说我们 tftp 0x23E00000 zImage 去下载 zImage 到内存的 0x23E00000 处就会出错,因为这个内存处实际是 uboot 的镜像所在。这样下载会导致下载的 zImage 把内存中的 uboot 给冲掉。


源自朱有鹏老师.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值