[PATCH v10 0/9] env: Allow environment in text files

One barrier to completing the 7-year-long Kconfig migration is that the default environment is implemented using ad-hoc CONFIG options. At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS.
It is not really feasible to move the environment to Kconfig as it is hundreds of lines of text in some cases.
Even considering the current situation, it is painful to add large amounts of text to the config-header file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
This is already supported by the CONFIG_USE_DEFAULT_ENV_FILE feature. but that does not support use of CONFIG options or comments, so is best suited for use by other build systems wanting to define the U-Boot environment.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file board/<vendor>/<board>.env or use CONFIG_ENV_SOURCE_FILE to set a filename.
The environment variables should be of the form "var=value". Values can extend to multiple lines. This series converts the existing environment documentation to rST and updates it to explain how to use this.
Note: this series was originally sent eight years ago:
https://patchwork.ozlabs.org/project/uboot/patch/1382763695-2849-4-git-send-...
It has been updated to work with Kconfig, etc. Some review comments in that patch were infeasible so I have not addressed them. I would like this series to be considered independently, on its merits.
Rather than deal with the complexity of rewriting the distro-boot script, this is disabled for sandbox. The forthcoming bootmethod approach should provide the same functionality without needing the complex scripting in the environment.
Migration needs more thought, although it can be done later. It may be possible to do migrate automatically, using buildman to extract the built-in environmnent from the ELF file.
This would produce a pretty ugly conversion though, since it would drop all the intermediate variables used to create the environment.
Better would be to parse the config.h file, figure out the components of CONFIG_EXTRA_ENV_SETTINGS then output these as separate pieces in the file. It is not clear how easy that would be, nor whether the result would be very pretty. Also the __stringify() macro needs to be handled somehow.
This series is available at u-boot-dm/env-working
Comments welcome.
Changes in v10: - Use backslash to allow assignment to a variable ending in + - Add rST file into the index - Minor tweaks to the script's pattern matching - Add updates as suggested by Heinrich - Add new patch to update the test MAC/IP addresses
Changes in v9: - Drop mention of other strange characters - Clarify that the + restriction is on the variable name not its value - Add some tests for the script - Deal with leading tabs - Squash indentation down to one space - Convert newlines within strings to spaces, which seems more consistent - Handle appending an empty string to an empty var - Fix blank line between tags - Fix typo in commit message - More bikeshedding on env_get_autostart() - Fix '<vendor><board>' in cover letter - Use env_get_yesno() in env_get_autostart() and update docs
Changes in v8: - Update commit message to avoid mentioning the 'env' subdirectory - Update commit message to mention the + restriction, etc. - Overwrite the env file each time, to avoid incremental-build problems - Fix ambiguity about what is ignored - Go into more detail about the change of behaviour with autostart
Changes in v7: - Use 'env' basename instead of 'environment' for intermediate output files - Show a message indicating the source text file being used - Give an error if CONFIG_EXTRA_ENV_SETTINGS is also defined - Use CONFIG_ENV_SOURCE_FILE instead of rules to specify the text-file name - Make board.env the default name if CONFIG_ENV_SOURCE_FILE is empty - Rewrite the documentation - Drop the use of common.env - Update awk script to output the whole CONFIG string, or just a comment - Add new patch to explain the relationship with DEFAULT_ENV_FILE - A few more tweaks - Update the cover letter
Changes in v6: - Move all updates to a separate patch - Combine the two env2string.awk patches into one - Move all updates to a separate patch - More updates and improvements - Add new patch to tidy up use of autostart env var
Changes in v5: - Minor updates as suggested by Wolfgang - Explain how to include the common.env file - Explain why variables starting with _ , and / are not supported - Expand the definition of how to declare an environment variable - Explain what happens to empty variables - Update maintainer - Move use of += to this patch - Explain that environment variables may not end in + - Minor updates as suggested by Wolfgang
Changes in v4: - Add new patch to move environment documentation to rST - Move this from being part of configuring U-Boot to part of building it - Don't put the environment in autoconf.mk as it is not needed - Add documentation in rST format instead of README - Drop mention of import/export - Update awk script to ignore blank lines, as generated by clang - Add documentation in rST format instead of README - Add new patch to move environment documentation to rST
Changes in v3: - Adjust Makefile to generate the .inc and .h files in separate fules - Add more detail in the README about the format of .env files - Improve the comment about " in the awk script - Correctly terminate environment files with \n - Define __UBOOT_CONFIG__ when collecting environment files - Add new patch to use a text-based environment for sandbox
Changes in v2: - Move .env file from include/configs to board/ - Use awk script to process environment since it is much easier on the brain - Add information and updated example script to README - Add dependency rule so that the environment is rebuilt when it changes - Add separate patch to enable C preprocessor for environment files - Enable var+=value form to simplify composing variables in multiple steps
Simon Glass (9): sandbox: Drop distro_boot doc: Move environment documentation to rST env: Allow U-Boot scripts to be placed in a .env file sandbox: Use a text-based environment doc: Mention CONFIG_DEFAULT_ENV_FILE doc: Improve environment documentation doc: Improve environment documentation further sandbox: Update the test MAC/IP addresses bootm: Tidy up use of autostart env var
MAINTAINERS | 7 + Makefile | 66 ++++- README | 328 ------------------------- board/sandbox/sandbox.env | 25 ++ cmd/bootm.c | 4 +- cmd/elf.c | 3 +- common/bootm_os.c | 5 +- config.mk | 2 + doc/develop/environment.rst | 51 ++++ doc/develop/index.rst | 1 + doc/usage/environment.rst | 465 ++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 2 + env/Kconfig | 18 ++ env/common.c | 5 + env/embedded.c | 1 + include/configs/sandbox.h | 40 ---- include/env.h | 7 + include/env_default.h | 11 + scripts/env2string.awk | 80 +++++++ test/py/tests/test_env.py | 107 +++++++++ 20 files changed, 850 insertions(+), 378 deletions(-) create mode 100644 board/sandbox/sandbox.env create mode 100644 doc/develop/environment.rst create mode 100644 doc/usage/environment.rst create mode 100644 scripts/env2string.awk

This is a complicated set of #defines and it is painful to convert to a text file. We can (once pending patches are applied) provide the same functionality with bootmethod. Drop this for sandbox to allow conversion to a text-file environment.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz ---
(no changes since v1)
include/configs/sandbox.h | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 24c9a84fa35..c19232f202f 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -49,16 +49,6 @@ #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ 115200}
-#define BOOT_TARGET_DEVICES(func) \ - func(HOST, host, 1) \ - func(HOST, host, 0) - -#ifdef __ASSEMBLY__ -#define BOOTENV -#else -#include <config_distro_bootcmd.h> -#endif - #define CONFIG_KEEP_SERVERADDR #define CONFIG_UDP_CHECKSUM #define CONFIG_TIMESTAMP @@ -103,7 +93,6 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ SANDBOX_SERIAL_SETTINGS \ SANDBOX_ETH_SETTINGS \ - BOOTENV \ MEM_LAYOUT_ENV_SETTINGS
#ifndef CONFIG_SPL_BUILD

On Thu, Oct 21, 2021 at 09:08:44PM -0600, Simon Glass wrote:
This is a complicated set of #defines and it is painful to convert to a text file. We can (once pending patches are applied) provide the same functionality with bootmethod. Drop this for sandbox to allow conversion to a text-file environment.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz
For the series, applied to u-boot/next, thanks!

