以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
linux终端设计有3种缓冲机制:无缓冲、行缓冲、全缓冲。
uboot提供类似linux终端的行缓冲命令行。当我们向终端命令行输入命令的时候,这些命令没有立即被系统识别,而是被缓冲到一个缓存区(也就是系统认为我们还没有输入完),当我们按下回车键(换行)后系统就认为我们输入完了,然后将缓冲区中所有刚才输入的作为命令拿去分析处理。
uboot的命令中,有些命令有简化后的别名,比如printenv命令可以简化为print;有些命令会带参数;有些命令带的参数非常长,此时可以使用单引号把参数引起来;有些命令是命令族,即好多个命令,它们的开头都使用同一个命令关键字,但是后面的参数不一样,完成的功能也不同,但往往有极大的关联,比如movi族,都和moviNand(EMMC、iNand)操作有关。
以下是uboot控制台下常用的命令。
printenv/print
print命令不用带参数,作用是打印出系统中所有的环境变量。
环境变量就好像程序的全局变量一样。程序中任何地方都可以根据需要去调用或者更改环境变量(一般都是调用),环境变量和全局变量不同之处在于:全局变量的生命周期是在程序的一次运行当中,开始运行时诞生程序结束时死亡,下次运行程序时从头开始;但是环境变量被存储在Flash的另一块专门区域(Flash上有一个环境变量分区),一旦我们在程序中保存了该环境变量,那么下次开机时该环境变量的值将维持上一次更改保存后的值。
setenv/set
setenv/set命令用于设置(添加/更改)环境变量。用法是“set name value”。
saveenv/save
saveenv/save命令用于保存环境变量。
saveenv/save命令不带参数,直接执行,作用是将内存中的环境变量的值同步保存到Flash中环境变量的分区。注意,环境变量的保存是整体的覆盖保存,也就是说内存中所有的环境变量都会整体的将Flash中环境变量分区中原来的内容整体覆盖。
更改环境变量的值需要两步:第一步set命令来更改内存中的环境变量,第二步用save命令将其同步到Flash中环境变量的分区。
ping
ping命令用于网络测试,用法是“ping ip地址”。
tftp
tftp命令用于下载。
uboot将镜像从主机(windows或者虚拟机ubuntu)下载到开发板的主流方式是fastboot和tftp。fastboot方式通过USB线进行数据传输,是近些年才发展的;tftp方式通过有线网络进行数据传输,是很传统与典型的方式。
使用tftp方式下载时,uboot扮演的是tftp客户端,主机windows或虚拟机ubuntu扮演tftp服务器。我们把被下载的镜像文件放在服务器的下载目录中,然后在开发板uboot的控制台下使用tftp命令下载即可。
在虚拟机中设置tftp下载目录是/tftpboot,把被下载的镜像复制到这个目录下。检查uboot的环境变量是否设置合适,是否能ping通虚拟机,然后使用指令“tftp 0x30000000 zImage-qt”进行下载。这指令表示将tftp服务器上名为zImage-qt的文件下载到开发板内存的0x30000000地址处。
镜像下载到开发板的DDR中后,uboot就可以用movi指令进行镜像的烧写了。
nfs
nfs命令用于启动内核。
movi
movie命令用于操作SD卡或者iNand。
开发板如果用SD卡/EMMC/iNand等作为Flash,则在uboot中操作flash的指令为movi(或mmc)。movi指令是一个命令集,有很多子命令,具体用法可以help movi查看。
movi的指令都是movi read和movi write一组的。movi read用来读取iNand到DDR上,movi write用来将DDR中的内容写入iNand中。这些命令涉及两个硬件,即iNand和DDR内存。
movi read {u-boot | kernel} {addr}
- 这个命令使用了一种通用型的描述方法来描述。movi和read外面没有任何标记,说明它必选的。大括号{}表示大括号里的内容必选其一,竖线表示多选一。中括号[]表示可选参数(可以有也可以没有)。
- 比如movi read u-boot 0x30000000,意思是把iNand中的u-boot分区读出到DDR的0x30000000起始的位置处。
- uboot代码中将iNand分成很多个分区,每个分区有地址范围和分区名,uboot程序操作中可以使用直接地址来操作iNand分区,也可以使用分区名来操作分区。
- 0x30000000也可以直接写作30000000,因为uboot的命令行中所有数字都被默认当作十六进制处理。
nand
nand命令用于操作NandFlash。理解方法和操作方法完全类似于movi指令。
mm、mw、md
这些命令都是用来操作内存的。
md就是memory display,用来显示内存中的内容。
mw就是memory write,将内容写到内存中。
mm就是memory modify,修改内存中的某一块,其实还是写内存,适合于批量地修改内存。
DDR是没有分区的(只听说过对Flash进行分区,没听说过对内存进行分区),因此使用内存时要注意,不能越界覆盖数据。
uboot不像操作系统那样,由系统来负责内存的分配和管理,从而保证内存不会随便越界。uboot并不管理所有内存,内存是随便用的,如果不注意就可能出现越界而导致数据覆盖。
bootm、go
这两个命令都可以用来启动内核。
uboot的终极目标就是启动内核,启动内核在uboot中表现为一个指令,在uboot控制台中使用这两个命令之一就会启动内核(不管成功与否,所以这个指令是一条死路)。
这两个命令的区别是,bootm启动内核时会给内核传参,而go命令启动内核时不传参。
其实bootm才是正宗的启动内核的命令,一般情况下都用这个。
go命令不是专为启动内核而设计的,它的实质就是PC直接跳转到一个内存地址去运行。在uboot控制台下,可以使用go命令执行任何的裸机程序(调试裸机程序的方法之一,就是事先启动uboot,然后在uboot中下载裸机程序,然后用go命令去执行裸机程序)。