June 25, 2024

Zynq - Poke around the U-Boot source

Recently I cloned the Xilinx U-Boot repository and built U-Boot. More on that elsewhere.

Since I have the source handy, I can investigate some things. To get started, I do this:

cd /u1/Projects/Zynq/u-boot-xlnx
ctags -R .
Next I do a recursive grep looking for 0xE0000 -- the mistaken address that U-Boot performs its saveenv to. I discover:
./.config:CONFIG_ENV_OFFSET=0xE00000
./configs/xilinx_zynq_virt_defconfig:CONFIG_ENV_OFFSET=0xE00000
What is odd here though is that this is shifted 4 bits left. I.e. it is E00000 with five zeros, not E0000 with 4 zeros.
Interestingly, I see also:
./env/Kconfig:	default 0xE0000 if ARCH_ZYNQ
A comment in this file says:
This offset may be interpreted differently depending on the chosen
ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may
be negative to indicate an offset backwards from the end of the
partition. See the relevant help messages for more details.
I search for this and in u-boot.cfg I find:
#define CONFIG_ENV_IS_IN_FAT 1
#define CONFIG_ENV_IS_IN_NAND 1
#define CONFIG_ENV_IS_IN_SPI_FLASH 1
#define CONFIG_ENV_IS_NOWHERE 1
More "grepping" gives me these candidates for study:
./board/xilinx/zynq/board.c:		if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
./env/env.c:#ifdef CONFIG_ENV_IS_IN_NAND
It is nice that all the "env" related codes seems to be collected together in the "env" directory In board.c we find a routine "env_get_location()" with a block of code like this:
	switch (bootmode) {
        case ZYNQ_BM_SD:
                if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
                        return ENVL_FAT;
                if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
                        return ENVL_EXT4;
                return ENVL_NOWHERE;
        case ZYNQ_BM_NAND:
                if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
                        return ENVL_NAND;
                if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI))
                        return ENVL_UBI;
                return ENVL_NOWHERE;
At the risk of heading off on a tangent, note that if we are booting from SD card, the environment may be in FAT, which could be nice. However, I'll swear that the U-Boot I have on my hardware (which is not the same as this source by any means) performs the obnoxious saveenv to NAND at 0xE0000.

First we look at env/fat.c -- an important configuration parameter is

u-boot.cfg:#define CONFIG_ENV_FAT_FILE "uboot.env"
u-boot.cfg:#define CONFIG_ENV_FAT_FILE_REDUND "uboot-redund.env"

Next we look at env/nand.c

Some versions of U-boot support a pair of environment variables that define where the bootenv partition of the flash is at:

The saveenv command will save the environment variables to the bootenv partition of the flash. This partition is defined by the environment variables bootenvstart and bootenvsize
I do see that my U-boot (from 2014) has this defined:
bootenv=uEnv.txt
I try an experiment of putting all 3 of these files on the FAT partition:
uboot.env
uEnv.txt
u-boot.scr
The last filename was already on the card -- I replaced the contents with junk that U-boot should trip over. I "boot" the card and see no evidence that it saw any of these files or was annoyed by them.

Conclusion

My board is running:
U-Boot 2014.01-gfb1d3e7-dirty (Mar 09 2018 - 19:36:04)
The sources I have been examining are 10 years more recent. What I believe is that the ancient build I am using has a stupid bad offset for saveenv to NAND, and no facility to pull the environment from a file on the SD card.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org