Move this from the README to rST format.
Drop i2cfast since it is obviously obsolete and breaks the formatting. Other changes and improvements are in a following patch.
Signed-off-by: Simon Glass sjg@chromium.org Acked-by: Marek Behún marek.behun@nic.cz ---
(no changes since v6)
Changes in v6: - Move all updates to a separate patch
Changes in v5: - Minor updates as suggested by Wolfgang
Changes in v4: - Add new patch to move environment documentation to rST
README | 328 -------------------------------- doc/usage/environment.rst | 381 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 328 deletions(-) create mode 100644 doc/usage/environment.rst
diff --git a/README b/README index 840b192aae5..f20bc38a41c 100644 --- a/README +++ b/README @@ -2999,334 +2999,6 @@ TODO. For now: just type "help <command>".
-Environment Variables: -====================== - -U-Boot supports user configuration using Environment Variables which -can be made persistent by saving to Flash memory. - -Environment Variables are set using "setenv", printed using -"printenv", and saved to Flash using "saveenv". Using "setenv" -without a value can be used to delete a variable from the -environment. As long as you don't save the environment you are -working with an in-memory copy. In case the Flash area containing the -environment is erased by accident, a default environment is provided. - -Some configuration options can be set using Environment Variables. - -List of environment variables (most likely not complete): - - baudrate - see CONFIG_BAUDRATE - - bootdelay - see CONFIG_BOOTDELAY - - bootcmd - see CONFIG_BOOTCOMMAND - - bootargs - Boot arguments when booting an RTOS image - - bootfile - Name of the image to load with TFTP - - bootm_low - Memory range available for image processing in the bootm - command can be restricted. This variable is given as - a hexadecimal number and defines lowest address allowed - for use by the bootm command. See also "bootm_size" - environment variable. Address defined by "bootm_low" is - also the base of the initial memory mapping for the Linux - kernel -- see the description of CONFIG_SYS_BOOTMAPSZ and - bootm_mapsize. - - bootm_mapsize - Size of the initial memory mapping for the Linux kernel. - This variable is given as a hexadecimal number and it - defines the size of the memory region starting at base - address bootm_low that is accessible by the Linux kernel - during early boot. If unset, CONFIG_SYS_BOOTMAPSZ is used - as the default value if it is defined, and bootm_size is - used otherwise. - - bootm_size - Memory range available for image processing in the bootm - command can be restricted. This variable is given as - a hexadecimal number and defines the size of the region - allowed for use by the bootm command. See also "bootm_low" - environment variable. - - bootstopkeysha256, bootdelaykey, bootstopkey - See README.autoboot - - updatefile - Location of the software update file on a TFTP server, used - by the automatic software update feature. Please refer to - documentation in doc/README.update for more details. - - autoload - if set to "no" (any string beginning with 'n'), - "bootp" will just load perform a lookup of the - configuration from the BOOTP server, but not try to - load any image using TFTP - - autostart - if set to "yes", an image loaded using the "bootp", - "rarpboot", "tftpboot" or "diskboot" commands will - be automatically started (by internally calling - "bootm") - - If set to "no", a standalone image passed to the - "bootm" command will be copied to the load address - (and eventually uncompressed), but NOT be started. - This can be used to load and uncompress arbitrary - data. - - fdt_high - if set this restricts the maximum address that the - flattened device tree will be copied into upon boot. - For example, if you have a system with 1 GB memory - at physical address 0x10000000, while Linux kernel - only recognizes the first 704 MB as low memory, you - may need to set fdt_high as 0x3C000000 to have the - device tree blob be copied to the maximum address - of the 704 MB low memory, so that Linux kernel can - access it during the boot procedure. - - If this is set to the special value 0xFFFFFFFF then - the fdt will not be copied at all on boot. For this - to work it must reside in writable memory, have - sufficient padding on the end of it for u-boot to - add the information it needs into it, and the memory - must be accessible by the kernel. - - fdtcontroladdr- if set this is the address of the control flattened - device tree used by U-Boot when CONFIG_OF_CONTROL is - defined. - - i2cfast - (PPC405GP|PPC405EP only) - if set to 'y' configures Linux I2C driver for fast - mode (400kHZ). This environment variable is used in - initialization code. So, for changes to be effective - it must be saved and board must be reset. - - initrd_high - restrict positioning of initrd images: - If this variable is not set, initrd images will be - copied to the highest possible address in RAM; this - is usually what you want since it allows for - maximum initrd size. If for some reason you want to - make sure that the initrd image is loaded below the - CONFIG_SYS_BOOTMAPSZ limit, you can set this environment - variable to a value of "no" or "off" or "0". - Alternatively, you can set it to a maximum upper - address to use (U-Boot will still check that it - does not overwrite the U-Boot stack and data). - - For instance, when you have a system with 16 MB - RAM, and want to reserve 4 MB from use by Linux, - you can do this by adding "mem=12M" to the value of - the "bootargs" variable. However, now you must make - sure that the initrd image is placed in the first - 12 MB as well - this can be done with - - setenv initrd_high 00c00000 - - If you set initrd_high to 0xFFFFFFFF, this is an - indication to U-Boot that all addresses are legal - for the Linux kernel, including addresses in flash - memory. In this case U-Boot will NOT COPY the - ramdisk at all. This may be useful to reduce the - boot time on your system, but requires that this - feature is supported by your Linux kernel. - - ipaddr - IP address; needed for tftpboot command - - loadaddr - Default load address for commands like "bootp", - "rarpboot", "tftpboot", "loadb" or "diskboot" - - loads_echo - see CONFIG_LOADS_ECHO - - serverip - TFTP server IP address; needed for tftpboot command - - bootretry - see CONFIG_BOOT_RETRY_TIME - - bootdelaykey - see CONFIG_AUTOBOOT_DELAY_STR - - bootstopkey - see CONFIG_AUTOBOOT_STOP_STR - - ethprime - controls which interface is used first. - - ethact - controls which interface is currently active. - For example you can do the following - - => setenv ethact FEC - => ping 192.168.0.1 # traffic sent on FEC - => setenv ethact SCC - => ping 10.0.0.1 # traffic sent on SCC - - ethrotate - When set to "no" U-Boot does not go through all - available network interfaces. - It just stays at the currently selected interface. - - netretry - When set to "no" each network operation will - either succeed or fail without retrying. - When set to "once" the network operation will - fail when all the available network interfaces - are tried once without success. - Useful on scripts which control the retry operation - themselves. - - npe_ucode - set load address for the NPE microcode - - silent_linux - If set then Linux will be told to boot silently, by - changing the console to be empty. If "yes" it will be - made silent. If "no" it will not be made silent. If - unset, then it will be made silent if the U-Boot console - is silent. - - tftpsrcp - If this is set, the value is used for TFTP's - UDP source port. - - tftpdstp - If this is set, the value is used for TFTP's UDP - destination port instead of the Well Know Port 69. - - tftpblocksize - Block size to use for TFTP transfers; if not set, - we use the TFTP server's default block size - - tftptimeout - Retransmission timeout for TFTP packets (in milli- - seconds, minimum value is 1000 = 1 second). Defines - when a packet is considered to be lost so it has to - be retransmitted. The default is 5000 = 5 seconds. - Lowering this value may make downloads succeed - faster in networks with high packet loss rates or - with unreliable TFTP servers. - - tftptimeoutcountmax - maximum count of TFTP timeouts (no - unit, minimum value = 0). Defines how many timeouts - can happen during a single file transfer before that - transfer is aborted. The default is 10, and 0 means - 'no timeouts allowed'. Increasing this value may help - downloads succeed with high packet loss rates, or with - unreliable TFTP servers or client hardware. - - tftpwindowsize - if this is set, the value is used for TFTP's - window size as described by RFC 7440. - This means the count of blocks we can receive before - sending ack to server. - - vlan - When set to a value < 4095 the traffic over - Ethernet is encapsulated/received over 802.1q - VLAN tagged frames. - - bootpretryperiod - Period during which BOOTP/DHCP sends retries. - Unsigned value, in milliseconds. If not set, the period will - be either the default (28000), or a value based on - CONFIG_NET_RETRY_COUNT, if defined. This value has - precedence over the valu based on CONFIG_NET_RETRY_COUNT. - - memmatches - Number of matches found by the last 'ms' command, in hex - - memaddr - Address of the last match found by the 'ms' command, in hex, - or 0 if none - - mempos - Index position of the last match found by the 'ms' command, - in units of the size (.b, .w, .l) of the search - - zbootbase - (x86 only) Base address of the bzImage 'setup' block - - zbootaddr - (x86 only) Address of the loaded bzImage, typically - BZIMAGE_LOAD_ADDR which is 0x100000 - -The following image location variables contain the location of images -used in booting. The "Image" column gives the role of the image and is -not an environment variable name. The other columns are environment -variable names. "File Name" gives the name of the file on a TFTP -server, "RAM Address" gives the location in RAM the image will be -loaded to, and "Flash Location" gives the image's address in NOR -flash or offset in NAND flash. - -*Note* - these variables don't have to be defined for all boards, some -boards currently use other variables for these purposes, and some -boards use these variables for other purposes. - -Image File Name RAM Address Flash Location ------ --------- ----------- -------------- -u-boot u-boot u-boot_addr_r u-boot_addr -Linux kernel bootfile kernel_addr_r kernel_addr -device tree blob fdtfile fdt_addr_r fdt_addr -ramdisk ramdiskfile ramdisk_addr_r ramdisk_addr - -The following environment variables may be used and automatically -updated by the network boot commands ("bootp" and "rarpboot"), -depending the information provided by your boot server: - - bootfile - see above - dnsip - IP address of your Domain Name Server - dnsip2 - IP address of your secondary Domain Name Server - gatewayip - IP address of the Gateway (Router) to use - hostname - Target hostname - ipaddr - see above - netmask - Subnet Mask - rootpath - Pathname of the root filesystem on the NFS server - serverip - see above - - -There are two special Environment Variables: - - serial# - contains hardware identification information such - as type string and/or serial number - ethaddr - Ethernet address - -These variables can be set only once (usually during manufacturing of -the board). U-Boot refuses to delete or overwrite these variables -once they have been set once. - - -Further special Environment Variables: - - ver - Contains the U-Boot version string as printed - with the "version" command. This variable is - readonly (see CONFIG_VERSION_VARIABLE). - - -Please note that changes to some configuration parameters may take -only effect after the next boot (yes, that's just like Windoze :-). - - -Callback functions for environment variables: ---------------------------------------------- - -For some environment variables, the behavior of u-boot needs to change -when their values are changed. This functionality allows functions to -be associated with arbitrary variables. On creation, overwrite, or -deletion, the callback will provide the opportunity for some side -effect to happen or for the change to be rejected. - -The callbacks are named and associated with a function using the -U_BOOT_ENV_CALLBACK macro in your board or driver code. - -These callbacks are associated with variables in one of two ways. The -static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC -in the board configuration to a string that defines a list of -associations. The list must be in the following format: - - entry = variable_name[:callback_name] - list = entry[,list] - -If the callback name is not specified, then the callback is deleted. -Spaces are also allowed anywhere in the list. - -Callbacks can also be associated by defining the ".callbacks" variable -with the same list format above. Any association in ".callbacks" will -override any association in the static list. You can define -CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the -".callbacks" environment variable in the default or embedded environment. - -If CONFIG_REGEX is defined, the variable_name above is evaluated as a -regular expression. This allows multiple variables to be connected to -the same callback without explicitly listing them all out. - -The signature of the callback functions is: - - int callback(const char *name, const char *value, enum env_op op, int flags) - -* name - changed environment variable -* value - new value of the environment variable -* op - operation (create, overwrite, or delete) -* flags - attributes of the environment variable change, see flags H_* in - include/search.h - -The return value is 0 if the variable change is accepted and 1 otherwise. - - Note for Redundant Ethernet Interfaces: =======================================
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst new file mode 100644 index 00000000000..7a733b44556 --- /dev/null +++ b/doc/usage/environment.rst @@ -0,0 +1,381 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Environment Variables +===================== + +U-Boot supports user configuration using Environment Variables which +can be made persistent by saving to Flash memory. + +Environment Variables are set using "setenv", printed using +"printenv", and saved to Flash using "saveenv". Using "setenv" +without a value can be used to delete a variable from the +environment. As long as you don't save the environment you are +working with an in-memory copy. In case the Flash area containing the +environment is erased by accident, a default environment is provided. + +Some configuration options can be set using Environment Variables. + +List of environment variables (most likely not complete): + +baudrate + see CONFIG_BAUDRATE + +bootdelay + see CONFIG_BOOTDELAY + +bootcmd + see CONFIG_BOOTCOMMAND + +bootargs + Boot arguments when booting an RTOS image + +bootfile + Name of the image to load with TFTP + +bootm_low + Memory range available for image processing in the bootm + command can be restricted. This variable is given as + a hexadecimal number and defines lowest address allowed + for use by the bootm command. See also "bootm_size" + environment variable. Address defined by "bootm_low" is + also the base of the initial memory mapping for the Linux + kernel -- see the description of CONFIG_SYS_BOOTMAPSZ and + bootm_mapsize. + +bootm_mapsize + Size of the initial memory mapping for the Linux kernel. + This variable is given as a hexadecimal number and it + defines the size of the memory region starting at base + address bootm_low that is accessible by the Linux kernel + during early boot. If unset, CONFIG_SYS_BOOTMAPSZ is used + as the default value if it is defined, and bootm_size is + used otherwise. + +bootm_size + Memory range available for image processing in the bootm + command can be restricted. This variable is given as + a hexadecimal number and defines the size of the region + allowed for use by the bootm command. See also "bootm_low" + environment variable. + +bootstopkeysha256, bootdelaykey, bootstopkey + See README.autoboot + +updatefile + Location of the software update file on a TFTP server, used + by the automatic software update feature. Please refer to + documentation in doc/README.update for more details. + +autoload + if set to "no" (any string beginning with 'n'), + "bootp" will just load perform a lookup of the + configuration from the BOOTP server, but not try to + load any image using TFTP + +autostart + if set to "yes", an image loaded using the "bootp", + "rarpboot", "tftpboot" or "diskboot" commands will + be automatically started (by internally calling + "bootm") + + If set to "no", a standalone image passed to the + "bootm" command will be copied to the load address + (and eventually uncompressed), but NOT be started. + This can be used to load and uncompress arbitrary + data. + +fdt_high + if set this restricts the maximum address that the + flattened device tree will be copied into upon boot. + For example, if you have a system with 1 GB memory + at physical address 0x10000000, while Linux kernel + only recognizes the first 704 MB as low memory, you + may need to set fdt_high as 0x3C000000 to have the + device tree blob be copied to the maximum address + of the 704 MB low memory, so that Linux kernel can + access it during the boot procedure. + + If this is set to the special value 0xFFFFFFFF then + the fdt will not be copied at all on boot. For this + to work it must reside in writable memory, have + sufficient padding on the end of it for u-boot to + add the information it needs into it, and the memory + must be accessible by the kernel. + +fdtcontroladdr + if set this is the address of the control flattened + device tree used by U-Boot when CONFIG_OF_CONTROL is + defined. + +initrd_high + restrict positioning of initrd images: + If this variable is not set, initrd images will be + copied to the highest possible address in RAM; this + is usually what you want since it allows for + maximum initrd size. If for some reason you want to + make sure that the initrd image is loaded below the + CONFIG_SYS_BOOTMAPSZ limit, you can set this environment + variable to a value of "no" or "off" or "0". + Alternatively, you can set it to a maximum upper + address to use (U-Boot will still check that it + does not overwrite the U-Boot stack and data). + + For instance, when you have a system with 16 MB + RAM, and want to reserve 4 MB from use by Linux, + you can do this by adding "mem=12M" to the value of + the "bootargs" variable. However, now you must make + sure that the initrd image is placed in the first + 12 MB as well - this can be done with:: + + setenv initrd_high 00c00000 + + If you set initrd_high to 0xFFFFFFFF, this is an + indication to U-Boot that all addresses are legal + for the Linux kernel, including addresses in flash + memory. In this case U-Boot will NOT COPY the + ramdisk at all. This may be useful to reduce the + boot time on your system, but requires that this + feature is supported by your Linux kernel. + +ipaddr + IP address; needed for tftpboot command + +loadaddr + Default load address for commands like "bootp", + "rarpboot", "tftpboot", "loadb" or "diskboot" + +loads_echo + see CONFIG_LOADS_ECHO + +serverip + TFTP server IP address; needed for tftpboot command + +bootretry + see CONFIG_BOOT_RETRY_TIME + +bootdelaykey + see CONFIG_AUTOBOOT_DELAY_STR + +bootstopkey + see CONFIG_AUTOBOOT_STOP_STR + +ethprime + controls which interface is used first. + +ethact + controls which interface is currently active. + For example you can do the following:: + + => setenv ethact FEC + => ping 192.168.0.1 # traffic sent on FEC + => setenv ethact SCC + => ping 10.0.0.1 # traffic sent on SCC + +ethrotate + When set to "no" U-Boot does not go through all + available network interfaces. + It just stays at the currently selected interface. + +netretry + When set to "no" each network operation will + either succeed or fail without retrying. + When set to "once" the network operation will + fail when all the available network interfaces + are tried once without success. + Useful on scripts which control the retry operation + themselves. + +npe_ucode + set load address for the NPE microcode + +silent_linux + If set then Linux will be told to boot silently, by + changing the console to be empty. If "yes" it will be + made silent. If "no" it will not be made silent. If + unset, then it will be made silent if the U-Boot console + is silent. + +tftpsrcp + If this is set, the value is used for TFTP's + UDP source port. + +tftpdstp + If this is set, the value is used for TFTP's UDP + destination port instead of the Well Know Port 69. + +tftpblocksize + Block size to use for TFTP transfers; if not set, + we use the TFTP server's default block size + +tftptimeout + Retransmission timeout for TFTP packets (in milli- + seconds, minimum value is 1000 = 1 second). Defines + when a packet is considered to be lost so it has to + be retransmitted. The default is 5000 = 5 seconds. + Lowering this value may make downloads succeed + faster in networks with high packet loss rates or + with unreliable TFTP servers. + +tftptimeoutcountmax + maximum count of TFTP timeouts (no + unit, minimum value = 0). Defines how many timeouts + can happen during a single file transfer before that + transfer is aborted. The default is 10, and 0 means + 'no timeouts allowed'. Increasing this value may help + downloads succeed with high packet loss rates, or with + unreliable TFTP servers or client hardware. + +tftpwindowsize + if this is set, the value is used for TFTP's + window size as described by RFC 7440. + This means the count of blocks we can receive before + sending ack to server. + +vlan + When set to a value < 4095 the traffic over + Ethernet is encapsulated/received over 802.1q + VLAN tagged frames. + +bootpretryperiod + Period during which BOOTP/DHCP sends retries. + Unsigned value, in milliseconds. If not set, the period will + be either the default (28000), or a value based on + CONFIG_NET_RETRY_COUNT, if defined. This value has + precedence over the valu based on CONFIG_NET_RETRY_COUNT. + +memmatches + Number of matches found by the last 'ms' command, in hex + +memaddr + Address of the last match found by the 'ms' command, in hex, + or 0 if none + +mempos + Index position of the last match found by the 'ms' command, + in units of the size (.b, .w, .l) of the search + +zbootbase + (x86 only) Base address of the bzImage 'setup' block + +zbootaddr + (x86 only) Address of the loaded bzImage, typically + BZIMAGE_LOAD_ADDR which is 0x100000 + + +Image locations +--------------- + +The following image location variables contain the location of images +used in booting. The "Image" column gives the role of the image and is +not an environment variable name. The other columns are environment +variable names. "File Name" gives the name of the file on a TFTP +server, "RAM Address" gives the location in RAM the image will be +loaded to, and "Flash Location" gives the image's address in NOR +flash or offset in NAND flash. + +*Note* - these variables don't have to be defined for all boards, some +boards currently use other variables for these purposes, and some +boards use these variables for other purposes. + +================= ============== ================ ============== +Image File Name RAM Address Flash Location +================= ============== ================ ============== +u-boot u-boot u-boot_addr_r u-boot_addr +Linux kernel bootfile kernel_addr_r kernel_addr +device tree blob fdtfile fdt_addr_r fdt_addr +ramdisk ramdiskfile ramdisk_addr_r ramdisk_addr +================= ============== ================ ============== + + +Automatically updated variables +------------------------------- + +The following environment variables may be used and automatically +updated by the network boot commands ("bootp" and "rarpboot"), +depending the information provided by your boot server: + +========= =================================================== +Variable Notes +========= =================================================== +bootfile see above +dnsip IP address of your Domain Name Server +dnsip2 IP address of your secondary Domain Name Server +gatewayip IP address of the Gateway (Router) to use +hostname Target hostname +ipaddr See above +netmask Subnet Mask +rootpath Pathname of the root filesystem on the NFS server +serverip see above +========= =================================================== + + +Special environment variables +----------------------------- + +There are two special Environment Variables: + +serial# + contains hardware identification information such as type string and/or + serial number +ethaddr + Ethernet address + +These variables can be set only once (usually during manufacturing of +the board). U-Boot refuses to delete or overwrite these variables +once they have been set once. + +Also: + +ver + Contains the U-Boot version string as printed + with the "version" command. This variable is + readonly (see CONFIG_VERSION_VARIABLE). + +Please note that changes to some configuration parameters may take +only effect after the next boot (yes, that's just like Windoze :-). + + +Callback functions for environment variables +-------------------------------------------- + +For some environment variables, the behavior of u-boot needs to change +when their values are changed. This functionality allows functions to +be associated with arbitrary variables. On creation, overwrite, or +deletion, the callback will provide the opportunity for some side +effect to happen or for the change to be rejected. + +The callbacks are named and associated with a function using the +U_BOOT_ENV_CALLBACK macro in your board or driver code. + +These callbacks are associated with variables in one of two ways. The +static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC +in the board configuration to a string that defines a list of +associations. The list must be in the following format:: + + entry = variable_name[:callback_name] + list = entry[,list] + +If the callback name is not specified, then the callback is deleted. +Spaces are also allowed anywhere in the list. + +Callbacks can also be associated by defining the ".callbacks" variable +with the same list format above. Any association in ".callbacks" will +override any association in the static list. You can define +CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the +".callbacks" environment variable in the default or embedded environment. + +If CONFIG_REGEX is defined, the variable_name above is evaluated as a +regular expression. This allows multiple variables to be connected to +the same callback without explicitly listing them all out. + +The signature of the callback functions is:: + + int callback(const char *name, const char *value, enum env_op op, int flags) + +* name - changed environment variable +* value - new value of the environment variable +* op - operation (create, overwrite, or delete) +* flags - attributes of the environment variable change, see flags H_* in + include/search.h + +The return value is 0 if the variable change is accepted and 1 otherwise.

