How to write u-boot environment variables with fw_setenv fdt_file


I am trying to change my dtb file using uboot environment variable fw_setenv fdt_file custom-devicetree.dtbbut after reboot again the old .dtb file loaded. Then I found that the boot partition is readonly and I source the script source /etc/profile.d/ to make boot partition writable. I tried again to reboot and faced the same problem.

my goal is to write the env_vairable only using fw_setenv fdt_file

Is there some steps i have missed?

Thank you in advance


What version of things are you using?

Hi Max,

sorry, I forget to upload the version info

root@apalis-imx6:~# uname -a
Linux apalis-imx6 4.1.35-v2.7b1+gc117783 #1 SMP Tue Oct 17 13:21:57 CEST 2017 armv7l GNU/Linux

What is the version of your U-Boot?

Can you post the content of /etc/fw_env.config?

u boot version :U-Boot 2015.04 (Dec 02 2015 - 09:35:08)

content from /etc/fw_env.config

    # Configuration file for fw_(printenv/setenv) utility.
    # Up to two entries are valid, in this case the redundant
    # environment sector is assumed present.
    # Device offset must be prefixed with 0x to be parsed as a hexadecimal value.
    # On a block device a negative offset is treated as a backwards offset from the
    # end of the device/partition, rather than a forwards offset from the start.
    # Colibri iMX6/Apalis iMX6
    # U-Boot environment is stored at the end of the first eMMC boot partition
    # hence use a negative value. The environment is just in front of the config
    # block which occupies the last sector (hence -0x200)
    # Block device name	Device offset	Env. size
    /dev/mmcblk0boot0	-0x2200		0x2000

I found that my new kernel fw_env.config was different from the old kernel. Is there any possibility to change environment variables with out updating the u-boot ?

Your U-Boot version is ambiguous. With Linux Image V2.5 Beta 2 (November 6, 2015) we changed among other things

  • boot U-Boot from the eMMC boot area (/dev/mmcblk0boot0)
  • move environment to the end of the eMMC boot area before the config block

This included changing /etc/fw_env.config in the rootfs so that it finds the new U-Boot environment storage location in the eMMC boot area.

If you mix an old U-Boot with the new rootfs then you will modify the new location from your Linux but U-Boot will read from the old one.

You could try what happens if you modify /etc/fw_env.config to read/write to the old location:

e.g. changing:

#/dev/mmcblk0boot0    -0x2200        0x2000  
/dev/mmcblk0 0x80000 0x2000


P.S. Note that you will have to move to boot from the eMMC boot area with new modules. Check the PCN for your specific module type here.

I modified the fw_env.config and changed the fdt_file.

Now, after rebooting the file changed to my custom.dtb in kernel, but not updated in the U-boot

Hit any key to stop autoboot:  0
Saving Environment to MMC...
Writing to MMC(0)... done
Booting from internal eMMC chip...
reading imx6q-apalis-eval1.dtb
49952 bytes read in 19 ms (2.5 MiB/s)
reading uImage1
4844728 bytes read in 147 ms (31.4 MiB/s)
## Booting kernel from Legacy Image at 11000000 ...
   Image Name:   Linux-4.1.35-v2.7b1+gc117783
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4844664 Bytes = 4.6 MiB
   Load Address: 10008000
   Entry Point:  10008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 12000000
   Booting using the fdt blob at 0x12000000
   Loading Kernel Image ... OK
   Using Device Tree in place at 12000000, end 1200f31f

Starting kernel ...

I have also updated my U-boot version to 2016.11+fslc+g22e68cb (Aug 14 2017 - 11:28:45 +0200) and tried with both modifying and without modifying /etc/fw_env.config. I experienced the same results.


I don’t know what exactly goes wrong in your case. You seem to mix various components of the Image from different versions which do not work together.
So I sum up here what is involved in the U-Boot environment handling.

  • U-Boot

U-Boot is reading its environment from the eMMC. This used to be in the user area of the eMMC at byte address 0x80000 and with with Linux Image V2.5 Beta 2 this moved to the first boot area of the eMMC, 0x2200 before the end of that partition. If U-Boot does not find a valid checksum it uses defaults compiled into the U-Boot binary.
Note that by default we do not store an U-Boot environment ex. factory and rely on the defaults compiled in.

  • User Space Tools, e.g. the relevant files in the rootfs

fw_printenv and fw_setenv use the file ‘/etc/fw_env.config’ to get the U-Boot environment location. The fw_printenv/fw_setenv binaries also fall back to defaults in the binary if they do not find a valid checksum in the eMMC.

  • Kernel

The kernel needs to be able to read and write the eMMC location were the environment is stored. I think that only very old kernel versions could be affected. But the boot area is only accessible read only by default, setting this to rw can be accomplished by executing ‘source /etc/profile.d/’. On a serial getty this is done automatically when one does login.

So, you have to make sure that your version of U-Boot and the file ‘/etc/fw_env.config’ agree on the location were the environment is stored.

Additionally, you have to either save the environment once from U-Boot before using the fw_printenv/fw_saveenv tools OR you must be able to live with the default environment stored in the fw_saveenv binary.