U-Boot中的filesize环境变量
如:setenv updaterootfs nand write.yaffs 30000000 200000 $(filesize)
这时如果printenv,会发现updaterootfs=nand write.yaffs 30000000 200000 6365D0
这里的6365D0为setenv语句时环境变量filesize的大小.
需要引起注意的是:6365D0这个值是固定的,不会随每次传输文件后而更改。
所以如果run updaterootfs,则这里的6365D0这个值就不是我们想要的了,我们想要的是上次传输的文件大小。
正确的做法是使用单引号:setenv updaterootfs nand write.yaffs 30000000 200000 '$(filesize)'
这时printenv,则会显示 updaterootfs=nand write.yaffs 30000000 200000 $(filesize)
1. U-Boot的常用命令的用法
进入U-Boot控制界面后,可以运行各种命令,比如下载文件到内存,擦除、读写Flash,运行内存、NOR Flash、NAND Flash中的程序,查看、修改、比较内存中的数据等。
使用各种命令时,可以使用其开头的若干个字母代替它。比如tftpboot命令,可以使用t、tf、tft、tftp等字母代替,只要其他命令不以这些字母开头即可。
当运行一个命令之后,如果它是可重复执行的(代码中使用U_BOOT_CMD定义这个命令时,第3个参数是1),若想再次运行可以直接输入回车。
U-Boot接受的数据都是16进制,输入时可以省略前缀0x、0X。
下面介绍常用的命令:
(1)帮助命令help。
运行help命令可以看到U-Boot中所有命令的作用,如果要查看某个命令的使用方法,运行“help 命令名”,比如“help bootm”。
可以使用“?”来代替“help”,比如直接输入“?”、“? bootm”。
(2)下载命令。
U-Boot支持串口下载、网络下载,相关命令有:loadb、loads、loadx、loady和tftpboot、nfs。
前几个串口下载命令使用方法相似,以loadx命令为例,它的用法为“loadx [
off ] [ baud
]”。中括号“[]”表示里面的参数可以省略,off表示文件下载后存放的内存地址,baud表示使用的波特率。如果baud参数省略,则使用当前的波特
率;如果off参数省略,存放的地址为配置文件中定义的宏CFG_LOAD_ADDR。
tftpboot命令使用TFTP协议从服务器下载文件,服务器的IP地址为环境变量
serverip。用法为“tftpboot [loadAddress]
[bootfilename]”,loadAddress表示文件下载后存放的内存地址,bootfilename表示要下载的文件的名称。如果
loadAddress省略,存放的地址为配置文件中定义的宏CFG_LOAD_ADDR;如果bootfilename省略,则使用单板的IP地址构造
一个文件名,比如单板IP为192.168.1.17,则缺省的文件名为C0A80711.img。
nfs命令使用NFS协议下载文件,用法为“nfs [loadAddress]
[host ip
addr:bootfilename]”。loadAddress、bootfilename的意义与tftpboot命令一样,host ip
addr表示服务器的IP地址,默认为环境变量serverip。
下载文件成功后,U-Boot会自动创建或更新环境变量filesize,它表示下载的文件的长度,可以在后续命令中使用“$(filesize)”来引用它。
(3)内存操作命令。
常用的命令有:查看内存命令md、修改内存命令md、填充内存命令mw、拷贝命令cp。这些
命令都可以带上后缀“.b”、“.w”或“.l”,表示以字节、字(2个字节)、双字(4个字节)为单位进行操作。比如“cp.l 30000000
31000000 2”将从开始地址0x30000000处,拷贝2个双字到开始地址为0x31000000的地方。
md命令用法为“md[.b, .w, .l] address [count]”,表示以字节、字或双字(默认为双字)为单位,显示从地址address开始的内存数据,显示的数据个数为count。
mm命令用法为“mm[.b, .w, .l] address”,表示以字节、字或双字(默认为双字)为单位,从地址address开始修改内存数据。执行mm命令后,输入新数据后回车,地址会自动增加,Ctrl+C退出。
mw命令用法为“mw[.b, .w, .l] address value [count]”,表示以字节、字或双字(默认为双字)为单位,往开始地址为address的内存中填充count个数据,数据值为value。
cp命令用法为“cp[.b, .w, .l] source target count”,表示以字节、字或双字(默认为双字)为单位,从源地址source的内存拷贝count个数据到目的地址的内存。
(4)NOR Flash操作命令。
常用的命令有查看Flash信息的flinfo命令、加/解写保护命令protect、擦除
命令erase。由于NOR Flash的接口与一般内存相似,所以一些内存命令可以在NOR Flash上使用,比如读NOR
Flash时可以使用md、cp命令,写NOR Flash时可以使用cp命令(cp根据地址分辨出是NOR Flash,从而调用NOR
Flash驱动完成写操作)。
直接运行“flinfo”即可看到NOR Flash的信息,有NOR Flash的型号、容量、各扇区的开始地址、是否只读等信息。比如对于本书基于的开发板,flinfo命令的结果如下:
Bank # 1: AMD: 1x Amd29LV800BB (8Mbit)
Size: 1 MB in 19 Sectors
Sector Start Addresses:
00000000 (RO) 00004000 (RO) 00006000 (RO) 00008000 (RO) 00010000 (RO)
00020000 (RO) 00030000 00040000 00050000 00060000
00070000 00080000 00090000 000A0000 000B0000
000C0000 000D0000 000E0000 000F0000 (RO)
其中的RO表示该扇区处于写保护状态,只读。
对于只读的扇区,在擦除、烧写它之前,要先解除写保护。最简单的命令为“protect off all”,解除所有NOR Flash的写保护。
erase命令常用的格式为“erase start
end”──擦除的地址范围为start至end、“erase start +len”──擦除的地址范围为start至(start + len
– 1),“erase all”──表示擦除所有NOR Flash。
注意:其中的地址范围,刚好是一个扇区的开始地址到另一个(或同一个)扇区的结束地址。比如要擦除Amd29LV800BB的前5个扇区,执行的命令为“erase 0 0x2ffff”,而非“erase 0 0x30000”。
(5)NAND Flash操作命令。
NAND Flash操作命令只有一个:nand,它根据不同的参数进行不同操作,比如擦除、读取、烧写等。
“nand info”查看NAND Flash信息。
“nand erase [clean] [off size]”擦除NAND
Flash。加上“clean”时,表示在每个块的第一个扇区的OOB区加写入清除标记;off、size表示要擦除的开始偏移地址和长度,如果省略
off和size,表示要擦除整个NAND Flash。
“nand read[.jffs2] addr off size”从NAND Flash偏移地址off处读出size个字节的数据,存放到开始地址为addr的内存中。是否加后缀“.jffs”的差别只是读操作时的ECC较验方法不同。
“nand write[.jffs2] addr off size”把开始地址为addr的内存中的size个字节数据,写到NAND Flash的偏移地址off处。是否加后缀“.jffs”的差别只是写操作时的ECC较验方法不同。
“nand read.yaffs addr off size”从NAND Flash偏移地址off处读出size个字节的数据(包括OOB区域),存放到开始地址为addr的内存中。
“nand write.yaffs addr off size”把开始地址为addr的内存中的size个字节数据(其中有要写入OOB区域的数据),写到NAND Flash的偏移地址off处。
“nand dump off”,将NAND Flash偏移地址off的一个扇区的数据打印出来,包括OOB数据。
(6)环境变量命令。
“printenv”命令打印全部环境变量,“printenv name1 name2 ...”打印名字为name1、name2、……”的环境变量。
“setenv name value”设置名字为name的环境变量的值为value。
“setenv name”删除名字为name的环境变量。
上面的设置、删除操作只是在内存中进行,“saveenv”将更改后的所有环境变量写入NOR Flash中。
(7)启动命令。
不带参数的“boot”、“bootm”命令都是执行环境变量bootcmd所指定的命令。
“bootm [addr [arg
...]]”命令启动存放在地址addr处的U-Boot格式的映像文件(使用U-Boot目录tools下的mkimage工具制作得到),[arg
...]表示参数。如果addr参数省略,映像文件所在地址为配置文件中定义的宏CFG_LOAD_ADDR。
“go addr [arg ...]”与bootm命令类似,启动存放在地址addr处的二进制文件, [arg ...]表示参数。
“nboot [[[loadAddr] dev] offset]”命令将NAND
Flash设备dev上偏移地址off处的映像文件复制到内存loadAddr处,然后,如果环境变量autostart的值为“yes”,就启动这个映
像。如果loadAddr参数省略,存放地址为配置文件中定义的宏CFG_LOAD_ADDR;如果dev参数省略,则它的取值为环境变量
bootdevice的值;如果offset参数省略,则默认为0。
2. U-Boot命令使用实例
下面通过一个例子来演示如何使用各种命令烧写内核映像文件、yaffs映像文件,并启动系统。
(1)制作内核映像文件。
对于本书使用的Linux 2.6.22.6版本,编译内核时可以直接生成U-Boot格式的映像文件uImage。
对于不能直接生成uImage的内核,制作方法在U-Boot根目录下的README文件中
有说明,假设已经编译好的内核文件为vmlinux,它是ELF格式的。mkimage是U-Boot目录tools下的工具,它在编译U-Boot时自
动生成。执行以下3个命令将内核文件vmlinux制作为U-Boot格式的映像文件uImage,它们首先将vmlinux转换为二进制格式,然后压
缩,最后构造头部信息(里面包含有文件名称、大小、类型、CRC较验码等):
① arm-linux-objcopy -O binary -R .note -R .comment -S vmlinux linux.bin
② gzip -9 linux.bin
③ mkimage -A arm -O linux -T kernel -C gzip -a 0x30008000 -e 0x30008000 -n "Linux Kernel Image" -d linux.bin.gz uImage
(2)烧写内核映像文件uImage。
首先将uImage放在主机上的tftp或nfs目录下,确保已经开启tftp或nfs服务。
然后运行如下命令下载文件,擦除、烧写NAND Flash:
① tftp 0x30000000 uImage 或 nfs 0x30000000 192.168.1.57:/work/nfs_root/uImage
② nand erase 0x0 0x00200000
③ nand write.jffs2 0x30000000 0x0 $(filesize)
第3条命令之所以使用“nand write.jffs2”而不是“nand
write”,是因为前者不要求文件的长度是页对齐的(512字节对齐)。也可以使用“nand
write”,但是需要将命令中的长度参数改为$(filesize)向上进行512取整后的值。比如uImage的大小为1540883,向上进行
512取整后为1541120(即0x178400),可以使用命令“nand write 0x30000000 0x0
0x178400”进行烧写。
(3)烧写yaffs文件系统映像。
假设yaffs文件系统映像的文件名为yaffs.img,首先将它放在主机上的tftp或nfs目录下,确保已经开启tftp或nfs服务;然后执行如下命令下载、擦除、烧写:
① tftp 0x30000000 yaffs.img 或 nfs 0x30000000 192.168.1.57:/work/nfs_root/yaffs.img
② nand erase 0xA00000 0x3600000
③ nand write.yaffs 0x30000000 0xA00000 $(filesize)
这时,重启系统,在U-Boot倒数3秒之后,就会自动启动Linux系统。
(4)烧写jffs2文件系统映像。
假设jffs2文件系统映像的文件名为jffs2.img,首先将它放在主机上的tftp或nfs目录下,确保已经开启tftp或nfs服务;然后执行如下命令下载、擦除、烧写:
① tftp 0x30000000 jffs2.img 或 nfs 0x30000000 192.168.1.57:/work/nfs_root/jffs2.img
② nand erase 0x200000 0x800000
③ nand write.jffs2 0x30000000 0x200000 $(filesize)
系统启动后,就可以使用“mount -t jffs2 /dev/mtdblock1 /mnt”挂接jffs2文件系统。
本文来自博客园,作者:dolinux,未经同意,禁止转载