At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
In many cases environment variables need access to the U-Boot CONFIG variables to select different options. Enable this so that the environment scripts can be as useful as the ones currently in the board config files. This uses the C preprocessor, means that comments can be included in the environment using /* ... */
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz Tested-by: Marek Behún marek.behun@nic.cz ---
Changes in v10: - Use backslash to allow assignment to a variable ending in + - Add rST file into the index - Minor tweaks to the script's pattern matching
Changes in v9: - Drop mention of other strange characters - Clarify that the + restriction is on the variable name not its value - Add some tests for the script - Deal with leading tabs - Squash indentation down to one space - Convert newlines within strings to spaces, which seems more consistent - Handle appending an empty string to an empty var
Changes in v8: - Update commit message to avoid mentioning the 'env' subdirectory - Update commit message to mention the + restriction, etc. - Overwrite the env file each time, to avoid incremental-build problems
Changes in v7: - Use 'env' basename instead of 'environment' for intermediate output files - Show a message indicating the source text file being used - Give an error if CONFIG_EXTRA_ENV_SETTINGS is also defined - Use CONFIG_ENV_SOURCE_FILE instead of rules to specify the text-file name - Make board.env the default name if CONFIG_ENV_SOURCE_FILE is empty - Rewrite the documentation - Drop the use of common.env - Update awk script to output the whole CONFIG string, or just a comment
Changes in v6: - Combine the two env2string.awk patches into one
Changes in v5: - Explain how to include the common.env file - Explain why variables starting with _ , and / are not supported - Expand the definition of how to declare an environment variable - Explain what happens to empty variables - Update maintainer - Move use of += to this patch - Explain that environment variables may not end in +
Changes in v4: - Move this from being part of configuring U-Boot to part of building it - Don't put the environment in autoconf.mk as it is not needed - Add documentation in rST format instead of README - Drop mention of import/export - Update awk script to ignore blank lines, as generated by clang - Add documentation in rST format instead of README
Changes in v3: - Adjust Makefile to generate the .inc and .h files in separate fules - Add more detail in the README about the format of .env files - Improve the comment about " in the awk script - Correctly terminate environment files with \n - Define __UBOOT_CONFIG__ when collecting environment files
Changes in v2: - Move .env file from include/configs to board/ - Use awk script to process environment since it is much easier on the brain - Add information and updated example script to README - Add dependency rule so that the environment is rebuilt when it changes - Add separate patch to enable C preprocessor for environment files - Enable var+=value form to simplify composing variables in multiple steps
MAINTAINERS | 7 +++ Makefile | 66 ++++++++++++++++++++++- config.mk | 2 + doc/usage/environment.rst | 81 ++++++++++++++++++++++++++++- doc/usage/index.rst | 1 + env/Kconfig | 18 +++++++ env/embedded.c | 1 + include/env_default.h | 11 ++++ scripts/env2string.awk | 80 ++++++++++++++++++++++++++++ test/py/tests/test_env.py | 107 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 scripts/env2string.awk
diff --git a/MAINTAINERS b/MAINTAINERS index 8845c6fd750..8820a0f895e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -738,6 +738,13 @@ F: test/env/ F: tools/env* F: tools/mkenvimage.c
+ENVIRONMENT AS TEXT +M: Simon Glass sjg@chromium.org +R: Wolfgang Denk wd@denx.de +S: Maintained +F: doc/usage/environment.rst +F: scripts/env2string.awk + FPGA M: Michal Simek michal.simek@xilinx.com S: Maintained diff --git a/Makefile b/Makefile index 5194e4dc782..a80be71c78a 100644 --- a/Makefile +++ b/Makefile @@ -517,6 +517,7 @@ version_h := include/generated/version_autogenerated.h timestamp_h := include/generated/timestamp_autogenerated.h defaultenv_h := include/generated/defaultenv_autogenerated.h dt_h := include/generated/dt.h +env_h := include/generated/environment.h
no-dot-config-targets := clean clobber mrproper distclean \ help %docs check% coccicheck \ @@ -1786,6 +1787,69 @@ quiet_cmd_sym ?= SYM $@ u-boot.sym: u-boot FORCE $(call if_changed,sym)
+# Environment processing +# --------------------------------------------------------------------------- + +# Directory where we expect the .env file, if it exists +ENV_DIR := $(srctree)/board/$(BOARDDIR) + +# Basename of .env file, stripping quotes +ENV_SOURCE_FILE := $(CONFIG_ENV_SOURCE_FILE:"%"=%) + +# Filename of .env file +ENV_FILE_CFG := $(ENV_DIR)/$(ENV_SOURCE_FILE).env + +# Default filename, if CONFIG_ENV_SOURCE_FILE is empty +ENV_FILE_BOARD := $(ENV_DIR)/$(CONFIG_SYS_BOARD:"%"=%).env + +# Select between the CONFIG_ENV_SOURCE_FILE and the default one +ENV_FILE := $(if $(ENV_SOURCE_FILE),$(ENV_FILE_CFG),$(wildcard $(ENV_FILE_BOARD))) + +# Run the environment text file through the preprocessor, but only if it is +# non-empty, to save time and possible build errors if something is wonky with +# the board +quiet_cmd_gen_envp = ENVP $@ + cmd_gen_envp = \ + if [ -s "$(ENV_FILE)" ]; then \ + $(CPP) -P $(CFLAGS) -x assembler-with-cpp -D__ASSEMBLY__ \ + -D__UBOOT_CONFIG__ \ + -I . -I include -I $(srctree)/include \ + -include linux/kconfig.h -include include/config.h \ + -I$(srctree)/arch/$(ARCH)/include \ + $< -o $@; \ + else \ + echo -n >$@ ; \ + fi +include/generated/env.in: include/generated/env.txt FORCE + $(call cmd,gen_envp) + +# Regenerate the environment if it changes +# We use 'wildcard' since the file is not required to exist (at present), in +# which case we don't want this dependency, but instead should create an empty +# file +# This rule is useful since it shows the source file for the environment +quiet_cmd_envc = ENVC $@ + cmd_envc = \ + if [ -f "$<" ]; then \ + cat $< > $@; \ + elif [ -n "$(ENV_SOURCE_FILE)" ]; then \ + echo "Missing file $(ENV_FILE_CFG)"; \ + else \ + echo -n >$@ ; \ + fi + +include/generated/env.txt: $(wildcard $(ENV_FILE)) FORCE + $(call cmd,envc) + +# Write out the resulting environment, converted to a C string +quiet_cmd_gen_envt = ENVT $@ + cmd_gen_envt = \ + awk -f $(srctree)/scripts/env2string.awk $< >$@ +$(env_h): include/generated/env.in + $(call cmd,gen_envt) + +# --------------------------------------------------------------------------- + # The actual objects are generated when descending, # make sure no implicit rule kicks in $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ; @@ -1841,7 +1905,7 @@ endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile cfg
-prepare1: prepare2 $(version_h) $(timestamp_h) $(dt_h) \ +prepare1: prepare2 $(version_h) $(timestamp_h) $(dt_h) $(env_h) \ include/config/auto.conf ifeq ($(wildcard $(LDSCRIPT)),) @echo >&2 " Could not find linker script." diff --git a/config.mk b/config.mk index 7bb1fd4ed1b..2595aed218b 100644 --- a/config.mk +++ b/config.mk @@ -50,8 +50,10 @@ endif ifneq ($(BOARD),) ifdef VENDOR BOARDDIR = $(VENDOR)/$(BOARD) +ENVDIR=${vendor}/env else BOARDDIR = $(BOARD) +ENVDIR=${board}/env endif endif ifdef BOARD diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index 7a733b44556..043c02d9a94 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -15,7 +15,86 @@ environment is erased by accident, a default environment is provided.
Some configuration options can be set using Environment Variables.
-List of environment variables (most likely not complete): +Text-based Environment +---------------------- + +The default environment for a board is created using a `.env` environment file +using a simple text format. The base filename for this is defined by +`CONFIG_ENV_SOURCE_FILE`, or `CONFIG_SYS_BOARD` if that is empty. + +The file must be in the board directory and have a .env extension, so +assuming that there is a board vendor, the resulting filename is therefore:: + + board/<vendor>/<board>/<CONFIG_ENV_SOURCE_FILE>.env + +or:: + + board/<vendor>/<board>/<CONFIG_SYS_BOARD>.env + +This is a plain text file where you can type your environment variables in +the form `var=value`. Blank lines and multi-line variables are supported. +The conversion script looks for a line that starts in column 1 with a string +and has an equals sign immediately afterwards. Spaces before the = are not +permitted. It is a good idea to indent your scripts so that only the 'var=' +appears at the start of a line. + +To add additional text to a variable you can use `var+=value`. This text is +merged into the variable during the make process and made available as a +single value to U-Boot. Variables can contain `+` characters but in the unlikely +event that you want to have a variable name ending in plus, put a backslash +before the `+` so that the script knows you are not adding to an existing +variable but assigning to a new one:: + + maximum+=value + +This file can include C-style comments. Blank lines and multi-line +variables are supported, and you can use normal C preprocessor directives +and CONFIG defines from your board config also. + +For example, for snapper9260 you would create a text file called +`board/bluewater/snapper9260.env` containing the environment text. + +Example:: + + stdout=serial + #ifdef CONFIG_LCD + stdout+=,lcd + #endif + bootcmd= + /* U-Boot script for booting */ + + if [ -z ${tftpserverip} ]; then + echo "Use 'setenv tftpserverip a.b.c.d' to set IP address." + fi + + usb start; setenv autoload n; bootp; + tftpboot ${tftpserverip}: + bootm + failed= + /* Print a message when boot fails */ + echo CONFIG_SYS_BOARD boot failed - please check your image + echo Load address is CONFIG_SYS_LOAD_ADDR + +If CONFIG_ENV_SOURCE_FILE is empty and the default filename is not present, then +the old-style C environment is used instead. See below. + +Old-style C environment +----------------------- + +Traditionally, the default environment is created in `include/env_default.h`, +and can be augmented by various `CONFIG` defines. See that file for details. In +particular you can define `CONFIG_EXTRA_ENV_SETTINGS` in your board file +to add environment variables. + +Board maintainers are encouraged to migrate to the text-based environment as it +is easier to maintain. The distro-board script still requires the old-style +environment but work is underway to address this. + + +List of environment variables +----------------------------- + +This is most-likely not complete:
baudrate see CONFIG_BAUDRATE diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 356f2a56181..4314112ff34 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -10,6 +10,7 @@ Use U-Boot netconsole partitions cmdline + environment
Shell commands -------------- diff --git a/env/Kconfig b/env/Kconfig index f75f2b13536..b93ad5c8ee0 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -3,6 +3,24 @@ menu "Environment" config ENV_SUPPORT def_bool y
+config ENV_SOURCE_FILE + string "Environment file to use" + default "" + help + This sets the basename to use to generate the default environment. + This a text file as described in doc/usage/environment.rst + + The file must be in the board directory and have a .env extension, so + the resulting filename is typically + board/<vendor>/<board>/<CONFIG_ENV_SOURCE_FILE>.env + + If the file is not present, an error is produced. + + If this CONFIG is empty, U-Boot uses CONFIG SYS_BOARD as a default, if + the file board/<vendor>/<board>/<SYS_BOARD>.env exists. Otherwise the + environment is assumed to come from the ad-hoc + CONFIG_EXTRA_ENV_SETTINGS #define + config SAVEENV def_bool y if CMD_SAVEENV
diff --git a/env/embedded.c b/env/embedded.c index 208553e6af1..9f26e6cad9c 100644 --- a/env/embedded.c +++ b/env/embedded.c @@ -66,6 +66,7 @@ #endif
#define DEFAULT_ENV_INSTANCE_EMBEDDED +#include <config.h> #include <env_default.h>
#ifdef CONFIG_ENV_ADDR_REDUND diff --git a/include/env_default.h b/include/env_default.h index 66e203eb6e4..c06506313e5 100644 --- a/include/env_default.h +++ b/include/env_default.h @@ -10,6 +10,10 @@ #include <env_callback.h> #include <linux/stringify.h>
+#ifndef USE_HOSTCC +#include <generated/environment.h> +#endif + #ifdef DEFAULT_ENV_INSTANCE_EMBEDDED env_t embedded_environment __UBOOT_ENV_SECTION__(environment) = { ENV_CRC, /* CRC Sum */ @@ -110,6 +114,13 @@ const uchar default_environment[] = { #if defined(CONFIG_BOOTCOUNT_BOOTLIMIT) && (CONFIG_BOOTCOUNT_BOOTLIMIT > 0) "bootlimit=" __stringify(CONFIG_BOOTCOUNT_BOOTLIMIT)"\0" #endif +#ifdef CONFIG_EXTRA_ENV_TEXT +# ifdef CONFIG_EXTRA_ENV_SETTINGS +# error "Your board uses a text-file environment, so must not define CONFIG_EXTRA_ENV_SETTINGS" +# endif + /* This is created in the Makefile */ + CONFIG_EXTRA_ENV_TEXT +#endif #ifdef CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS #endif diff --git a/scripts/env2string.awk b/scripts/env2string.awk new file mode 100644 index 00000000000..57d0fc8f3ba --- /dev/null +++ b/scripts/env2string.awk @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2021 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Awk script to parse a text file containing an environment and convert it +# to a C string which can be compiled into U-Boot. + +# The resulting output is: +# +# #define CONFIG_EXTRA_ENV_TEXT "<environment here>" +# +# If the input is empty, this script outputs a comment instead. + +BEGIN { + # env holds the env variable we are currently processing + env = ""; + ORS = "" +} + +# Skip empty lines, as these are generated by the clang preprocessor +NF { + # Quote quotes + gsub(""", "\"") + + # Is this the start of a new environment variable? + if (match($0, "^([^ \t=][^ =]*)=(.*)$", arr)) { + if (length(env) != 0) { + # Record the value of the variable now completed + vars[var] = env + } + var = arr[1] + env = arr[2] + + # Deal with += which concatenates the new string to the existing + # variable + if (length(env) != 0 && match(var, "^(.*)[+]$", var_arr)) + { + # Allow var+=val to indicate that the variable name is + # var+ and this is not actually a concatenation + if (substr(var_arr[1], length(var_arr[1])) == "\") { + # Drop the backslash + sub(/\[+]$/, "+", var) + } else { + var = var_arr[1] + env = vars[var] env + } + } + } else { + # Change newline to space + gsub(/^[ \t]+/, "") + + # Don't keep leading spaces generated by the previous blank line + if (length(env) == 0) { + env = $0 + } else { + env = env " " $0 + } + } +} + +END { + # Record the value of the variable now completed. If the variable is + # empty it is not set. + if (length(env) != 0) { + vars[var] = env + } + + if (length(vars) != 0) { + printf("%s", "#define CONFIG_EXTRA_ENV_TEXT "") + + # Print out all the variables + for (var in vars) { + env = vars[var] + print var "=" vars[var] "\0" + } + print ""\n" + } +} diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py index 9bed2f48d77..f85cb031382 100644 --- a/test/py/tests/test_env.py +++ b/test/py/tests/test_env.py @@ -7,6 +7,7 @@ import os import os.path from subprocess import call, check_call, CalledProcessError +import tempfile
import pytest import u_boot_utils @@ -515,3 +516,109 @@ def test_env_ext4(state_test_env): finally: if fs_img: call('rm -f %s' % fs_img, shell=True) + +def test_env_text(u_boot_console): + """Test the script that converts the environment to a text file""" + + def check_script(intext, expect_val): + """Check a test case + + Args: + intext: Text to pass to the script + expect_val: Expected value of the CONFIG_EXTRA_ENV_TEXT string, or + None if we expect it not to be defined + """ + with tempfile.TemporaryDirectory() as path: + fname = os.path.join(path, 'infile') + with open(fname, 'w') as inf: + print(intext, file=inf) + result = u_boot_utils.run_and_log(cons, ['awk', '-f', script, fname]) + if expect_val is not None: + expect = '#define CONFIG_EXTRA_ENV_TEXT "%s"\n' % expect_val + assert result == expect + else: + assert result == '' + + cons = u_boot_console + script = os.path.join(cons.config.source_dir, 'scripts', 'env2string.awk') + + # simple script with a single var + check_script('fred=123', 'fred=123\0') + + # no vars + check_script('', None) + + # two vars + check_script('''fred=123 +ernie=456''', 'fred=123\0ernie=456\0') + + # blank lines + check_script('''fred=123 + + +ernie=456 + +''', 'fred=123\0ernie=456\0') + + # append + check_script('''fred=123 +ernie=456 +fred+= 456''', 'fred=123 456\0ernie=456\0') + + # append from empty + check_script('''fred= +ernie=456 +fred+= 456''', 'fred= 456\0ernie=456\0') + + # variable with + in it + check_script('fred+ernie=123', 'fred+ernie=123\0') + + # ignores variables that are empty + check_script('''fred= +fred+= +ernie=456''', 'ernie=456\0') + + # single-character env name + check_script('''f=123 +e=456 +f+= 456''', 'e=456\0f=123 456\0') + + # contains quotes + check_script('''fred="my var" +ernie=another"''', 'fred=\"my var\"\0ernie=another\"\0') + + # variable name ending in + + check_script('''fred\+=my var +fred++= again''', 'fred+=my var again\0') + + # variable name containing + + check_script('''fred+jane=both +fred+jane+=again +ernie=456''', 'fred+jane=bothagain\0ernie=456\0') + + # multi-line vars - new vars always start at column 1 + check_script('''fred=first + second +\tthird with tab + + after blank + confusing=oops +ernie=another"''', 'fred=first second third with tab after blank confusing=oops\0ernie=another\"\0') + + # real-world example + check_script('''ubifs_boot= + env exists bootubipart || + env set bootubipart UBI; + env exists bootubivol || + env set bootubivol boot; + if ubi part ${bootubipart} && + ubifsmount ubi${devnum}:${bootubivol}; + then + devtype=ubi; + run scan_dev_for_boot; + fi +''', + 'ubifs_boot=env exists bootubipart || env set bootubipart UBI; ' + 'env exists bootubivol || env set bootubivol boot; ' + 'if ubi part ${bootubipart} && ubifsmount ubi${devnum}:${bootubivol}; ' + 'then devtype=ubi; run scan_dev_for_boot; fi\0')

