diff options
| author | Tom Rini <[email protected]> | 2023-12-13 11:51:53 -0500 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2023-12-13 11:51:53 -0500 |
| commit | 9565771076c2d4b0193f1741b3990695ac33c1f3 (patch) | |
| tree | 076f2a305250c83e4e3c5acf0e6492507d10babb /include | |
| parent | bfe3c7b93b9e722340e0e4950e886a46ba41244e (diff) | |
| parent | 8632b36b96d38a85f2e71603a6f90ec9e4e5e37e (diff) | |
Merge patch series "bootm: Refactoring to reduce reliance on CMDLINE (part A)"
To quote the author:
It would be useful to be able to boot an OS when CONFIG_CMDLINE is
disabled. This could allow reduced code size.
Standard boot provides a way to handle programmatic boot, without
scripts, so such a feature is possible. The main impediment is the
inability to use the booting features of U-Boot without a command line.
So the solution is to avoid passing command arguments and the like to
code in boot/
A similar process has taken place with filesystems, for example, where
we have (somewhat) separate Kconfig options for the filesystem commands
and the filesystems themselves.
This series starts the process of refactoring the bootm logic so that
it can be called from standard boot without using the command line.
Mostly it removes the use of argc, argv and cmdtbl from the internal
logic.
Some limited tidy-up is included, but this is kept to smaller patches,
rather than trying to remove all #ifdefs etc. Some function comments
are added, however.
A simple programmatic boot is provided as a starting point.
This work will likely take many series, so this is just the start.
Size growth with this series for firefly-rk3288 (Thumb2) is:
arm: (for 1/1 boards) all +23.0 rodata -49.0 text +72.0
This should be removed by:
https://source.denx.de/u-boot/custodians/u-boot-dm/-/issues/11
but it is not included in this series as it is already large enough.
No functional change is intended in this series.
Changes in v3:
- Add a panic if programmatic boot fails
- Drop RFC tag
Changes in v2:
- Add new patch to adjust position of unmap_sysmem() in boot_get_kernel()
- Add new patch to obtain command arguments
- Fix 'boot_find_os' typo
- Pass in the command name
- Use the command table to provide the command name, instead of "bootm"
Diffstat (limited to 'include')
| -rw-r--r-- | include/bootdev.h | 1 | ||||
| -rw-r--r-- | include/bootm.h | 26 | ||||
| -rw-r--r-- | include/bootstage.h | 1 | ||||
| -rw-r--r-- | include/bootstd.h | 9 | ||||
| -rw-r--r-- | include/command.h | 35 | ||||
| -rw-r--r-- | include/fdt_support.h | 5 | ||||
| -rw-r--r-- | include/image.h | 127 |
7 files changed, 170 insertions, 34 deletions
diff --git a/include/bootdev.h b/include/bootdev.h index 35fa25aff1d..2cee8832d26 100644 --- a/include/bootdev.h +++ b/include/bootdev.h @@ -7,6 +7,7 @@ #ifndef __bootdev_h #define __bootdev_h +#include <dm/uclass-id.h> #include <linux/list.h> struct bootflow; diff --git a/include/bootm.h b/include/bootm.h index 10a1bd65a75..f5229ea90b3 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -52,9 +52,29 @@ int boot_selected_os(int argc, char *const argv[], int state, ulong bootm_disable_interrupts(void); -/* This is a special function used by booti/bootz */ -int bootm_find_images(int flag, int argc, char *const argv[], ulong start, - ulong size); +/** + * bootm_find_images() - find and locate various images + * + * @img_addr: Address of image being loaded + * @conf_ramdisk: Indicates the ramdisk to use (typically second arg of bootm) + * @conf_fdt: Indicates the FDT to use (typically third arg of bootm) + * @start: OS image start address + * @size: OS image size + * + * boot_find_images() will attempt to load an available ramdisk, + * flattened device tree, as well as specifically marked + * "loadable" images (loadables are FIT only) + * + * Note: bootm_find_images will skip an image if it is not found + * + * This is a special function used by booti/bootz + * + * Return: + * 0, if all existing images were loaded correctly + * 1, if an image is found but corrupted, or invalid + */ +int bootm_find_images(ulong img_addr, const char *conf_ramdisk, + const char *conf_fdt, ulong start, ulong size); /* * Measure the boot images. Measurement is the process of hashing some binary diff --git a/include/bootstage.h b/include/bootstage.h index affb0e5c6a6..59a76d0f0c4 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -147,7 +147,6 @@ enum bootstage_id { BOOTSTAGE_ID_FIT_CONFIG = 110, BOOTSTAGE_ID_FIT_TYPE, - BOOTSTAGE_ID_FIT_KERNEL_INFO, BOOTSTAGE_ID_FIT_COMPRESSION, BOOTSTAGE_ID_FIT_OS, diff --git a/include/bootstd.h b/include/bootstd.h index 7802564bcc6..99ce7b64e7c 100644 --- a/include/bootstd.h +++ b/include/bootstd.h @@ -94,4 +94,13 @@ int bootstd_get_priv(struct bootstd_priv **stdp); */ void bootstd_clear_glob(void); +/** + * bootstd_prog_boot() - Run standard boot in a fully programmatic mode + * + * Attempts to boot without making any use of U-Boot commands + * + * Returns: -ve error value (does not return except on failure to boot) + */ +int bootstd_prog_boot(void); + #endif diff --git a/include/command.h b/include/command.h index 6262365e128..4cec6345453 100644 --- a/include/command.h +++ b/include/command.h @@ -60,6 +60,39 @@ struct cmd_tbl { #endif }; +/** + * cmd_arg_get() - Get a particular argument + * + * @argc: Number of arguments + * @argv: Argument vector of length @argc + * @argnum: Argument to get (0=first) + * Return: Pointer to argument @argnum if it exists, else NULL + */ +static inline const char *cmd_arg_get(int argc, char *const argv[], int argnum) +{ + return argc > argnum ? argv[argnum] : NULL; +} + +static inline const char *cmd_arg0(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 0); +} + +static inline const char *cmd_arg1(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 1); +} + +static inline const char *cmd_arg2(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 2); +} + +static inline const char *cmd_arg3(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 3); +} + #if defined(CONFIG_CMD_RUN) int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); @@ -390,7 +423,7 @@ int cmd_source_script(ulong addr, const char *fit_uname, const char *confname); #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \ ll_entry_declare(struct cmd_tbl, _name, cmd) = \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp); + _usage, _help, _comp) #define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \ _help, _comp) \ diff --git a/include/fdt_support.h b/include/fdt_support.h index 2cd83668982..feda0d99740 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -7,8 +7,7 @@ #ifndef __FDT_SUPPORT_H #define __FDT_SUPPORT_H -#if (defined(CONFIG_OF_LIBFDT) || defined(CONFIG_OF_CONTROL)) && \ - !defined(USE_HOSTCC) +#if !defined(USE_HOSTCC) #include <asm/u-boot.h> #include <linux/libfdt.h> @@ -418,7 +417,7 @@ int fdt_valid(struct fdt_header **blobp); */ int fdt_get_cells_len(const void *blob, char *nr_cells_name); -#endif /* ifdef CONFIG_OF_LIBFDT */ +#endif /* !USE_HOSTCC */ #ifdef USE_HOSTCC int fdtdec_get_int(const void *blob, int node, const char *prop_name, diff --git a/include/image.h b/include/image.h index 2e3cf839ee3..b89912a50f9 100644 --- a/include/image.h +++ b/include/image.h @@ -612,41 +612,86 @@ int boot_get_setup(struct bootm_headers *images, uint8_t arch, ulong *setup_star #define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ #define IMAGE_FORMAT_ANDROID 0x03 /* Android boot image */ -ulong genimg_get_kernel_addr_fit(char * const img_addr, - const char **fit_uname_config, - const char **fit_uname_kernel); +/** + * genimg_get_kernel_addr_fit() - Parse FIT specifier + * + * Get the real kernel start address from a string which is normally the first + * argv of bootm/bootz + * + * These cases are dealt with, based on the value of @img_addr: + * NULL: Returns image_load_addr, does not set last two args + * "<addr>": Returns address + * + * For FIT: + * "[<addr>]#<conf>": Returns address (or image_load_addr), + * sets fit_uname_config to config name + * "[<addr>]:<subimage>": Returns address (or image_load_addr) and sets + * fit_uname_kernel to the subimage name + * + * @img_addr: a string might contain real image address (or NULL) + * @fit_uname_config: Returns configuration unit name + * @fit_uname_kernel: Returns subimage name + * + * Returns: kernel start address + */ +ulong genimg_get_kernel_addr_fit(const char *const img_addr, + const char **fit_uname_config, + const char **fit_uname_kernel); + ulong genimg_get_kernel_addr(char * const img_addr); int genimg_get_format(const void *img_addr); int genimg_has_config(struct bootm_headers *images); -int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, - uint8_t arch, const ulong *ld_start, ulong * const ld_len); -int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, - uint8_t arch, ulong *rd_start, ulong *rd_end); +/** + * boot_get_fpga() - Locate the FPGA image + * + * @images: Information about images being loaded + * Return 0 if OK, non-zero on failure + */ +int boot_get_fpga(struct bootm_headers *images); + +/** + * boot_get_ramdisk() - Locate the ramdisk + * + * @select: address or name of ramdisk to use, or NULL for default + * @images: pointer to the bootm images structure + * @arch: expected ramdisk architecture + * @rd_start: pointer to a ulong variable, will hold ramdisk start address + * @rd_end: pointer to a ulong variable, will hold ramdisk end + * + * boot_get_ramdisk() is responsible for finding a valid ramdisk image. + * Currently supported are the following ramdisk sources: + * - multicomponent kernel/ramdisk image, + * - commandline provided address of decicated ramdisk image. + * + * returns: + * 0, if ramdisk image was found and valid, or skiped + * rd_start and rd_end are set to ramdisk start/end addresses if + * ramdisk image is found and valid + * + * 1, if ramdisk image is found but corrupted, or invalid + * rd_start and rd_end are set to 0 if no ramdisk exists + */ +int boot_get_ramdisk(char const *select, struct bootm_headers *images, + uint arch, ulong *rd_start, ulong *rd_end); /** - * boot_get_loadable - routine to load a list of binaries to memory - * @argc: Ignored Argument - * @argv: Ignored Argument + * boot_get_loadable() - load a list of binaries to memory + * * @images: pointer to the bootm images structure - * @arch: expected architecture for the image - * @ld_start: Ignored Argument - * @ld_len: Ignored Argument * - * boot_get_loadable() will take the given FIT configuration, and look - * for a field named "loadables". Loadables, is a list of elements in - * the FIT given as strings. exe: + * Takes the given FIT configuration, then looks for a field named + * "loadables", a list of elements in the FIT given as strings, e.g.: * loadables = "linux_kernel", "fdt-2"; - * this function will attempt to parse each string, and load the - * corresponding element from the FIT into memory. Once placed, - * no aditional actions are taken. * - * @return: + * Each string is parsed, loading the corresponding element from the FIT into + * memory. Once placed, no additional actions are taken. + * + * Return: * 0, if only valid images or no images are found * error code, if an error occurs during fit_image_load */ -int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, - uint8_t arch, const ulong *ld_start, ulong *const ld_len); +int boot_get_loadable(struct bootm_headers *images); int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len); @@ -705,7 +750,13 @@ int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, * @param load_op Decribes what to do with the load address * @param datap Returns address of loaded image * @param lenp Returns length of loaded image - * Return: node offset of image, or -ve error code on error + * Return: node offset of image, or -ve error code on error: + * -ENOEXEC - unsupported architecture + * -ENOENT - could not find image / subimage + * -EACCES - hash, signature or decryptions failure + * -EBADF - invalid OS or image type, or cannot get image load-address + * -EXDEV - memory overwritten / overlap + * -NOEXEC - image decompression error, or invalid FDT */ int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, @@ -756,9 +807,33 @@ int image_locate_script(void *buf, int size, const char *fit_uname, int fit_get_node_from_config(struct bootm_headers *images, const char *prop_name, ulong addr); -int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - struct bootm_headers *images, - char **of_flat_tree, ulong *of_size); +/** + * boot_get_fdt() - locate FDT devicetree to use for booting + * + * @buf: Pointer to image + * @select: FDT to select (this is normally argv[2] of the bootm command) + * @arch: architecture (IH_ARCH_...) + * @images: pointer to the bootm images structure + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_get_fdt() is responsible for finding a valid flat device tree image. + * Currently supported are the following FDT sources: + * - multicomponent kernel/ramdisk/FDT image, + * - commandline provided address of decicated FDT image. + * + * Return: + * 0, if fdt image was found and valid, or skipped + * of_flat_tree and of_size are set to fdt start address and length if + * fdt image is found and valid + * + * 1, if fdt image is found but corrupted + * of_flat_tree and of_size are set to 0 if no fdt exists + */ +int boot_get_fdt(void *buf, const char *select, uint arch, + struct bootm_headers *images, char **of_flat_tree, + ulong *of_size); + void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size); |
