如何修改uboot的环境变量env的值来指定uImage的名字

时间:2021-08-25 16:30:10

今天继续玩基于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重启完后,可以看到,顺利的按照新的路径和文件名定位到内核文件,成功的引导了系统启动!

搞定,收工!