Dear Simon,
In message 20211021210847.v10.3.Ie78bfbfca0d01d9cba501e127f446ec48e1f7afe@changeid you wrote:
At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
The README does not contain this information as it has been moved into doc/usage/environment.rst
I think the documentation is lacking a hint that multiline definitions will always be separated by spaces.
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
I cannot see what the preprocessor has to do with this feature. It would be useful in any case, even without the preporcessor.
The documentation reads:
"Variables can contain `+` characters but in the unlikely event that you want to have a variable name ending in plus, put a backslash before the `+` so that the script knows you are not adding to an existing variable but assigning to a new one::
maximum+=value "
However, '' is also a legal character in a variable name (and doubled backslashes or apostrophes etc. are legal, too), so above line should actually set the environment variable "maximum+" to "value".
Best regards,
Wolfgang Denk

On Fri, Oct 22, 2021 at 10:29:26AM +0200, Wolfgang Denk wrote:
Dear Simon,
In message 20211021210847.v10.3.Ie78bfbfca0d01d9cba501e127f446ec48e1f7afe@changeid you wrote:
At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
The README does not contain this information as it has been moved into doc/usage/environment.rst
I think the documentation is lacking a hint that multiline definitions will always be separated by spaces.
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
I cannot see what the preprocessor has to do with this feature. It would be useful in any case, even without the preporcessor.
The documentation reads:
"Variables can contain `+` characters but in the unlikely event that you want to have a variable name ending in plus, put a backslash before the `+` so that the script knows you are not adding to an existing variable but assigning to a new one::
maximum\+=value
"
However, '' is also a legal character in a variable name (and doubled backslashes or apostrophes etc. are legal, too), so above line should actually set the environment variable "maximum+" to "value".
I feel I should preface this with "I am cranky". Now I see that I can indeed do: => setenv foo\bar baz => printenv foo\bar foo\bar=baz
on a system today. To what value, I know not. I can see how you write some fancy state machine set of scripts where you end up with "foo+bar+" needing to be set because you do a bunch of probing of things at run time and concatenate and ... there, we've got a variable that ends in + (and fwiw, sh says baz+ is a bad variable name, bash gets kinda funny with it). I don't see the value in allowing "" in a variable name, nor can I make bash nor sh handle that. We can just disallow "" in variable names.

Hi all,
My 2 cents.
As a maintainer for some hobbyist downstream u-boots (tracking mainline) and some out-of-tree u-boots, I do lots of envs scripting. The most common scenario for me is to create an env by combining 2 or more strings. Examples, init_usb, init_sata, init_sata_usb and so on, i.e concatenating "init" with the device name(s). The device names might be some other envs, and so on.
Note that I used _ (underscore) and could end up with an env name that has trailing underscore. So I can see the trailing + in env names might occur often in some existing scripts. It's just my preference to use underscore, but someone else might use a + sign!
OTOH, It never occurred to me that I can use a backward slash \ in env names. Since we use this escape character in ./include/configs/someboard.h CONFIG_EXTRA_ENV_SETTINGS as a linebreak, I think perhaps nobody would have attempted to make use of that in the env name.
So I agree with Tom, we could disallow \ in env name, and use it as a separator during parsing. Such as in the following 2 assignments, the 1st is appending the string bar to foo, the 2nd is assigning the string bar to foo+.
foo+=bar foo+=bar
Thanks, Tony

Dear Tom,
In message 20211022142912.GF3577824@bill-the-cat you wrote:
However, '' is also a legal character in a variable name (and doubled backslashes or apostrophes etc. are legal, too), so above line should actually set the environment variable "maximum+" to "value".
I feel I should preface this with "I am cranky". Now I see that I can indeed do: => setenv foo\bar baz => printenv foo\bar foo\bar=baz
on a system today. To what value, I know not.
That's simple: historical reasons.
I already explained that: when I wrote the environment code, memory was a very precious resource, so I implemented absolutely no checking that could be avoided. '=' was nevessary to separate name from value, and NUL was necessary to terminate an entry. All other characters where legal.
Yes, this can be misused to have all kinds of fun, like embedded terminal control sequences or "invisible" variable names:
=> setenv 'foo^H^H^H' bar => printenv =bar arch=sandbox baudrate=115200 ...
You don't like it? Don't do it, then.
Yes, robust programming is something different, but at that time we were fighting for 10 or 20 byte code size - there were so many systems where U-Boot, Linux, and root file system had to fit into 4 MB flash or so.
Best regards,
Wolfgang Denk

