Managing U-Boot Environment from Linux

Managing U-Boot Environment from Linux

Managing U-Boot Environment from Linux

U-Boot makes use of the so-called environment variables to define various aspects of the target functionality. The U-Boot environment is persistent across power or reset cycles. Its storage location depends on the board: on the NXP i.MX RT1xxx EVK board the environment is kept on the SD Card, while on the Avnet MaaXBoard RT it is stored in the on-board HyperFlash. Parameters defined by the U-boot environment variables include: target IP address, target MAC address, location in RAM where a Linux bootable image will be loaded, and many others.

In various use case scenarios, it may be needed to read or update U-Boot environment variables from Linux. Probably, the most obvious scenario would be when a remote target is accessible only through an Ethernet or WiFi link and no access to the serial console is available. In that scenario, it is impossible to get access to the U-Boot serial line command monitor, however the target still can be connected to over a telnet or ssh link providing access to the Linux shell interface. This application note explains how to read and update U-Boot environment variables from Linux.

The Linux utilities are called fw_printenv (read U-Boot environment) and fw_setenv (modify U-Boot environment). The two utilities are in fact implemented as a single utility, and the name of the executable file is used to distinguish between the fw_printenv and fw_setenv use cases on the target.

When you boot the newly installed Linux image on the target, you will be able to read and update the U-Boot environment. Here are some examples.

The following command reads the whole U-Boot environment:

/ # fw_printenv addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off arch=arm baudrate=115200 board=imxrt1170-evk board_name=imxrt1170-evk bootcmd=run mmcboot bootdelay=2 cpu=armv7m ... / #

Here is how you can read a specific environment variable:

/ # fw_printenv bootdelay bootdelay=0 / #

Here is how you change the value of an environment variable:

/ # fw_setenv bootdelay 5 / #

Having updated bootdelay as shown above, on the next reset U-Boot will wait for 5 seconds for you to press a keyboard and enter the U-Boot command monitor before proceeding to boot Linux.

The fw_printenv and fw_setenv utilities are provided by the libubootenv project. Pre-built binaries of the utilities and the libubootenv shared library are included in the BSP under A2F/root/usr/bin/fw_printenv and A2F/root/usr/lib/libubootenv.so.

When run on the target, the utility makes use of a configuration file that defines the geometry of the device and where the U-Boot environment is located in it. The configuration file format is board-specific, as described below.

NXP i.MX RT1xxx EVK boards

On these board the U-Boot environment is stored on the SD Card (MMC). The configuration file is as follows:

-bash-4.2$ cat projects/rootfs/etc/fw_env.config.mmc # Configuration file for fw_(printenv/setenv) utility. # Up to two entries are valid, in this case the redundant # environment sector is assumed present. # Configuration for a board with CONFIG_ENV_IS_IN_MMC # # MTD device name Device offset Env. size /dev/mmcblk0 0x80000 0x1f000

Avnet MaaXBoard RT

On this board the U-Boot environment is stored in HyperFlash (Cypress S26KS256S, 32 MB). The flash is exposed to Linux as an MTD device partitioned as follows:

Partition

MTD device

Label

Offset

Size

Partition

MTD device

Label

Offset

Size

0

/dev/mtd0

uboot

0x000000

0x080000

1

/dev/mtd1

uboot_env

0x080000

0x080000

2

/dev/mtd2

uImage

0x100000

0xD00000

3

/dev/mtd3

rootfs

0xE00000

0x1200000

The U-Boot environment (with a redundant copy) resides in the uboot_env partition. The configuration file accounts for the redundant environment layout and the 256 KB flash sector size:

$ cat projects/rootfs/etc/fw_env.config.hyperflash # Configuration file for fw_(printenv/setenv) utility. # Up to two entries are valid, in this case the redundant # environment sector is assumed present. # Configuration for the MaaXBoard RT (CONFIG_ENV_IS_IN_FLASH, hyperflash) # # MTD device name Device offset Env. size Flash sector size /dev/mtd1 0x0000 0x40000 0x40000 /dev/mtd1 0x40000 0x40000 0x40000

The two entries define the primary and redundant environment locations within the uboot_env partition. The environment size and flash sector size are both 0x40000 (256 KB).

Root filesystem integration

In the rootfs project, the fw_setenv and the configuration file are added to rootfs.initramfs:

... file /bin/fw_printenv ${INSTALL_ROOT}/u-boot/tools/env/fw_printenv 755 0 0 slink /bin/fw_setenv fw_printenv 755 0 0 ... ifarch IMXRT117X_NXPEVK file /etc/fw_env.config ${INSTALL_ROOT}/projects/${SAMPLE}/etc/fw_env.config.mmc 644 0 0 ifarch MAAXBOARD_RT file /etc/fw_env.config \ ${INSTALL_ROOT}/projects/${SAMPLE}/etc/fw_env.config.hyperflash 644 0 0 ...

Several U-Boot environment variables are used very early during the Linux bootstrap, at the /etc/rc stage.