Das U-Boot uses a small amount of space on the flash storage usually on the same partition it is stored on to store some important configuration parameters. This can hardly be compared to NVRAM/TFFS-approach of other bootloaders. It is called the u-boot environment. It stores some values like the IP address of the TFTP server (on your PC) to which the the TFTP client (part of U-Boot) will try to connect, etc.
You can read and write these values when you are connected to the U-Boot console via Serial Port and also from the CLI once you booted OpenWrt.
One of the huge advantages of Das U-Boot is it's ability for run time configuration. This flexibility is based on being able to easily change environment variables. The environment is usually at the end of the uboot partition. The environment variables are set up in a board specific file, e.g.
package/uboot-ar71xx/files/include/configs/nbg460n.h for the Zyxel NBG 460N/550N/550NH.
The location on the flash partition is predefined:
#define CONFIG_ENV_OFFSET 0x0000 #define CONFIG_ENV_SIZE 0x2000
and copied to RAM when U-Boot starts.
This lists the most important environment variables, all of which have a special meaning to U-Boot.
| || if set to
| || if set to
| ||a decimal number that selects the console baudrate (in bps).|
| ||The contents of this variable are passed to the Linux kernel as boot arguments (aka "command line").|
| ||This variable defines a command string that is automatically executed when the initial countdown is not interrupted. This command is only executed when the variable bootdelay is also defined!|
| || After reset, U-Boot will wait this number of seconds before it executes the contents of the bootcmd variable. During this time a countdown is printed, which can be interrupted by pressing any key.
Set this variable to 0 boot without delay. Be careful: depending on the contents of your
Set this variable to -1 to disable autoboot.
| ||name of the default image to load with TFTP|
| || Ethernet MAC address for first/only ethernet interface (
This variable can be set only once (usually during manufacturing of the board). U-Boot refuses to delete or overwrite this variable once it has been set.
| || IP address; needed for
| || Default load address for commands like
| || TFTP server IP address; needed for
| || If the configuration option
| || If set to
printenv ipaddr hostname netmask ipaddr=192.168.0.2 hostname=openwrt netmask=255.255.255.0 print bootdelay bootdelay=1 print serverip serverip=192.168.0.5
set bootcmd 'tftp 0x1000000 uImage548; bootm' set ipaddr 18.104.22.168 print ipaddr ipaddr=22.214.171.124 dhcp start Auto negotiation... (take ~2sec) Auto negotiation complete, 1000BaseT, full duplex BOOTP broadcast 1 DHCP client bound to address 126.96.36.199 print serverip serverip=188.8.131.52 set serverip 184.108.40.206
set foo 'tftp 0x1000000 uImage123; bootm' print foo tftp 0x1000000 uImage123; bootm set foo print foo ## Error: "foo" not defined
All changes you make to the U-Boot environment are made in RAM only! If you want to additionally make your changes permanent you have to use the
saveenv command to write a copy of the environment settings from RAM to persistent storage. The
saveenv command is not available in the
uboot-envtools, also, the bootloader partition will likely be mounted read-only. An example on how to change this, is here: making.bootloader.partition.writable
|uboot-envtools||20081215-2||zlib||7843|| This package includes tools to read (
You need to install and configure
opkg install uboot-envtools vi /etc/fw_env.config
# Configuration file for fw_(printenv/saveenv) utility. # Up to two entries are valid, in this case the redundant # environment sector is assumed present. # Notice, that the "Number of sectors" is ignored on NOR and SPI-dataflash. # Futhermore, if the Flash sector size is ommitted, this value is assumed to # be the same as the Environment size, which is valid for NOR and SPI-dataflash # NOR example # MTD device name Device offset Env. size Flash sector size Number of sectors /dev/mtd1 0x0000 0x4000 0x4000 /dev/mtd2 0x0000 0x4000 0x4000 # MTD SPI-dataflash example # MTD device name Device offset Env. size Flash sector size Number of sectors #/dev/mtd5 0x4200 0x4200 #/dev/mtd6 0x4200 0x4200 # NAND example #/dev/mtd0 0x4000 0x4000 0x20000 2
Expect that the environment address is a multiple of the block size. Please read the documentation file in the U-boot Source Code: /tools/env/README
In case of the WR1043ND, I was "lucky" in the file:
include/configs/ap83.h (in Source Code, obtain from manufacturer). I found following values:
/*----------------------------------------------------------------------- * FLASH and environment organization */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ //#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ #define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */ #define CFG_FLASH_SECTOR_SIZE (64*1024) #define CFG_FLASH_SIZE 0x00800000 /* Total flash size */ #define CFG_FLASH_WORD_SIZE unsigned short #define CFG_FLASH_ADDR0 (0x5555) /* 1st address for flash config cycles */ #define CFG_FLASH_ADDR1 (0x2AAA) /* 2nd address for flash config cycles */ #define CFG_HOWL_1_2 1Maybe due to the historic version of uboot, the variable names are different.
Cannot parse config file: Invalid argument
Useful offset information can also be found by running dmesg on your device. This is taken from a modified WT3020:
[ 0.400000] 0x000000000000-0x000000030000 : "u-boot" [ 0.420000] 0x000000030000-0x000000040000 : "u-boot-env" [ 0.430000] 0x000000040000-0x000000050000 : "factory" [ 0.440000] 0x000000050000-0x000001000000 : "firmware" [ 0.480000] 0x00000015db2b-0x000001000000 : "rootfs" [ 0.540000] 0x000000500000-0x000001000000 : "rootfs_data"
and also from /proc/mtd. Example below.
cat /proc/mtd dev: size erasesize name mtd0: 00030000 00010000 "u-boot" mtd1: 00010000 00010000 "u-boot-env" mtd2: 00010000 00010000 "factory" mtd3: 00fb0000 00010000 "firmware" mtd4: 00ea24d5 00010000 "rootfs" mtd5: 00b00000 00010000 "rootfs_data"
root@openwrt:~# fw_printenv baudrate=115200 loads_echo=0 ipaddr=169.254.123.123 serverip=169.254.254.254 rootpath=/mnt/ARM_FS/ netmask=255.255.0.0 run_diag=yes console=console=ttyS0,115200 CASset=min MALLOC_len=1 ethprime=egiga0 bootargs_root=root=/dev/mtdblock2 ro ethmtu=1500 usb0Mode=host nandEcc=1bit ethact=egiga0 ethaddr=00:10:75:xx:xx:xx cesvcid=6UQX37NNJL85RGNQ5RKCBM5DDN ceserialno=2GEP09HS ceboardver=REDSTONE:1.0 bootcmd=nand read.e 0x800000 0x100000 0x300000; setenv bootargs $(console) $(bootargs_root); bootm 0x800000 arcNumber=2097 stdin=serial stdout=serial stderr=serial mainlineLinux=yes enaMonExt=no enaCpuStream=no enaWrAllo=no pexMode=RC disL2Cache=no setL2CacheWT=yes disL2Prefetch=yes enaICPref=yes enaDCPref=yes sata_dma_mode=yes netbsd_en=no vxworks_en=no bootdelay=3 disaMvPnp=no Environment size: 778/131068 bytes
In above example the boot partition is 2x64KiB ins size, but the booloader console only reports 131068 Bytes which is 4 Bytes short. How can this be? This could be CRC32 value. Furthermore we see, the environment occupies 778Bytes! Now we guess, the environment is located at the end of the partition and the CRC32 is again behind it. So it's offset should be, hmm, hmm, 131.068-778=130.290 and minus 1 because we count the zeros = 130.289 in hex 0x0001FCF1. Let's do a backup and look at the content of the whole partition with help of a hex editor. The assumption was obviously wrong. At the end, there is only FF data at the end.
Revert u-boot silent boot and add a bootdelay
fw_setenv silent Unlocking flash... Done Erasing old environment... Done Writing environment to /dev/mtd0... Done Locking ... Done fw_setenv bootdelay 1 Unlocking flash... Done Erasing old environment... Done Writing environment to /dev/mtd0... Done Locking ... Done