今天继续玩基于uboot的nfs。昨天总算是基本搞清了make zImage和make uImage的区别,那么今天就来实际编译几个玩一玩。
不过,在利用mkimage工具对zImage镜像文件加工完、生成了符合uboot格式的uImage镜像文件之后,我突然意识到,此时的镜像文件,已经完完全全是名副其实的uboot格式了,那么此时再将其称为zImage.img,其实已经是不合适的,应该改名为uImage.img才对。也就是说,我在(make zImage和make uImage的区别和mkimage工具的使用)博客中引用的tekkaman前辈的下面这条命令:
mkimage -n 'tekkaman' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
其实应该是有瑕疵的。应该要将其中的zImage.img改为uImage.img才对。如下:
mkimage -n 'tekkaman' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage uImage.img
于是,我将镜像文件改名,复制到nfs目录下,然后启动开发板。却发现,开发板中的uboot不认uImage.img的名字,它只认zImage.img,引导内核失败,要修改一下。
一开始我尝试通过修改uboot的源代码的方法来做,修改mini2440.h头文件中的相关宏的定义:
#define CONFIG_BOOTCOMMAND "nfs 0x30008000 192.168.100.120:/opt/FriendlyARM/mini2440/rootfs/uImage.img;bootm"
修改完后使用super-vivi将uboot烧录进去,重启开发板,却发现问题仍然存在。这是为什么呢?
经过一番思索,我找到原因了。这是因为uboot已经将zImage.img这个名字写入了它的环境变量中。光修改上面的宏是没有用的,必须修改它的环境变量,否则它不会接受这个新的名字。
可是,要如何来修改它的环境变量呢?网上百度,也没度到什么对应的资料,看来还得自己去摸索。好在uboot提供了一整套方便使用的命令。直接在uboot启动时,敲击键盘进入它的命令行模式,输入help命令便可以看到,如下所示:
[u-boot@MINI2440]# help
? - alias for 'help'
askenv - get environment variables from stdin
base - print or set address offset
bdinfo - print Board Info structure
bmp - manipulate BMP image data
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootvx - Boot vxWorks from an ELF image
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
date - get/set/reset date & time
dcache - enable or disable data cache
dhcp - boot image via network using DHCP/TFTP protocol
echo - echo args to console
editenv - edit environment variable
eeprom - EEPROM sub-system
erase - erase FLASH memory
exit - exit script
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
flinfo - print FLASH memory information
fsinfo - print information about filesystems
fsload - load binary file from a filesystem image
go - start application at address 'addr'
help - print command description/usage
i2c - I2C sub-system
icache - enable or disable instruction cache
iminfo - print header information for application image
imls - list all images found in flash
imxtract- extract a part of a multi-image
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
ls - list files in a directory (default /)
md - memory display
mm - memory modify (auto-incrementing address)
mmc - MMC sub-system
mtest - simple RAM read/write test
mw - memory write (fill)
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reginfo - print register information
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
showvar - print local hushshell variables
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true - do nothing, successfully
unzip - unzip a memory region
usb - USB sub-system
usbboot - boot from USB device
usbslave- usbslave - get file from host(PC)
version - print monitor version
找到其中与环境变量env相关的命令。一个是打印当前的环境变量的命令printenv,一个是修改环境变量的命令editenv,还有一个是保存环境变量到存储器的命令saveenv。一个一个的用起来吧。
1、首先把当前的环境变量env的值打印出来。如下:
[u-boot@MINI2440]# printenv
bootargs=noinitrd root=/dev/nfs rw nfsroot=192.168.100.120:/opt/FriendlyARM/mini2440/rootfs ip=192.168.100.230:192.168.100.120:192.168.100.1:255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
bootcmd=nfs 0x30008000 192.168.100.120:/opt/FriendlyARM/mini2440/rootfs/zImage.img;bootm
bootdelay=10
baudrate=115200
ethaddr=08:08:11:18:12:27
ipaddr=192.168.100.230
serverip=192.168.100.120
gatewayip=192.168.100.1
netmask=255.255.255.0
tekkaman=bmp d 70000
stdin=serial
stdout=serial
stderr=serial
ethact=dm9000
Environment size: 515/131068 bytes
可以看到,变量bootcmd的值,确实是zImage.img。那么接下来我们就要修改这个参数就好。使用editenv这个命令,如下:
[u-boot@MINI2440]# editenv bootcmd
edit: nfs 0x30008000 192.168.100.120:/opt/FriendlyARM/mini2440/rootfs/uImage.img;bootm
修改完后记得手动保存一下,否则uboot是不会自动将你的修改动作存入存储器的,一重启就丢失了,白弄了。如下:
[u-boot@MINI2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x7c00000000002 -- 0% complete.
Writing to Nand... done
OK,修改完成了。如果不太放心有没有修改成功,那么我们再将此刻最新的环境变量值打印出来看看吧,如下:
[u-boot@MINI2440]# printenv
bootargs=noinitrd root=/dev/nfs rw nfsroot=192.168.100.120:/opt/FriendlyARM/mini2440/rootfs ip=192.168.100.230:192.168.100.120:192.168.100.1:255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
bootdelay=10
baudrate=115200
ethaddr=08:08:11:18:12:27
ipaddr=192.168.100.230
serverip=192.168.100.120
gatewayip=192.168.100.1
netmask=255.255.255.0
tekkaman=bmp d 70000
stdin=serial
stdout=serial
stderr=serial
ethact=dm9000
bootcmd=nfs 0x30008000 192.168.100.120:/opt/FriendlyARM/mini2440/rootfs/uImage.img;bootm
Environment size: 515/131068 bytes
可以看到,变量bootcmd的值,已经成功修改为了uImage.img。OK,此时可以放心的重启了,输入reset命令就好!
uboot重启完后,可以看到,顺利的按照新的路径和文件名定位到内核文件,成功的引导了系统启动!
搞定,收工!