On Thu, Oct 21, 2021 at 09:08:46PM -0600, Simon Glass wrote:
At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
In many cases environment variables need access to the U-Boot CONFIG variables to select different options. Enable this so that the environment scripts can be as useful as the ones currently in the board config files. This uses the C preprocessor, means that comments can be included in the environment using /* ... */
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
I hope to see this change moving forward! It would be of great value for use in OpenWrt, as right now a per board default environment is often included using CONFIG_ENV_SOURCE_FILE and I was about to convert everything to C precompiler #defines to be more flexible... The suggested .env files made possible by this commit would provide an ideal solution.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz Tested-by: Marek Behún marek.behun@nic.cz
Changes in v10:
- Use backslash to allow assignment to a variable ending in +
- Add rST file into the index
- Minor tweaks to the script's pattern matching
Changes in v9:
- Drop mention of other strange characters
- Clarify that the + restriction is on the variable name not its value
- Add some tests for the script
- Deal with leading tabs
- Squash indentation down to one space
- Convert newlines within strings to spaces, which seems more consistent
- Handle appending an empty string to an empty var
Changes in v8:
- Update commit message to avoid mentioning the 'env' subdirectory
- Update commit message to mention the + restriction, etc.
- Overwrite the env file each time, to avoid incremental-build problems
Changes in v7:
- Use 'env' basename instead of 'environment' for intermediate output files
- Show a message indicating the source text file being used
- Give an error if CONFIG_EXTRA_ENV_SETTINGS is also defined
- Use CONFIG_ENV_SOURCE_FILE instead of rules to specify the text-file name
- Make board.env the default name if CONFIG_ENV_SOURCE_FILE is empty
- Rewrite the documentation
- Drop the use of common.env
- Update awk script to output the whole CONFIG string, or just a comment
Changes in v6:
- Combine the two env2string.awk patches into one
Changes in v5:
- Explain how to include the common.env file
- Explain why variables starting with _ , and / are not supported
- Expand the definition of how to declare an environment variable
- Explain what happens to empty variables
- Update maintainer
- Move use of += to this patch
- Explain that environment variables may not end in +
Changes in v4:
- Move this from being part of configuring U-Boot to part of building it
- Don't put the environment in autoconf.mk as it is not needed
- Add documentation in rST format instead of README
- Drop mention of import/export
- Update awk script to ignore blank lines, as generated by clang
- Add documentation in rST format instead of README
Changes in v3:
- Adjust Makefile to generate the .inc and .h files in separate fules
- Add more detail in the README about the format of .env files
- Improve the comment about " in the awk script
- Correctly terminate environment files with \n
- Define __UBOOT_CONFIG__ when collecting environment files
Changes in v2:
- Move .env file from include/configs to board/
- Use awk script to process environment since it is much easier on the brain
- Add information and updated example script to README
- Add dependency rule so that the environment is rebuilt when it changes
- Add separate patch to enable C preprocessor for environment files
- Enable var+=value form to simplify composing variables in multiple steps
MAINTAINERS | 7 +++ Makefile | 66 ++++++++++++++++++++++- config.mk | 2 + doc/usage/environment.rst | 81 ++++++++++++++++++++++++++++- doc/usage/index.rst | 1 + env/Kconfig | 18 +++++++ env/embedded.c | 1 + include/env_default.h | 11 ++++ scripts/env2string.awk | 80 ++++++++++++++++++++++++++++ test/py/tests/test_env.py | 107 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 scripts/env2string.awk
diff --git a/MAINTAINERS b/MAINTAINERS index 8845c6fd750..8820a0f895e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -738,6 +738,13 @@ F: test/env/ F: tools/env* F: tools/mkenvimage.c
+ENVIRONMENT AS TEXT +M: Simon Glass sjg@chromium.org +R: Wolfgang Denk wd@denx.de +S: Maintained +F: doc/usage/environment.rst +F: scripts/env2string.awk
FPGA M: Michal Simek michal.simek@xilinx.com S: Maintained diff --git a/Makefile b/Makefile index 5194e4dc782..a80be71c78a 100644 --- a/Makefile +++ b/Makefile @@ -517,6 +517,7 @@ version_h := include/generated/version_autogenerated.h timestamp_h := include/generated/timestamp_autogenerated.h defaultenv_h := include/generated/defaultenv_autogenerated.h dt_h := include/generated/dt.h +env_h := include/generated/environment.h
no-dot-config-targets := clean clobber mrproper distclean \ help %docs check% coccicheck \ @@ -1786,6 +1787,69 @@ quiet_cmd_sym ?= SYM $@ u-boot.sym: u-boot FORCE $(call if_changed,sym)
+# Environment processing +# ---------------------------------------------------------------------------
+# Directory where we expect the .env file, if it exists +ENV_DIR := $(srctree)/board/$(BOARDDIR)
+# Basename of .env file, stripping quotes +ENV_SOURCE_FILE := $(CONFIG_ENV_SOURCE_FILE:"%"=%)
+# Filename of .env file +ENV_FILE_CFG := $(ENV_DIR)/$(ENV_SOURCE_FILE).env
+# Default filename, if CONFIG_ENV_SOURCE_FILE is empty +ENV_FILE_BOARD := $(ENV_DIR)/$(CONFIG_SYS_BOARD:"%"=%).env
+# Select between the CONFIG_ENV_SOURCE_FILE and the default one +ENV_FILE := $(if $(ENV_SOURCE_FILE),$(ENV_FILE_CFG),$(wildcard $(ENV_FILE_BOARD)))
+# Run the environment text file through the preprocessor, but only if it is +# non-empty, to save time and possible build errors if something is wonky with +# the board +quiet_cmd_gen_envp = ENVP $@
cmd_gen_envp = \
- if [ -s "$(ENV_FILE)" ]; then \
$(CPP) -P $(CFLAGS) -x assembler-with-cpp -D__ASSEMBLY__ \
-D__UBOOT_CONFIG__ \
-I . -I include -I $(srctree)/include \
-include linux/kconfig.h -include include/config.h \
-I$(srctree)/arch/$(ARCH)/include \
$< -o $@; \
- else \
echo -n >$@ ; \
- fi
+include/generated/env.in: include/generated/env.txt FORCE
- $(call cmd,gen_envp)
+# Regenerate the environment if it changes +# We use 'wildcard' since the file is not required to exist (at present), in +# which case we don't want this dependency, but instead should create an empty +# file +# This rule is useful since it shows the source file for the environment +quiet_cmd_envc = ENVC $@
cmd_envc = \
- if [ -f "$<" ]; then \
cat $< > $@; \
- elif [ -n "$(ENV_SOURCE_FILE)" ]; then \
echo "Missing file $(ENV_FILE_CFG)"; \
- else \
echo -n >$@ ; \
- fi
+include/generated/env.txt: $(wildcard $(ENV_FILE)) FORCE
- $(call cmd,envc)
+# Write out the resulting environment, converted to a C string +quiet_cmd_gen_envt = ENVT $@
cmd_gen_envt = \
- awk -f $(srctree)/scripts/env2string.awk $< >$@
+$(env_h): include/generated/env.in
- $(call cmd,gen_envt)
+# ---------------------------------------------------------------------------
# The actual objects are generated when descending, # make sure no implicit rule kicks in $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ; @@ -1841,7 +1905,7 @@ endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile cfg
-prepare1: prepare2 $(version_h) $(timestamp_h) $(dt_h) \ +prepare1: prepare2 $(version_h) $(timestamp_h) $(dt_h) $(env_h) \ include/config/auto.conf ifeq ($(wildcard $(LDSCRIPT)),) @echo >&2 " Could not find linker script." diff --git a/config.mk b/config.mk index 7bb1fd4ed1b..2595aed218b 100644 --- a/config.mk +++ b/config.mk @@ -50,8 +50,10 @@ endif ifneq ($(BOARD),) ifdef VENDOR BOARDDIR = $(VENDOR)/$(BOARD) +ENVDIR=${vendor}/env else BOARDDIR = $(BOARD) +ENVDIR=${board}/env endif endif ifdef BOARD diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index 7a733b44556..043c02d9a94 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -15,7 +15,86 @@ environment is erased by accident, a default environment is provided.
Some configuration options can be set using Environment Variables.
-List of environment variables (most likely not complete): +Text-based Environment +----------------------
+The default environment for a board is created using a `.env` environment file +using a simple text format. The base filename for this is defined by +`CONFIG_ENV_SOURCE_FILE`, or `CONFIG_SYS_BOARD` if that is empty.
+The file must be in the board directory and have a .env extension, so +assuming that there is a board vendor, the resulting filename is therefore::
- board/<vendor>/<board>/<CONFIG_ENV_SOURCE_FILE>.env
+or::
- board/<vendor>/<board>/<CONFIG_SYS_BOARD>.env
+This is a plain text file where you can type your environment variables in +the form `var=value`. Blank lines and multi-line variables are supported. +The conversion script looks for a line that starts in column 1 with a string +and has an equals sign immediately afterwards. Spaces before the = are not +permitted. It is a good idea to indent your scripts so that only the 'var=' +appears at the start of a line.
+To add additional text to a variable you can use `var+=value`. This text is +merged into the variable during the make process and made available as a +single value to U-Boot. Variables can contain `+` characters but in the unlikely +event that you want to have a variable name ending in plus, put a backslash +before the `+` so that the script knows you are not adding to an existing +variable but assigning to a new one::
- maximum+=value
+This file can include C-style comments. Blank lines and multi-line +variables are supported, and you can use normal C preprocessor directives +and CONFIG defines from your board config also.
+For example, for snapper9260 you would create a text file called +`board/bluewater/snapper9260.env` containing the environment text.
+Example::
- stdout=serial
- #ifdef CONFIG_LCD
- stdout+=,lcd
- #endif
- bootcmd=
/* U-Boot script for booting */
if [ -z ${tftpserverip} ]; then
echo "Use 'setenv tftpserverip a.b.c.d' to set IP address."
fi
usb start; setenv autoload n; bootp;
tftpboot ${tftpserverip}:
bootm
- failed=
/* Print a message when boot fails */
echo CONFIG_SYS_BOARD boot failed - please check your image
echo Load address is CONFIG_SYS_LOAD_ADDR
+If CONFIG_ENV_SOURCE_FILE is empty and the default filename is not present, then +the old-style C environment is used instead. See below.
+Old-style C environment +-----------------------
+Traditionally, the default environment is created in `include/env_default.h`, +and can be augmented by various `CONFIG` defines. See that file for details. In +particular you can define `CONFIG_EXTRA_ENV_SETTINGS` in your board file +to add environment variables.
+Board maintainers are encouraged to migrate to the text-based environment as it +is easier to maintain. The distro-board script still requires the old-style +environment but work is underway to address this.
+List of environment variables +-----------------------------
+This is most-likely not complete:
baudrate see CONFIG_BAUDRATE diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 356f2a56181..4314112ff34 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -10,6 +10,7 @@ Use U-Boot netconsole partitions cmdline
- environment
Shell commands
diff --git a/env/Kconfig b/env/Kconfig index f75f2b13536..b93ad5c8ee0 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -3,6 +3,24 @@ menu "Environment" config ENV_SUPPORT def_bool y
+config ENV_SOURCE_FILE
- string "Environment file to use"
- default ""
- help
This sets the basename to use to generate the default environment.
This a text file as described in doc/usage/environment.rst
The file must be in the board directory and have a .env extension, so
the resulting filename is typically
board/<vendor>/<board>/<CONFIG_ENV_SOURCE_FILE>.env
If the file is not present, an error is produced.
If this CONFIG is empty, U-Boot uses CONFIG SYS_BOARD as a default, if
the file board/<vendor>/<board>/<SYS_BOARD>.env exists. Otherwise the
environment is assumed to come from the ad-hoc
CONFIG_EXTRA_ENV_SETTINGS #define
config SAVEENV def_bool y if CMD_SAVEENV
diff --git a/env/embedded.c b/env/embedded.c index 208553e6af1..9f26e6cad9c 100644 --- a/env/embedded.c +++ b/env/embedded.c @@ -66,6 +66,7 @@ #endif
#define DEFAULT_ENV_INSTANCE_EMBEDDED +#include <config.h> #include <env_default.h>
#ifdef CONFIG_ENV_ADDR_REDUND diff --git a/include/env_default.h b/include/env_default.h index 66e203eb6e4..c06506313e5 100644 --- a/include/env_default.h +++ b/include/env_default.h @@ -10,6 +10,10 @@ #include <env_callback.h> #include <linux/stringify.h>
+#ifndef USE_HOSTCC +#include <generated/environment.h> +#endif
#ifdef DEFAULT_ENV_INSTANCE_EMBEDDED env_t embedded_environment __UBOOT_ENV_SECTION__(environment) = { ENV_CRC, /* CRC Sum */ @@ -110,6 +114,13 @@ const uchar default_environment[] = { #if defined(CONFIG_BOOTCOUNT_BOOTLIMIT) && (CONFIG_BOOTCOUNT_BOOTLIMIT > 0) "bootlimit=" __stringify(CONFIG_BOOTCOUNT_BOOTLIMIT)"\0" #endif +#ifdef CONFIG_EXTRA_ENV_TEXT +# ifdef CONFIG_EXTRA_ENV_SETTINGS +# error "Your board uses a text-file environment, so must not define CONFIG_EXTRA_ENV_SETTINGS" +# endif
- /* This is created in the Makefile */
- CONFIG_EXTRA_ENV_TEXT
+#endif #ifdef CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS #endif diff --git a/scripts/env2string.awk b/scripts/env2string.awk new file mode 100644 index 00000000000..57d0fc8f3ba --- /dev/null +++ b/scripts/env2string.awk @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2021 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Awk script to parse a text file containing an environment and convert it +# to a C string which can be compiled into U-Boot.
+# The resulting output is: +# +# #define CONFIG_EXTRA_ENV_TEXT "<environment here>" +# +# If the input is empty, this script outputs a comment instead.
+BEGIN {
- # env holds the env variable we are currently processing
- env = "";
- ORS = ""
+}
+# Skip empty lines, as these are generated by the clang preprocessor +NF {
- # Quote quotes
- gsub(""", "\"")
- # Is this the start of a new environment variable?
- if (match($0, "^([^ \t=][^ =]*)=(.*)$", arr)) {
if (length(env) != 0) {
# Record the value of the variable now completed
vars[var] = env
}
var = arr[1]
env = arr[2]
# Deal with += which concatenates the new string to the existing
# variable
if (length(env) != 0 && match(var, "^(.*)[+]$", var_arr))
{
# Allow var\+=val to indicate that the variable name is
# var+ and this is not actually a concatenation
if (substr(var_arr[1], length(var_arr[1])) == "\\") {
# Drop the backslash
sub(/\\[+]$/, "+", var)
} else {
var = var_arr[1]
env = vars[var] env
}
}
- } else {
# Change newline to space
gsub(/^[ \t]+/, "")
# Don't keep leading spaces generated by the previous blank line
if (length(env) == 0) {
env = $0
} else {
env = env " " $0
}
- }
+}
+END {
- # Record the value of the variable now completed. If the variable is
- # empty it is not set.
- if (length(env) != 0) {
vars[var] = env
- }
- if (length(vars) != 0) {
printf("%s", "#define CONFIG_EXTRA_ENV_TEXT \"")
# Print out all the variables
for (var in vars) {
env = vars[var]
print var "=" vars[var] "\\0"
}
print "\"\n"
- }
+} diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py index 9bed2f48d77..f85cb031382 100644 --- a/test/py/tests/test_env.py +++ b/test/py/tests/test_env.py @@ -7,6 +7,7 @@ import os import os.path from subprocess import call, check_call, CalledProcessError +import tempfile
import pytest import u_boot_utils @@ -515,3 +516,109 @@ def test_env_ext4(state_test_env): finally: if fs_img: call('rm -f %s' % fs_img, shell=True)
+def test_env_text(u_boot_console):
- """Test the script that converts the environment to a text file"""
- def check_script(intext, expect_val):
"""Check a test case
Args:
intext: Text to pass to the script
expect_val: Expected value of the CONFIG_EXTRA_ENV_TEXT string, or
None if we expect it not to be defined
"""
with tempfile.TemporaryDirectory() as path:
fname = os.path.join(path, 'infile')
with open(fname, 'w') as inf:
print(intext, file=inf)
result = u_boot_utils.run_and_log(cons, ['awk', '-f', script, fname])
if expect_val is not None:
expect = '#define CONFIG_EXTRA_ENV_TEXT "%s"\n' % expect_val
assert result == expect
else:
assert result == ''
- cons = u_boot_console
- script = os.path.join(cons.config.source_dir, 'scripts', 'env2string.awk')
- # simple script with a single var
- check_script('fred=123', 'fred=123\0')
- # no vars
- check_script('', None)
- # two vars
- check_script('''fred=123
+ernie=456''', 'fred=123\0ernie=456\0')
- # blank lines
- check_script('''fred=123
+ernie=456
+''', 'fred=123\0ernie=456\0')
- # append
- check_script('''fred=123
+ernie=456 +fred+= 456''', 'fred=123 456\0ernie=456\0')
- # append from empty
- check_script('''fred=
+ernie=456 +fred+= 456''', 'fred= 456\0ernie=456\0')
- # variable with + in it
- check_script('fred+ernie=123', 'fred+ernie=123\0')
- # ignores variables that are empty
- check_script('''fred=
+fred+= +ernie=456''', 'ernie=456\0')
- # single-character env name
- check_script('''f=123
+e=456 +f+= 456''', 'e=456\0f=123 456\0')
- # contains quotes
- check_script('''fred="my var"
+ernie=another"''', 'fred=\"my var\"\0ernie=another\"\0')
- # variable name ending in +
- check_script('''fred\+=my var
+fred++= again''', 'fred+=my var again\0')
- # variable name containing +
- check_script('''fred+jane=both
+fred+jane+=again +ernie=456''', 'fred+jane=bothagain\0ernie=456\0')
- # multi-line vars - new vars always start at column 1
- check_script('''fred=first
- second
+\tthird with tab
- after blank
- confusing=oops
+ernie=another"''', 'fred=first second third with tab after blank confusing=oops\0ernie=another\"\0')
- # real-world example
- check_script('''ubifs_boot=
- env exists bootubipart ||
env set bootubipart UBI;
- env exists bootubivol ||
env set bootubivol boot;
- if ubi part ${bootubipart} &&
ubifsmount ubi${devnum}:${bootubivol};
- then
devtype=ubi;
run scan_dev_for_boot;
- fi
+''',
'ubifs_boot=env exists bootubipart || env set bootubipart UBI; '
'env exists bootubivol || env set bootubivol boot; '
'if ubi part ${bootubipart} && ubifsmount ubi${devnum}:${bootubivol}; '
'then devtype=ubi; run scan_dev_for_boot; fi\\0')
-- 2.33.0.1079.g6e70778dc9-goog

Hi Daniel,
On Fri, 12 Nov 2021 at 11:13, Daniel Golle daniel@makrotopia.org wrote:
On Thu, Oct 21, 2021 at 09:08:46PM -0600, Simon Glass wrote:
At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
In many cases environment variables need access to the U-Boot CONFIG variables to select different options. Enable this so that the environment scripts can be as useful as the ones currently in the board config files. This uses the C preprocessor, means that comments can be included in the environment using /* ... */
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
I hope to see this change moving forward! It would be of great value for use in OpenWrt, as right now a per board default environment is often included using CONFIG_ENV_SOURCE_FILE and I was about to convert everything to C precompiler #defines to be more flexible... The suggested .env files made possible by this commit would provide an ideal solution.
OK, well let 's see what happens. It is ready to apply, I think. I am sure some additional tweaks will be needed as we migrate things.
[..]
Regards, Simon

Hi Simon,
On 10/22/21 05:08, Simon Glass wrote:
At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
In many cases environment variables need access to the U-Boot CONFIG variables to select different options. Enable this so that the environment scripts can be as useful as the ones currently in the board config files. This uses the C preprocessor, means that comments can be included in the environment using /* ... */
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz Tested-by: Marek Behún marek.behun@nic.cz
...
MAINTAINERS | 7 +++ Makefile | 66 ++++++++++++++++++++++- config.mk | 2 + doc/usage/environment.rst | 81 ++++++++++++++++++++++++++++- doc/usage/index.rst | 1 + env/Kconfig | 18 +++++++ env/embedded.c | 1 + include/env_default.h | 11 ++++ scripts/env2string.awk | 80 ++++++++++++++++++++++++++++ test/py/tests/test_env.py | 107 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 scripts/env2string.awk
...
For information, it seems the new test "test_env_text" failed when the gawk is not installed on Ubuntu distribution,
or when /usr/bin/mawk is used as alternative (sudo update-alternatives --config awk)
The test result is
test/py/tests/test_env.py:556: in test_env_text check_script('''fred=123 test/py/tests/test_env.py:542: in check_script assert result == expect E assert '#define CONF...red=123\0"\n' == '#define CONF...nie=456\0"\n' E - #define CONFIG_EXTRA_ENV_TEXT "ernie=456\0fred=123\0" E ? ---------- E + #define CONFIG_EXTRA_ENV_TEXT "fred=123\0ernie=456\0" E ? ++++++++++ ------------------------------------------------------------ Captured stdout call ------------------------------------------------------------- +awk -f <PATH>/u-boot/scripts/env2string.awk /tmp/tmp0zgiwrd9/infile #define CONFIG_EXTRA_ENV_TEXT "fred=123\0" +awk -f <PATH>/u-boot/scripts/env2string.awk /tmp/tmpq6xej0ct/infile +awk -f <PATH>/u-boot/scripts/env2string.awk /tmp/tmpyrn10apn/infile #define CONFIG_EXTRA_ENV_TEXT "ernie=456\0fred=123\0"
=> the env variables are sorted in alphabetic order in mawk output / in creation order in gawk ouput
I don't found solution to be POSIX compliant and to guarantee the output order
By default, when a for loop traverses an array, the order is undefined,
meaning that the awk implementation determines the order in which
the array is traversed. This order is usually based on the internal
implementation of arrays and will vary from one version of awk to
the next.
References:
https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html
https://www.gnu.org/software/gawk/manual/html_node/Controlling-Array-Travers...
diff --git a/scripts/env2string.awk b/scripts/env2string.awk new file mode 100644 index 00000000000..57d0fc8f3ba --- /dev/null +++ b/scripts/env2string.awk @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2021 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Awk script to parse a text file containing an environment and convert it +# to a C string which can be compiled into U-Boot.
+# The resulting output is: +# +# #define CONFIG_EXTRA_ENV_TEXT "<environment here>" +# +# If the input is empty, this script outputs a comment instead.
+BEGIN {
- # env holds the env variable we are currently processing
- env = "";
- ORS = ""
+}
...
+END {
- # Record the value of the variable now completed. If the variable is
- # empty it is not set.
- if (length(env) != 0) {
vars[var] = env
- }
- if (length(vars) != 0) {
printf("%s", "#define CONFIG_EXTRA_ENV_TEXT \"")
# Print out all the variables
ORDER is not guarantee here by awk for the loop on the "vars" array
for (var in vars) {
env = vars[var]
print var "=" vars[var] "\\0"
}
print "\"\n"
- }
+} diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py index 9bed2f48d77..f85cb031382 100644 --- a/test/py/tests/test_env.py +++ b/test/py/tests/test_env.py @@ -7,6 +7,7 @@ import os import os.path from subprocess import call, check_call, CalledProcessError +import tempfile
import pytest import u_boot_utils @@ -515,3 +516,109 @@ def test_env_ext4(state_test_env): finally: if fs_img: call('rm -f %s' % fs_img, shell=True)
+def test_env_text(u_boot_console):
- """Test the script that converts the environment to a text file"""
- def check_script(intext, expect_val):
"""Check a test case
Args:
intext: Text to pass to the script
expect_val: Expected value of the CONFIG_EXTRA_ENV_TEXT string, or
None if we expect it not to be defined
"""
with tempfile.TemporaryDirectory() as path:
fname = os.path.join(path, 'infile')
with open(fname, 'w') as inf:
print(intext, file=inf)
result = u_boot_utils.run_and_log(cons, ['awk', '-f', script, fname])
if expect_val is not None:
expect = '#define CONFIG_EXTRA_ENV_TEXT "%s"\n' % expect_val
assert result == expect
else:
assert result == ''
- cons = u_boot_console
- script = os.path.join(cons.config.source_dir, 'scripts', 'env2string.awk')
- # simple script with a single var
- check_script('fred=123', 'fred=123\0')
- # no vars
- check_script('', None)
- # two vars
- check_script('''fred=123
+ernie=456''', 'fred=123\0ernie=456\0')
Here according the awk implementation the test result can be
'fred=123\0ernie=456\0' => creation order
'ernie=456\0fred=123\0' => alphabetic order
and perhaps other order for other awk ?
do you think you can have a solution with POSIX awk ? today I found only solution for gawk:
---------------------------- scripts/env2string.awk ---------------------------- index 1bfe9ed07a..f3215c369a 100644 @@ -81,7 +81,8 @@ END { if (do_output) { printf("%s", "#define CONFIG_EXTRA_ENV_TEXT "")
- # Print out all the variables + # Print out all the variables by alphabetic order + PROCINFO["sorted_in"] = "@ind_str_asc" for (var in vars) { env = vars[var] print var "=" vars[var] "\0"
But this GNU feature must be avoid, see commit 7acb32256831 ("env: Avoid using GNU features in awk")
Regard
Patrick Delaunay

Hi Patrick,
On Thu, 10 Feb 2022 at 04:20, Patrick DELAUNAY patrick.delaunay@foss.st.com wrote:
Hi Simon,
On 10/22/21 05:08, Simon Glass wrote:
At present U-Boot environment variables, and thus scripts, are defined by CONFIG_EXTRA_ENV_SETTINGS. It is painful to add large amounts of text to this file and dealing with quoting and newlines is harder than it should be. It would be better if we could just type the script into a text file and have it included by U-Boot.
Add a feature that brings in a .env file associated with the board config, if present. To use it, create a file in a board/<vendor> directory, typically called <board>.env and controlled by the CONFIG_ENV_SOURCE_FILE option.
The environment variables should be of the form "var=value". Values can extend to multiple lines. See the README under 'Environment Variables:' for more information and an example.
In many cases environment variables need access to the U-Boot CONFIG variables to select different options. Enable this so that the environment scripts can be as useful as the ones currently in the board config files. This uses the C preprocessor, means that comments can be included in the environment using /* ... */
Also support += to allow variables to be appended to. This is needed when using the preprocessor.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz Tested-by: Marek Behún marek.behun@nic.cz
...
MAINTAINERS | 7 +++ Makefile | 66 ++++++++++++++++++++++- config.mk | 2 + doc/usage/environment.rst | 81 ++++++++++++++++++++++++++++- doc/usage/index.rst | 1 + env/Kconfig | 18 +++++++ env/embedded.c | 1 + include/env_default.h | 11 ++++ scripts/env2string.awk | 80 ++++++++++++++++++++++++++++ test/py/tests/test_env.py | 107 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 scripts/env2string.awk
...
For information, it seems the new test "test_env_text" failed when the gawk is not installed on Ubuntu distribution,
or when /usr/bin/mawk is used as alternative (sudo update-alternatives --config awk)
The test result is
test/py/tests/test_env.py:556: in test_env_text check_script('''fred=123 test/py/tests/test_env.py:542: in check_script assert result == expect E assert '#define CONF...red=123\0"\n' == '#define CONF...nie=456\0"\n' E - #define CONFIG_EXTRA_ENV_TEXT "ernie=456\0fred=123\0" E ? ---------- E + #define CONFIG_EXTRA_ENV_TEXT "fred=123\0ernie=456\0" E ? ++++++++++ ------------------------------------------------------------ Captured stdout call ------------------------------------------------------------- +awk -f <PATH>/u-boot/scripts/env2string.awk /tmp/tmp0zgiwrd9/infile #define CONFIG_EXTRA_ENV_TEXT "fred=123\0" +awk -f <PATH>/u-boot/scripts/env2string.awk /tmp/tmpq6xej0ct/infile +awk -f <PATH>/u-boot/scripts/env2string.awk /tmp/tmpyrn10apn/infile #define CONFIG_EXTRA_ENV_TEXT "ernie=456\0fred=123\0"
=> the env variables are sorted in alphabetic order in mawk output / in creation order in gawk ouput
I don't found solution to be POSIX compliant and to guarantee the output order
By default, when a for loop traverses an array, the order is undefined,
meaning that the awk implementation determines the order in which
the array is traversed. This order is usually based on the internal
implementation of arrays and will vary from one version of awk to
the next.
References:
https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html
https://www.gnu.org/software/gawk/manual/html_node/Controlling-Array-Travers...
diff --git a/scripts/env2string.awk b/scripts/env2string.awk new file mode 100644 index 00000000000..57d0fc8f3ba --- /dev/null +++ b/scripts/env2string.awk @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2021 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Awk script to parse a text file containing an environment and convert it +# to a C string which can be compiled into U-Boot.
+# The resulting output is: +# +# #define CONFIG_EXTRA_ENV_TEXT "<environment here>" +# +# If the input is empty, this script outputs a comment instead.
+BEGIN {
# env holds the env variable we are currently processing
env = "";
ORS = ""
+}
...
+END {
# Record the value of the variable now completed. If the variable is
# empty it is not set.
if (length(env) != 0) {
vars[var] = env
}
if (length(vars) != 0) {
printf("%s", "#define CONFIG_EXTRA_ENV_TEXT \"")
# Print out all the variables
ORDER is not guarantee here by awk for the loop on the "vars" array
for (var in vars) {
env = vars[var]
print var "=" vars[var] "\\0"
}
print "\"\n"
}
+} diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py index 9bed2f48d77..f85cb031382 100644 --- a/test/py/tests/test_env.py +++ b/test/py/tests/test_env.py @@ -7,6 +7,7 @@ import os import os.path from subprocess import call, check_call, CalledProcessError +import tempfile
import pytest import u_boot_utils @@ -515,3 +516,109 @@ def test_env_ext4(state_test_env): finally: if fs_img: call('rm -f %s' % fs_img, shell=True)
+def test_env_text(u_boot_console):
- """Test the script that converts the environment to a text file"""
- def check_script(intext, expect_val):
"""Check a test case
Args:
intext: Text to pass to the script
expect_val: Expected value of the CONFIG_EXTRA_ENV_TEXT string, or
None if we expect it not to be defined
"""
with tempfile.TemporaryDirectory() as path:
fname = os.path.join(path, 'infile')
with open(fname, 'w') as inf:
print(intext, file=inf)
result = u_boot_utils.run_and_log(cons, ['awk', '-f', script, fname])
if expect_val is not None:
expect = '#define CONFIG_EXTRA_ENV_TEXT "%s"\n' % expect_val
assert result == expect
else:
assert result == ''
- cons = u_boot_console
- script = os.path.join(cons.config.source_dir, 'scripts', 'env2string.awk')
- # simple script with a single var
- check_script('fred=123', 'fred=123\0')
- # no vars
- check_script('', None)
- # two vars
- check_script('''fred=123
+ernie=456''', 'fred=123\0ernie=456\0')
Here according the awk implementation the test result can be
'fred=123\0ernie=456\0' => creation order
'ernie=456\0fred=123\0' => alphabetic order
and perhaps other order for other awk ?
do you think you can have a solution with POSIX awk ? today I found only solution for gawk:
---------------------------- scripts/env2string.awk ---------------------------- index 1bfe9ed07a..f3215c369a 100644 @@ -81,7 +81,8 @@ END { if (do_output) { printf("%s", "#define CONFIG_EXTRA_ENV_TEXT "")
# Print out all the variables
# Print out all the variables by alphabetic order
PROCINFO["sorted_in"] = "@ind_str_asc" for (var in vars) { env = vars[var] print var "=" vars[var] "\\0"
But this GNU feature must be avoid, see commit 7acb32256831 ("env: Avoid using GNU features in awk")
Thanks for this. I filed:
https://source.denx.de/u-boot/u-boot/-/issues/10
Regards, Simon

Use a text file for the environment instead of the #define settings.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz ---
(no changes since v3)
Changes in v3: - Add new patch to use a text-based environment for sandbox
board/sandbox/sandbox.env | 25 +++++++++++++++++++++++++ include/configs/sandbox.h | 29 ----------------------------- 2 files changed, 25 insertions(+), 29 deletions(-) create mode 100644 board/sandbox/sandbox.env
diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env new file mode 100644 index 00000000000..0f8d95b8db0 --- /dev/null +++ b/board/sandbox/sandbox.env @@ -0,0 +1,25 @@ +stdin=serial +#ifdef CONFIG_SANDBOX_SDL +stdin+=,cros-ec-keyb,usbkbd +#endif +stdout=serial,vidconsole +stderr=serial,vidconsole + +ethaddr=00:00:11:22:33:44 +eth2addr=00:00:11:22:33:48 +eth3addr=00:00:11:22:33:45 +eth4addr=00:00:11:22:33:48 +eth5addr=00:00:11:22:33:46 +eth6addr=00:00:11:22:33:47 +ipaddr=1.2.3.4 + +/* + * These are used for distro boot which is not supported. But once bootmethod + * is provided these will be used again. + */ +bootm_size=0x10000000 +kernel_addr_r=0x1000000 +fdt_addr_r=0xc00000 +ramdisk_addr_r=0x2000000 +scriptaddr=0x1000 +pxefile_addr_r=0x2000 diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index c19232f202f..c703a1330c0 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -64,37 +64,8 @@ #define CONFIG_LCD_BMP_RLE8
#define CONFIG_KEYBOARD - -#define SANDBOX_SERIAL_SETTINGS "stdin=serial,cros-ec-keyb,usbkbd\0" \ - "stdout=serial,vidconsole\0" \ - "stderr=serial,vidconsole\0" -#else -#define SANDBOX_SERIAL_SETTINGS "stdin=serial\0" \ - "stdout=serial,vidconsole\0" \ - "stderr=serial,vidconsole\0" #endif
-#define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \ - "eth2addr=00:00:11:22:33:48\0" \ - "eth3addr=00:00:11:22:33:45\0" \ - "eth4addr=00:00:11:22:33:48\0" \ - "eth5addr=00:00:11:22:33:46\0" \ - "eth6addr=00:00:11:22:33:47\0" \ - "ipaddr=1.2.3.4\0" - -#define MEM_LAYOUT_ENV_SETTINGS \ - "bootm_size=0x10000000\0" \ - "kernel_addr_r=0x1000000\0" \ - "fdt_addr_r=0xc00000\0" \ - "ramdisk_addr_r=0x2000000\0" \ - "scriptaddr=0x1000\0" \ - "pxefile_addr_r=0x2000\0" - -#define CONFIG_EXTRA_ENV_SETTINGS \ - SANDBOX_SERIAL_SETTINGS \ - SANDBOX_ETH_SETTINGS \ - MEM_LAYOUT_ENV_SETTINGS - #ifndef CONFIG_SPL_BUILD #define CONFIG_SYS_IDE_MAXBUS 1 #define CONFIG_SYS_ATA_IDE0_OFFSET 0

Add mention of this option since it does a similar thing to the text environment.
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Rasmus Villemoes rasmus.villemoes@prevas.dk Reviewed-by: Marek Behún marek.behun@nic.cz ---
(no changes since v9)
Changes in v9: - Fix blank line between tags - Fix typo in commit message
Changes in v8: - Fix ambiguity about what is ignored
Changes in v7: - Add new patch to explain the relationship with DEFAULT_ENV_FILE
doc/usage/environment.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index 043c02d9a94..6f3066e2b65 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -458,3 +458,18 @@ The signature of the callback functions is:: include/search.h
The return value is 0 if the variable change is accepted and 1 otherwise. + + +External environment file +------------------------- + +The `CONFIG_USE_DEFAULT_ENV_FILE` option provides a way to bypass the +environment generation in U-Boot. If enabled, then `CONFIG_DEFAULT_ENV_FILE` +provides the name of a file which is converted into the environment, +completely bypassing the standard environment variables in `env_default.h`. + +The format is the same as accepted by the mkenvimage tool, with lines containing +key=value pairs. Blank lines and lines beginning with # are ignored. + +Future work may unify this feature with the text-based environment, perhaps +moving the contents of `env_default.h` to a text file.

Make various updates suggested during review of the rST conversion.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Marek Behún marek.behun@nic.cz Suggested-by: Wolfgang Denk wd@denx.de ---
(no changes since v7)
Changes in v7: - A few more tweaks
Changes in v6: - Move all updates to a separate patch - More updates and improvements
Changes in v5: - Minor updates as suggested by Wolfgang
Changes in v4: - Add new patch to move environment documentation to rST
doc/usage/environment.rst | 36 +++++++++++++++++++++++++++--------- doc/usage/index.rst | 1 + 2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index 6f3066e2b65..af193739a5a 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -4,16 +4,20 @@ Environment Variables =====================
U-Boot supports user configuration using Environment Variables which -can be made persistent by saving to Flash memory. +can be made persistent by saving to persistent storage, for example flash +memory.
-Environment Variables are set using "setenv", printed using -"printenv", and saved to Flash using "saveenv". Using "setenv" +Environment Variables are set using "env set" (alias "setenv"), printed using +"env print" (alias "printenv"), and saved to persistent storage using +"env save" (alias "saveenv"). Using "env set" without a value can be used to delete a variable from the -environment. As long as you don't save the environment you are +environment. As long as you don't save the environment, you are working with an in-memory copy. In case the Flash area containing the environment is erased by accident, a default environment is provided.
-Some configuration options can be set using Environment Variables. +Some configuration is controlled by Environment Variables, so that setting the +variable can adjust the behaviour of U-Boot (e.g. autoboot delay, autoloading +from tftp).
Text-based Environment ---------------------- @@ -94,16 +98,24 @@ environment but work is underway to address this. List of environment variables -----------------------------
+Some configuration options can be set using Environment Variables. In many cases +the value in the default environment comes from a CONFIG option - see +`include/env_default.h`) for this. + This is most-likely not complete:
baudrate - see CONFIG_BAUDRATE + Current baud rate used by the serial console. The built-in value is set by + CONFIG_BAUDRATE (see `drivers/serial/Kconfig`)
bootdelay - see CONFIG_BOOTDELAY + Current autoboot delay. The built-in value is set by CONFIG_BOOTDELAY (see + `common/Kconfig`)
bootcmd - see CONFIG_BOOTCOMMAND + Defines a command string that is automatically executed when no character + is read on the console interface within a cetain boot delay after reset. + The built-in value is set by CONFIG_BOOTCOMMAND (see `common/Kconfig`)
bootargs Boot arguments when booting an RTOS image @@ -149,7 +161,7 @@ autoload if set to "no" (any string beginning with 'n'), "bootp" will just load perform a lookup of the configuration from the BOOTP server, but not try to - load any image using TFTP + load any image using TFTP or DHCP.
autostart if set to "yes", an image loaded using the "bootp", @@ -315,6 +327,8 @@ vlan Ethernet is encapsulated/received over 802.1q VLAN tagged frames.
+ Note: This appears not to be used in U-Boot. See `README.VLAN`. + bootpretryperiod Period during which BOOTP/DHCP sends retries. Unsigned value, in milliseconds. If not set, the period will @@ -356,6 +370,10 @@ flash or offset in NAND flash. boards currently use other variables for these purposes, and some boards use these variables for other purposes.
+Also note that most of these variables are just a commonly used set of variable +names, used in some other variable definitions, but are not hard-coded anywhere +in U-Boot code. + ================= ============== ================ ============== Image File Name RAM Address Flash Location ================= ============== ================ ============== diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 4314112ff34..04dea9f0f8e 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -5,6 +5,7 @@ Use U-Boot :maxdepth: 1
dfu + environment fdt_overlays fit netconsole

Make various other updates suggested during review of the rST conversion.
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Heinrich Schuchardt xypron.glpk@gmx.de ---
Changes in v10: - Add updates as suggested by Heinrich
doc/develop/environment.rst | 51 ++++++++++++++++ doc/develop/index.rst | 1 + doc/usage/environment.rst | 115 ++++++++++++++---------------------- 3 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 doc/develop/environment.rst
diff --git a/doc/develop/environment.rst b/doc/develop/environment.rst new file mode 100644 index 00000000000..0b86fafbff7 --- /dev/null +++ b/doc/develop/environment.rst @@ -0,0 +1,51 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Environment implementation +========================== + +See :doc:`../usage/environment` for usage information. + +Callback functions for environment variables +-------------------------------------------- + +For some environment variables, the behavior of u-boot needs to change +when their values are changed. This functionality allows functions to +be associated with arbitrary variables. On creation, overwrite, or +deletion, the callback will provide the opportunity for some side +effect to happen or for the change to be rejected. + +The callbacks are named and associated with a function using the +U_BOOT_ENV_CALLBACK macro in your board or driver code. + +These callbacks are associated with variables in one of two ways. The +static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC +in the board configuration to a string that defines a list of +associations. The list must be in the following format:: + + entry = variable_name[:callback_name] + list = entry[,list] + +If the callback name is not specified, then the callback is deleted. +Spaces are also allowed anywhere in the list. + +Callbacks can also be associated by defining the ".callbacks" variable +with the same list format above. Any association in ".callbacks" will +override any association in the static list. You can define +CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the +".callbacks" environment variable in the default or embedded environment. + +If CONFIG_REGEX is defined, the variable_name above is evaluated as a +regular expression. This allows multiple variables to be connected to +the same callback without explicitly listing them all out. + +The signature of the callback functions is:: + + int callback(const char *name, const char *value, enum env_op op, int flags) + +* name - changed environment variable +* value - new value of the environment variable +* op - operation (create, overwrite, or delete) +* flags - attributes of the environment variable change, see flags H_* in + include/search.h + +The return value is 0 if the variable change is accepted and 1 otherwise. diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 5e064a4dac1..9eee8190453 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -15,6 +15,7 @@ Implementation config_binding devicetree/index driver-model/index + environment global_data logging makefiles diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index af193739a5a..8ddc672d467 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -3,11 +3,11 @@ Environment Variables =====================
-U-Boot supports user configuration using Environment Variables which +U-Boot supports user configuration using environment variables which can be made persistent by saving to persistent storage, for example flash memory.
-Environment Variables are set using "env set" (alias "setenv"), printed using +Environment variables are set using "env set" (alias "setenv"), printed using "env print" (alias "printenv"), and saved to persistent storage using "env save" (alias "saveenv"). Using "env set" without a value can be used to delete a variable from the @@ -98,27 +98,37 @@ environment but work is underway to address this. List of environment variables -----------------------------
-Some configuration options can be set using Environment Variables. In many cases -the value in the default environment comes from a CONFIG option - see +Some device configuration options can be set using environment variables. In +many cases the value in the default environment comes from a CONFIG option - see `include/env_default.h`) for this.
This is most-likely not complete:
baudrate - Current baud rate used by the serial console. The built-in value is set by - CONFIG_BAUDRATE (see `drivers/serial/Kconfig`) + Used to set the baudrate of the UART - it defaults to CONFIG_BAUDRATE (which + defaults to 115200).
bootdelay - Current autoboot delay. The built-in value is set by CONFIG_BOOTDELAY (see - `common/Kconfig`) + Delay before automatically running bootcmd. During this time the user + can choose to enter the shell (or the boot menu if + CONFIG_AUTOBOOT_MENU_SHOW=y): + + - 0 to autoboot with no delay, but you can stop it by key input. + - -1 to disable autoboot. + - -2 to autoboot with no delay and not check for abort + + The default value is defined by CONFIG_BOOTDELAY. + The value of 'bootdelay' is overridden by the /config/bootdelay value in + the device-tree if CONFIG_OF_CONTROL=y. + Does it really make sense that the devicetree overrides the user setting?
bootcmd - Defines a command string that is automatically executed when no character - is read on the console interface within a cetain boot delay after reset. - The built-in value is set by CONFIG_BOOTCOMMAND (see `common/Kconfig`) + The command that is run if the user does not enter the shell during the + boot delay.
bootargs - Boot arguments when booting an RTOS image + Command line arguments passed when booting an operating system or binary + image
bootfile Name of the image to load with TFTP @@ -159,12 +169,12 @@ updatefile
autoload if set to "no" (any string beginning with 'n'), - "bootp" will just load perform a lookup of the + "bootp" and "dhcp" will just load perform a lookup of the configuration from the BOOTP server, but not try to load any image using TFTP or DHCP.
autostart - if set to "yes", an image loaded using the "bootp", + if set to "yes", an image loaded using the "bootp", "dhcp", "rarpboot", "tftpboot" or "diskboot" commands will be automatically started (by internally calling "bootm") @@ -186,7 +196,8 @@ fdt_high of the 704 MB low memory, so that Linux kernel can access it during the boot procedure.
- If this is set to the special value 0xFFFFFFFF then + If this is set to the special value 0xffffffff (32-bit machines) or + 0xffffffffffffffff (64-bit machines) then the fdt will not be copied at all on boot. For this to work it must reside in writable memory, have sufficient padding on the end of it for u-boot to @@ -220,7 +231,8 @@ initrd_high
setenv initrd_high 00c00000
- If you set initrd_high to 0xFFFFFFFF, this is an + If you set initrd_high to 0xffffffff (32-bit machines) or + 0xffffffffffffffff (64-bit machines), this is an indication to U-Boot that all addresses are legal for the Linux kernel, including addresses in flash memory. In this case U-Boot will NOT COPY the @@ -251,7 +263,7 @@ bootstopkey see CONFIG_AUTOBOOT_STOP_STR
ethprime - controls which interface is used first. + controls which network interface is used first.
ethact controls which interface is currently active. @@ -265,7 +277,9 @@ ethact ethrotate When set to "no" U-Boot does not go through all available network interfaces. - It just stays at the currently selected interface. + It just stays at the currently selected interface. When unset or set to + anything other than "no", U-Boot does go through all + available network interfaces.
netretry When set to "no" each network operation will @@ -276,12 +290,9 @@ netretry Useful on scripts which control the retry operation themselves.
-npe_ucode - set load address for the NPE microcode - silent_linux If set then Linux will be told to boot silently, by - changing the console to be empty. If "yes" it will be + adding 'console=' to its command line. If "yes" it will be made silent. If "no" it will not be made silent. If unset, then it will be made silent if the U-Boot console is silent. @@ -292,7 +303,7 @@ tftpsrcp
tftpdstp If this is set, the value is used for TFTP's UDP - destination port instead of the Well Know Port 69. + destination port instead of the default port 69.
tftpblocksize Block size to use for TFTP transfers; if not set, @@ -415,11 +426,12 @@ serial# contains hardware identification information such as type string and/or serial number ethaddr - Ethernet address + Ethernet address. If CONFIG_REGEX=y, also eth*addr (where * is an integer).
These variables can be set only once (usually during manufacturing of the board). U-Boot refuses to delete or overwrite these variables -once they have been set once. +once they have been set, unless CONFIG_ENV_OVERWRITE is enabled in the board +configuration.
Also:
@@ -429,53 +441,7 @@ ver readonly (see CONFIG_VERSION_VARIABLE).
Please note that changes to some configuration parameters may take -only effect after the next boot (yes, that's just like Windoze :-). - - -Callback functions for environment variables --------------------------------------------- - -For some environment variables, the behavior of u-boot needs to change -when their values are changed. This functionality allows functions to -be associated with arbitrary variables. On creation, overwrite, or -deletion, the callback will provide the opportunity for some side -effect to happen or for the change to be rejected. - -The callbacks are named and associated with a function using the -U_BOOT_ENV_CALLBACK macro in your board or driver code. - -These callbacks are associated with variables in one of two ways. The -static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC -in the board configuration to a string that defines a list of -associations. The list must be in the following format:: - - entry = variable_name[:callback_name] - list = entry[,list] - -If the callback name is not specified, then the callback is deleted. -Spaces are also allowed anywhere in the list. - -Callbacks can also be associated by defining the ".callbacks" variable -with the same list format above. Any association in ".callbacks" will -override any association in the static list. You can define -CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the -".callbacks" environment variable in the default or embedded environment. - -If CONFIG_REGEX is defined, the variable_name above is evaluated as a -regular expression. This allows multiple variables to be connected to -the same callback without explicitly listing them all out. - -The signature of the callback functions is:: - - int callback(const char *name, const char *value, enum env_op op, int flags) - -* name - changed environment variable -* value - new value of the environment variable -* op - operation (create, overwrite, or delete) -* flags - attributes of the environment variable change, see flags H_* in - include/search.h - -The return value is 0 if the variable change is accepted and 1 otherwise. +only effect after the next boot (yes, that's just like Windows).
External environment file @@ -491,3 +457,8 @@ key=value pairs. Blank lines and lines beginning with # are ignored.
Future work may unify this feature with the text-based environment, perhaps moving the contents of `env_default.h` to a text file. + +Implementation +-------------- + +See :doc:`../develop/environment` for internal development details.

On 10/22/21 05:08, Simon Glass wrote:
Make various other updates suggested during review of the rST conversion.
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Heinrich Schuchardt xypron.glpk@gmx.de
Changes in v10:
Add updates as suggested by Heinrich
doc/develop/environment.rst | 51 ++++++++++++++++ doc/develop/index.rst | 1 + doc/usage/environment.rst | 115 ++++++++++++++---------------------- 3 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 doc/develop/environment.rst
diff --git a/doc/develop/environment.rst b/doc/develop/environment.rst new file mode 100644 index 00000000000..0b86fafbff7 --- /dev/null +++ b/doc/develop/environment.rst @@ -0,0 +1,51 @@ +.. SPDX-License-Identifier: GPL-2.0+
+Environment implementation +==========================
+See :doc:`../usage/environment` for usage information.
+Callback functions for environment variables +--------------------------------------------
+For some environment variables, the behavior of u-boot needs to change +when their values are changed. This functionality allows functions to +be associated with arbitrary variables. On creation, overwrite, or +deletion, the callback will provide the opportunity for some side +effect to happen or for the change to be rejected.
+The callbacks are named and associated with a function using the +U_BOOT_ENV_CALLBACK macro in your board or driver code.
+These callbacks are associated with variables in one of two ways. The +static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC +in the board configuration to a string that defines a list of +associations. The list must be in the following format::
- entry = variable_name[:callback_name]
- list = entry[,list]
+If the callback name is not specified, then the callback is deleted. +Spaces are also allowed anywhere in the list.
+Callbacks can also be associated by defining the ".callbacks" variable +with the same list format above. Any association in ".callbacks" will +override any association in the static list. You can define +CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the +".callbacks" environment variable in the default or embedded environment.
+If CONFIG_REGEX is defined, the variable_name above is evaluated as a +regular expression. This allows multiple variables to be connected to +the same callback without explicitly listing them all out.
+The signature of the callback functions is::
- int callback(const char *name, const char *value, enum env_op op, int flags)
+* name - changed environment variable +* value - new value of the environment variable +* op - operation (create, overwrite, or delete) +* flags - attributes of the environment variable change, see flags H_* in
- include/search.h
+The return value is 0 if the variable change is accepted and 1 otherwise. diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 5e064a4dac1..9eee8190453 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -15,6 +15,7 @@ Implementation config_binding devicetree/index driver-model/index
- environment global_data logging makefiles
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index af193739a5a..8ddc672d467 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -3,11 +3,11 @@ Environment Variables =====================
-U-Boot supports user configuration using Environment Variables which +U-Boot supports user configuration using environment variables which can be made persistent by saving to persistent storage, for example flash memory.
-Environment Variables are set using "env set" (alias "setenv"), printed using +Environment variables are set using "env set" (alias "setenv"), printed using "env print" (alias "printenv"), and saved to persistent storage using "env save" (alias "saveenv"). Using "env set" without a value can be used to delete a variable from the @@ -98,27 +98,37 @@ environment but work is underway to address this. List of environment variables
-Some configuration options can be set using Environment Variables. In many cases -the value in the default environment comes from a CONFIG option - see +Some device configuration options can be set using environment variables. In +many cases the value in the default environment comes from a CONFIG option - see `include/env_default.h`) for this.
This is most-likely not complete:
baudrate
- Current baud rate used by the serial console. The built-in value is set by
- CONFIG_BAUDRATE (see `drivers/serial/Kconfig`)
Used to set the baudrate of the UART - it defaults to CONFIG_BAUDRATE (which
defaults to 115200).
bootdelay
- Current autoboot delay. The built-in value is set by CONFIG_BOOTDELAY (see
- `common/Kconfig`)
- Delay before automatically running bootcmd. During this time the user
- can choose to enter the shell (or the boot menu if
- CONFIG_AUTOBOOT_MENU_SHOW=y):
- 0 to autoboot with no delay, but you can stop it by key input.
- -1 to disable autoboot.
- -2 to autoboot with no delay and not check for abort
- The default value is defined by CONFIG_BOOTDELAY.
- The value of 'bootdelay' is overridden by the /config/bootdelay value in
- the device-tree if CONFIG_OF_CONTROL=y.
- Does it really make sense that the devicetree overrides the user setting?
This sentence was not meant for inclusion. It was just as comment on the code. Adding this to a man-page is irritating users. You could at it as a TODO in the code.
bootcmd
- Defines a command string that is automatically executed when no character
- is read on the console interface within a cetain boot delay after reset.
- The built-in value is set by CONFIG_BOOTCOMMAND (see `common/Kconfig`)
The command that is run if the user does not enter the shell during the
boot delay.
bootargs
- Boot arguments when booting an RTOS image
Command line arguments passed when booting an operating system or binary
image
bootfile Name of the image to load with TFTP
@@ -159,12 +169,12 @@ updatefile
autoload if set to "no" (any string beginning with 'n'),
- "bootp" will just load perform a lookup of the
- "bootp" and "dhcp" will just load perform a lookup of the configuration from the BOOTP server, but not try to load any image using TFTP or DHCP.
%s/using TFTP or DHCP//
DHCP is not a protocol to load images. A DHCP server may indicate a TFPT server.
autostart
- if set to "yes", an image loaded using the "bootp",
- if set to "yes", an image loaded using the "bootp", "dhcp", "rarpboot", "tftpboot" or "diskboot" commands will be automatically started (by internally calling "bootm")
@@ -186,7 +196,8 @@ fdt_high of the 704 MB low memory, so that Linux kernel can access it during the boot procedure.
- If this is set to the special value 0xFFFFFFFF then
- If this is set to the special value 0xffffffff (32-bit machines) or
- 0xffffffffffffffff (64-bit machines) then the fdt will not be copied at all on boot. For this to work it must reside in writable memory, have sufficient padding on the end of it for u-boot to
@@ -220,7 +231,8 @@ initrd_high
setenv initrd_high 00c00000
- If you set initrd_high to 0xFFFFFFFF, this is an
- If you set initrd_high to 0xffffffff (32-bit machines) or
- 0xffffffffffffffff (64-bit machines), this is an indication to U-Boot that all addresses are legal for the Linux kernel, including addresses in flash memory. In this case U-Boot will NOT COPY the
@@ -251,7 +263,7 @@ bootstopkey see CONFIG_AUTOBOOT_STOP_STR
ethprime
- controls which interface is used first.
controls which network interface is used first.
ethact controls which interface is currently active.
@@ -265,7 +277,9 @@ ethact ethrotate When set to "no" U-Boot does not go through all available network interfaces.
- It just stays at the currently selected interface.
It just stays at the currently selected interface. When unset or set to
anything other than "no", U-Boot does go through all
available network interfaces.
netretry When set to "no" each network operation will
@@ -276,12 +290,9 @@ netretry Useful on scripts which control the retry operation themselves.
-npe_ucode
- set load address for the NPE microcode
- silent_linux If set then Linux will be told to boot silently, by
- changing the console to be empty. If "yes" it will be
- adding 'console=' to its command line. If "yes" it will be made silent. If "no" it will not be made silent. If unset, then it will be made silent if the U-Boot console is silent.
@@ -292,7 +303,7 @@ tftpsrcp
tftpdstp If this is set, the value is used for TFTP's UDP
- destination port instead of the Well Know Port 69.
destination port instead of the default port 69.
tftpblocksize Block size to use for TFTP transfers; if not set,
@@ -415,11 +426,12 @@ serial# contains hardware identification information such as type string and/or serial number ethaddr
- Ethernet address
- Ethernet address. If CONFIG_REGEX=y, also eth*addr (where * is an integer).
ethaddr Ethernet address
This variable can be set only once. U-Boot refuses to delete or overwrite this variable once it has bee set unless CONFIG_ENV_OVERWRITE is enabled in the board configuration. The same applies to eth*addr (where * is an integer) if CONFIG_REGEX=y.
Best regards
Heinrich
These variables can be set only once (usually during manufacturing of the board). U-Boot refuses to delete or overwrite these variables -once they have been set once. +once they have been set, unless CONFIG_ENV_OVERWRITE is enabled in the board +configuration.
Also:
@@ -429,53 +441,7 @@ ver readonly (see CONFIG_VERSION_VARIABLE).
Please note that changes to some configuration parameters may take -only effect after the next boot (yes, that's just like Windoze :-).
-Callback functions for environment variables
-For some environment variables, the behavior of u-boot needs to change -when their values are changed. This functionality allows functions to -be associated with arbitrary variables. On creation, overwrite, or -deletion, the callback will provide the opportunity for some side -effect to happen or for the change to be rejected.
-The callbacks are named and associated with a function using the -U_BOOT_ENV_CALLBACK macro in your board or driver code.
-These callbacks are associated with variables in one of two ways. The -static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC -in the board configuration to a string that defines a list of -associations. The list must be in the following format::
- entry = variable_name[:callback_name]
- list = entry[,list]
-If the callback name is not specified, then the callback is deleted. -Spaces are also allowed anywhere in the list.
-Callbacks can also be associated by defining the ".callbacks" variable -with the same list format above. Any association in ".callbacks" will -override any association in the static list. You can define -CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the -".callbacks" environment variable in the default or embedded environment.
-If CONFIG_REGEX is defined, the variable_name above is evaluated as a -regular expression. This allows multiple variables to be connected to -the same callback without explicitly listing them all out.
-The signature of the callback functions is::
- int callback(const char *name, const char *value, enum env_op op, int flags)
-* name - changed environment variable -* value - new value of the environment variable -* op - operation (create, overwrite, or delete) -* flags - attributes of the environment variable change, see flags H_* in
- include/search.h
-The return value is 0 if the variable change is accepted and 1 otherwise. +only effect after the next boot (yes, that's just like Windows).
External environment file @@ -491,3 +457,8 @@ key=value pairs. Blank lines and lines beginning with # are ignored.
Future work may unify this feature with the text-based environment, perhaps moving the contents of `env_default.h` to a text file.
+Implementation +--------------
+See :doc:`../develop/environment` for internal development details.

Hi Heinrich,
On Sat, 23 Oct 2021 at 02:23, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 10/22/21 05:08, Simon Glass wrote:
Make various other updates suggested during review of the rST conversion.
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Heinrich Schuchardt xypron.glpk@gmx.de
Changes in v10:
Add updates as suggested by Heinrich
doc/develop/environment.rst | 51 ++++++++++++++++ doc/develop/index.rst | 1 + doc/usage/environment.rst | 115 ++++++++++++++---------------------- 3 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 doc/develop/environment.rst
diff --git a/doc/develop/environment.rst b/doc/develop/environment.rst new file mode 100644 index 00000000000..0b86fafbff7 --- /dev/null +++ b/doc/develop/environment.rst @@ -0,0 +1,51 @@ +.. SPDX-License-Identifier: GPL-2.0+
[..]
ethaddr Ethernet address
This variable can be set only once. U-Boot refuses to delete or overwrite this variable once it has bee set unless CONFIG_ENV_OVERWRITE is enabled in the board configuration. The same applies to eth*addr (where * is an integer) if CONFIG_REGEX=y.
I added the other two suggestions but I am not sure what you intend for this one. We have serial# and ethaddr which are both 'write once'.
[..]
Regards, Simon

These conflict with real-word addresses. Use locally administered MAC addresses and a suitable IPv4 address from 192.0.2.0/24 (TEST-NET-1).
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Alexander Dahl ada@thorsis.com ---
Changes in v10: - Add new patch to update the test MAC/IP addresses
board/sandbox/sandbox.env | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index 0f8d95b8db0..b4c04635a48 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -5,13 +5,13 @@ stdin+=,cros-ec-keyb,usbkbd stdout=serial,vidconsole stderr=serial,vidconsole
-ethaddr=00:00:11:22:33:44 -eth2addr=00:00:11:22:33:48 -eth3addr=00:00:11:22:33:45 -eth4addr=00:00:11:22:33:48 -eth5addr=00:00:11:22:33:46 -eth6addr=00:00:11:22:33:47 -ipaddr=1.2.3.4 +ethaddr=02:00:11:22:33:44 +eth2addr=02:00:11:22:33:48 +eth3addr=02:00:11:22:33:45 +eth4addr=02:00:11:22:33:48 +eth5addr=02:00:11:22:33:46 +eth6addr=02:00:11:22:33:47 +ipaddr=192.0.2.1
/* * These are used for distro boot which is not supported. But once bootmethod

On 10/22/21 05:08, Simon Glass wrote:
These conflict with real-word addresses. Use locally administered MAC addresses and a suitable IPv4 address from 192.0.2.0/24 (TEST-NET-1).
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Alexander Dahl ada@thorsis.com
Changes in v10:
Add new patch to update the test MAC/IP addresses
board/sandbox/sandbox.env | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index 0f8d95b8db0..b4c04635a48 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -5,13 +5,13 @@ stdin+=,cros-ec-keyb,usbkbd stdout=serial,vidconsole stderr=serial,vidconsole
-ethaddr=00:00:11:22:33:44 -eth2addr=00:00:11:22:33:48 -eth3addr=00:00:11:22:33:45 -eth4addr=00:00:11:22:33:48 -eth5addr=00:00:11:22:33:46 -eth6addr=00:00:11:22:33:47 -ipaddr=1.2.3.4 +ethaddr=02:00:11:22:33:44 +eth2addr=02:00:11:22:33:48 +eth3addr=02:00:11:22:33:45 +eth4addr=02:00:11:22:33:48
Ethernet addresses should be unique.
Should it be on purpose that two Ethernet address are the same, please add a comment in the code.
Best regards
Heinrich
+eth5addr=02:00:11:22:33:46 +eth6addr=02:00:11:22:33:47 +ipaddr=192.0.2.1
/*
- These are used for distro boot which is not supported. But once bootmethod

Hi Heinrich,
On Sat, 23 Oct 2021 at 02:30, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 10/22/21 05:08, Simon Glass wrote:
These conflict with real-word addresses. Use locally administered MAC addresses and a suitable IPv4 address from 192.0.2.0/24 (TEST-NET-1).
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Alexander Dahl ada@thorsis.com
Changes in v10:
Add new patch to update the test MAC/IP addresses
board/sandbox/sandbox.env | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index 0f8d95b8db0..b4c04635a48 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -5,13 +5,13 @@ stdin+=,cros-ec-keyb,usbkbd stdout=serial,vidconsole stderr=serial,vidconsole
-ethaddr=00:00:11:22:33:44 -eth2addr=00:00:11:22:33:48 -eth3addr=00:00:11:22:33:45 -eth4addr=00:00:11:22:33:48 -eth5addr=00:00:11:22:33:46 -eth6addr=00:00:11:22:33:47 -ipaddr=1.2.3.4 +ethaddr=02:00:11:22:33:44 +eth2addr=02:00:11:22:33:48 +eth3addr=02:00:11:22:33:45 +eth4addr=02:00:11:22:33:48
Ethernet addresses should be unique.
Should it be on purpose that two Ethernet address are the same, please add a comment in the code.
Can you please explain what you are getting out here? Which ones are not unique?
+eth5addr=02:00:11:22:33:46 +eth6addr=02:00:11:22:33:47 +ipaddr=192.0.2.1
/*
- These are used for distro boot which is not supported. But once bootmethod
Regards, Simon

On Sun, Oct 24, 2021 at 01:54:17PM -0600, Simon Glass wrote:
Hi Heinrich,
On Sat, 23 Oct 2021 at 02:30, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 10/22/21 05:08, Simon Glass wrote:
These conflict with real-word addresses. Use locally administered MAC addresses and a suitable IPv4 address from 192.0.2.0/24 (TEST-NET-1).
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Alexander Dahl ada@thorsis.com
Changes in v10:
Add new patch to update the test MAC/IP addresses
board/sandbox/sandbox.env | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index 0f8d95b8db0..b4c04635a48 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -5,13 +5,13 @@ stdin+=,cros-ec-keyb,usbkbd stdout=serial,vidconsole stderr=serial,vidconsole
-ethaddr=00:00:11:22:33:44 -eth2addr=00:00:11:22:33:48 -eth3addr=00:00:11:22:33:45 -eth4addr=00:00:11:22:33:48 -eth5addr=00:00:11:22:33:46 -eth6addr=00:00:11:22:33:47 -ipaddr=1.2.3.4 +ethaddr=02:00:11:22:33:44 +eth2addr=02:00:11:22:33:48 +eth3addr=02:00:11:22:33:45 +eth4addr=02:00:11:22:33:48
Ethernet addresses should be unique.
Should it be on purpose that two Ethernet address are the same, please add a comment in the code.
Can you please explain what you are getting out here? Which ones are not unique?
I think you made a mistake ages ago by not doing eth..eth6 in sequence and updating the last digit each time. Before and after eth2addr and eth4addr both end in 48.

This has different semantics in different places. Go with the bootm method and put it in a common function so that the behaviour is consistent in U-Boot. Update the docs.
To be clear, this changes the way that 'bootelf' and standalone boot work. Before, if autostart was set to "fred" or "YES", for example, they would consider that a "yes". This may change behaviour for some boards, but the only in-tree boards which mention autostart use "no" to disable it, which will still work.
Signed-off-by: Simon Glass sjg@chromium.org Suggested-by: Wolfgang Denk wd@denx.de ---
(no changes since v9)
Changes in v9: - More bikeshedding on env_get_autostart() - Fix '<vendor><board>' in cover letter - Use env_get_yesno() in env_get_autostart() and update docs
Changes in v8: - Go into more detail about the change of behaviour with autostart
Changes in v7: - Update the cover letter
Changes in v6: - Add new patch to tidy up use of autostart env var
cmd/bootm.c | 4 +--- cmd/elf.c | 3 +-- common/bootm_os.c | 5 +---- doc/usage/environment.rst | 5 +++-- env/common.c | 5 +++++ include/env.h | 7 +++++++ 6 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/cmd/bootm.c b/cmd/bootm.c index 92468d09a1f..b82a872a86c 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -140,9 +140,7 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
int bootm_maybe_autostart(struct cmd_tbl *cmdtp, const char *cmd) { - const char *ep = env_get("autostart"); - - if (ep && !strcmp(ep, "yes")) { + if (env_get_autostart()) { char *local_args[2]; local_args[0] = (char *)cmd; local_args[1] = NULL; diff --git a/cmd/elf.c b/cmd/elf.c index d75b21461c2..2b33c50bd02 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -41,7 +41,6 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ char *sload = NULL; - const char *ep = env_get("autostart"); int rcode = 0;
/* Consume 'bootelf' */ @@ -69,7 +68,7 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) else addr = load_elf_image_shdr(addr);
- if (ep && !strcmp(ep, "no")) + if (!env_get_autostart()) return rcode;
printf("## Starting application at 0x%08lx ...\n", addr); diff --git a/common/bootm_os.c b/common/bootm_os.c index 39623f9126b..f30dcebbf7d 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -26,12 +26,9 @@ DECLARE_GLOBAL_DATA_PTR; static int do_bootm_standalone(int flag, int argc, char *const argv[], bootm_headers_t *images) { - char *s; int (*appl)(int, char *const[]);
- /* Don't start if "autostart" is set to "no" */ - s = env_get("autostart"); - if ((s != NULL) && !strcmp(s, "no")) { + if (!env_get_autostart()) { env_set_hex("filesize", images->os.image_len); return 0; } diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst index 8ddc672d467..d295cc89878 100644 --- a/doc/usage/environment.rst +++ b/doc/usage/environment.rst @@ -179,8 +179,9 @@ autostart be automatically started (by internally calling "bootm")
- If set to "no", a standalone image passed to the - "bootm" command will be copied to the load address + If unset, or set to "1"/"yes"/"true" (case insensitive, just the first + character is enough), a standalone image + passed to the "bootm" command will be copied to the load address (and eventually uncompressed), but NOT be started. This can be used to load and uncompress arbitrary data. diff --git a/env/common.c b/env/common.c index 81e9e0b2aaf..e46a9ee644e 100644 --- a/env/common.c +++ b/env/common.c @@ -47,6 +47,11 @@ int env_get_yesno(const char *var) 1 : 0; }
+bool env_get_autostart(void) +{ + return env_get_yesno("autostart") == 1; +} + /* * Look up the variable from the default environment */ diff --git a/include/env.h b/include/env.h index d5e2bcb530f..fdad495691f 100644 --- a/include/env.h +++ b/include/env.h @@ -143,6 +143,13 @@ int env_get_f(const char *name, char *buf, unsigned int len); */ int env_get_yesno(const char *var);
+/** + * env_get_autostart() - Check if autostart is enabled + * + * @return true if the "autostart" env var exists and is set to "yes" + */ +bool env_get_autostart(void); + /** * env_set() - set an environment variable *
participants (7)
-
Daniel Golle
-
Heinrich Schuchardt
-
Patrick DELAUNAY
-
Simon Glass
-
Tom Rini
-
Tony Dinh
-
Wolfgang Denk