We are using the RK3588 SmartHub SDK to compile the Buildroot Linux system, with the following versions of U-Boot and Linux Kernel:
U-Boot 2017.09Linux version 6.1.115
The U-Boot environment variables are stored in memory by default in the source code provided by RK, with the corresponding configuration as follows:
CONFIG_ENV_IS_NOWHERE=y
Executing the saveenv command in the U-Boot command line will produce the following output:
=> saveenvSaving Environment to nowhere...
Storing U-Boot Environment Variables in Block DevicesIn the U-Boot command line, executing the command part list mmc 0 will first confirm the current partition status:
=> part list mmc 0Partition Map for MMC device 0 -- Partition Type: EFIPart Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00002000 0x000027ff "security" attrs: 0x0000000000000000 type: 43750000-0000-4030-8000-28ca00004421 guid: 601f0000-0000-405e-8000-68bb00002fa4 2 0x00004000 0x00005fff "uboot" attrs: 0x0000000000000000 type: b55a0000-0000-490f-8000-24cb0000730e guid: 9f280000-0000-482d-8000-2577000002ee 3 0x00006000 0x00045fff "boot" attrs: 0x0000000000000000 type: bb380000-0000-4b12-8000-277b0000070f guid: e67d0000-0000-4e1d-8000-73d40000777f 4 0x00046000 0x00e45fff "rootfs" attrs: 0x0000000000000000 type: 3e340000-0000-4e40-8000-64c00000248b guid: 614e0000-0000-4b53-8000-1d28000054a9 5 0x00e46000 0x0747bfde "userdata" attrs: 0x0000000000000000 type: 24690000-0000-4a57-8000-0284000025ea guid: 2d010000-0000-401e-8000-6d1600007417
It can be seen that there is an unused area before the security partition, starting at 0x00002000, which is 8192, and since each sector is 512 Bytes, the corresponding starting position is 8192*512=4MB. Therefore, we will occupy 1MB of space starting from 3MB to store U-Boot environment variables.The following modifications are required for the RK3588 SmartHub SDK:
diff --git a/build/mk-loader.sh b/build/mk-loader.shindex 1197c7f33..75ba12752 100755--- a/build/mk-loader.sh+++ b/build/mk-loader.sh@@ -65,10 +65,12 @@ build_hook(){ fi echo "./make.sh $UBOOT_COMPILE_COMMANDS" ./make.sh $UBOOT_COMPILE_COMMANDS+ ./make.sh env check_cmd_exe "build uboot" else echo "./make.sh $RK_UBOOT_DEFCONFIG $UBOOT_COMPILE_COMMANDS" ./make.sh $RK_UBOOT_DEFCONFIG $UBOOT_COMPILE_COMMANDS+ ./make.sh env check_cmd_exe "build uboot" fi
@@ -151,4 +153,4 @@ for opt in $@; do build_hook ;; esac-done\ No newline at end of file+donediff --git a/build/mk-rootfs.sh b/build/mk-rootfs.shindex 22f4cab0c..0db2ecd79 100755--- a/build/mk-rootfs.sh+++ b/build/mk-rootfs.sh@@ -153,6 +153,11 @@ build_hook(){ fatal "Failed to extract buildroot rootfs!" exit 1 fi+ cp ${RK_ROOT_DIR}/u-boot/tools/env/fw_printenv ${RK_BUILDROOT_ROOTFS_DIR}/usr/sbin/fw_printenv+ cd ${RK_BUILDROOT_ROOTFS_DIR}/usr/sbin/+ ln -s fw_printenv fw_setenv+ cd -+ echo "/dev/mmcblk0 0x300000 0x100000" > ${RK_BUILDROOT_ROOTFS_DIR}/etc/fw_env.config fi
if [ "$RK_ROOTFS_TYPE" == "debian" ]; then
These modifications involve the following:1. Generating the fw_printenv tool Execute the command sudo ./make.sh env in the u-boot source code (since the SmartHub SDK uses Docker for compilation with sudo) to generate the fw_printenv tool, with the corresponding output as follows:
u-boot$ sudo ./make.sh env[sudo] password for stxinu: CHK include/config/uboot.release CHK include/generated/version_autogenerated.h CHK include/generated/timestamp_autogenerated.h UPD include/generated/timestamp_autogenerated.h LD tools/env/built-in.o HOSTCC tools/env/aes.o HOSTCC tools/env/crc32.o HOSTCC tools/env/ctype.o HOSTCC tools/env/env_attr.o HOSTCC tools/env/env_flags.o HOSTCC tools/env/fw_env.o HOSTCC tools/env/linux_string.o AR tools/env/lib.a HOSTCC tools/env/fw_env_main.o HOSTLD tools/env/fw_printenv STRIP tools/env/fw_printenv
2. Generating the fw_setenv tool and configuration file In the u-boot/tools/env/README file, there is the following description:
You should then create a symlink from fw_setenv to fw_printenv. They use the same program and its function depends on its basename.
Therefore, in the corresponding directory, use the command ln -s fw_printenv fw_setenv to generate the fw_setenv tool. In the u-boot/tools/env/fw_env_private.h file, there is the following content:
#define CONFIG_FILE "/etc/fw_env.config"
Thus, create the /etc/fw_env.config file in the root filesystem with the following content:
/dev/mmcblk0 0x300000 0x100000
This indicates that the area starting from 0x300000 (3MB) on the EMMC device (/dev/mmcblk0) with a size of 0x100000 (1MB) is designated for storing U-Boot environment variables.3. U-Boot compilation configuration In addition to the above three files (fw_setenv, fw_printenv, and fw_env.config) being prepared for the Linux environment, the U-Boot configuration itself needs to be modified as follows:
# CONFIG_ENV_IS_NOWHERE is not setCONFIG_ENV_IS_IN_BLK_DEV=yCONFIG_ENV_OFFSET=0x300000CONFIG_ENV_SIZE=0x100000
This configures the ENV to be stored in the Block device, starting from the EMMC’s 0x300000 position with a size of 0x100000. If the CONFIG_ENV_OFFSET and CONFIG_ENV_SIZE configurations are not set, the default values can be found in the u-boot/env/Kconfig file:
if ARCH_ROCKCHIPconfig ENV_OFFSET hex "Environment offset" depends on !ENV_IS_IN_UBI depends on !ENV_IS_NOWHERE || ENVF default 0x0 if ENVF default 0x3f8000 help Offset from the start of the device (or partition)config ENV_SIZE hex "Environment size" default 0x8000 help Size of the environment storage area
VerificationAfter modifying and compiling the generated image and flashing it to the board, we can perform the following verifications:1. Executing fw_printenv in Linux will return the content that printenv returns when executed in U-Boot.2. After executing fw_setenv rk_test2 test2abc in Linux (the first execution may return Warning: Bad CRC, using default environment, which does not affect the process), reboot the machine and enter the U-Boot command line, executing printenv rk_test2 will return the following:
=> printenv rk_test2rk_test2=test2abc
Accordingly, setting an environment variable in the U-Boot command line can also be viewed in the Linux environment.PostscriptWith the above configuration, U-Boot and the Kernel can pass configuration content through environment variables stored in the designated area, achieving the necessary judgments and scenarios. Furthermore, with this configuration, the content of the ENV area will not be erased after packaging and flashing the corresponding firmware, thus adding the following partition item in the parameter.txt partition table (starting from the 3MB position of EMMC with a size of 1MB, adjustable as needed):
0x00000800@0x00001800(env)
And when packaging update.img, modify the corresponding package-file to include an item like:
env Image/zero.img
Where zero.img can be generated using the dd command to create an empty file of specified size (1MB).