浅析嵌入式系统之uboot常用命令

浅析嵌入式系统 uboot常用命令

uboot常用命令1

1.1 类似linux终端的行缓冲命令行

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

  • linux终端设计有3种缓冲机制:无缓冲、行缓冲、全缓冲

  • 有些命令有简化的别名,如printenv命令可以简化为print,如setenv可以简化为set

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

  • 采用“help+命令名”来查询命令的详细信息,只输入help时,则打印出命令列表。

1.2 命令中的特殊符号(如单引号)

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

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

1.3 有些命令是一个命令族(如movi)

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

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

1.4 第一个命令:printenv/print

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

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

uboot常用命令2

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

用法:set name value

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

saveenv/save命令不带参数,直接执行,作用是将内存中的环境变量的值同步保存到Flash中环境变量的分区。

注意:环境变量的保存是整体的覆盖保存,也就是说内存中所有的环境变量都会整体的将Flash中环境变量分区中原来的内容整体覆盖。

总结:彻底更改一个环境变量的值,需要2步:

第一步:set命令来更改内存中的环境变量

第二步:用save命令将其同步到Flash中环境变量的分区。

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

2.3 网络测试指令:ping

命令用法: ping ip地址

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

  1. 首先要插上网线。
  2. 先试图ping通主机windows。注意Windows中有线网卡的地址设置(设置本地连接)。设置主机windows的本地连接IPv4地址为192.168.1.10
  3. 第三步确认开发板中uboot里几个网络相关的环境变量的值对不对。最重要的是ipaddr(这个环境变量表示当前开发板的IP地址),这个地址必须和主机windows的IP地址在同一个网段。

uboot常用命令3

3.1 tftp下载指令:tftp

  1. uboot本身主要目标是启动内核,为了完成启动内核必须要能够部署内核,uboot为了部署内核就需要将内核镜像从主机中下载过来然后烧录到本地flash中。uboot如何从主机(windows或者虚拟机ubuntu)下载镜像到开发板上?有很多种方式,主流方式是:fastboot和tftp。

    fastboot的方式是通过USB线进行数据传输。

    tftp的方式是通过有线网络的。典型的方式就是通过网络,fastboot是近些年才新发展的。

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

  3. 有些人习惯在windows中搭建tftp服务器,一般是用一些软件来搭建(譬如tftpd32,使用起来比较简单);有些人习惯在linux下搭建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指令进行镜像的烧写了。

uboot常用命令4

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都一样)。

4.2 NandFlash操作指令nand

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

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

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

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

  3. mw就是memory write,将内容写到内存中

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

4.4 启动内核指令:bootm、go

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

  2. 差别:bootm启动内核同时给内核传参,而Go命令启动内核不传参。

    bootm其实才是正宗的启动内核的命令,一般情况下都用这个;go命令本来不是专为启动内核设计的,go命令内部其实就是一个函数指针指向一个内存地址然后直接调用那个函数,go命令的实质就是PC直接跳转到一个内存地址去运行而已。

    go命令可以用来在uboot中执行任何的裸机程序(有一种调试裸机程序的方法就是事先启动uboot,然后在uboot中去下载裸机程序,用go命令去执行裸机程序)

uboot常用环境变量1

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

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

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

  1. 自动运行倒数时间:bootdelay

  2. 网络设置:ipaddr serverip

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

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

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

    (4)netmask是子网掩码

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

uboot常用环境变量2

6.1 自动运行命令设置:bootcmd

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

  2. uboot开机自动启动时实际就是在内部执行了bootcmd这个环境变量的值所对应的命令集:bootcmd=movi read kernel 30008000; bootm 30008000

    意思是:将iNand的kernel分区读取到DDR内存的0x30008000地址处,然后使用bootm启动命令从内存0x30008000处去启动内核。

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

  4. 设置bootcmd环境变量:set bootcmd ‘movi read kernel 30008000; bootm 30008000’

6.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. 内核传参非常重要。在内核移植的时候,新手经常因为忘记给内核传参,或者给内核传递的参数不对,造成内核启动不起来。

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

  1. 新建一个环境变量,使用set var value

  2. 更改一个环境变量,使用set var value

  3. 删除一个环境变量,使用set var

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

上一篇:加载LINUX内核/设备树/根文件系统的三种方法


下一篇:交换机FTP与TFTP配置