diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 12 | ||||
-rw-r--r-- | common/blspec.c | 39 | ||||
-rw-r--r-- | common/bootm.c | 17 | ||||
-rw-r--r-- | common/env.c | 28 | ||||
-rw-r--r-- | common/environment.c | 3 | ||||
-rw-r--r-- | common/filetype.c | 5 | ||||
-rw-r--r-- | common/globalvar.c | 10 |
7 files changed, 74 insertions, 40 deletions
diff --git a/common/Kconfig b/common/Kconfig index 7c09e8c117..d00ca6b0fb 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -536,6 +536,18 @@ config BLSPEC on a device and it allows the Operating System to install / update kernels. +config FLEXIBLE_BOOTARGS + bool + prompt "flexible Linux bootargs generation" + depends on GLOBALVAR + help + Select this to get a more flexible bootargs generation. With this + option the bootargs are concatenated together from global variables + beginning with 'global.linux.bootargs.' and 'global.linux.mtdparts.' + This allows for more flexible scripting since with it it's possible + to replace parts of the bootargs string without reconstructing it + completely. + config IMD bool "barebox metadata support" diff --git a/common/blspec.c b/common/blspec.c index b92f49fa2b..bf98e6b29a 100644 --- a/common/blspec.c +++ b/common/blspec.c @@ -639,29 +639,6 @@ int blspec_scan_devicename(struct blspec *blspec, const char *devname) return blspec_scan_device(blspec, dev); } -static int blspec_append_root(struct blspec_entry *entry) -{ - const char *appendroot; - char *rootarg; - - appendroot = blspec_entry_var_get(entry, "linux-appendroot"); - if (!appendroot || strcmp(appendroot, "true")) - return 0; - - rootarg = path_get_linux_rootarg(entry->rootpath); - if (IS_ERR(rootarg)) { - pr_err("Getting root argument for %s failed with: %s\n", - entry->rootpath, strerrorp(rootarg)); - return PTR_ERR(rootarg); - } - - globalvar_add_simple("linux.bootargs.dyn.blspec.appendroot", rootarg); - - free(rootarg); - - return 0; -} - /* * blspec_boot - boot an entry * @@ -673,6 +650,7 @@ int blspec_boot(struct blspec_entry *entry, int verbose, int dryrun) { int ret; const char *abspath, *devicetree, *options, *initrd, *linuximage; + const char *appendroot; struct bootm_data data = { .initrd_address = UIMAGE_INVALID_ADDRESS, .os_address = UIMAGE_SOME_ADDRESS, @@ -711,9 +689,18 @@ int blspec_boot(struct blspec_entry *entry, int verbose, int dryrun) globalvar_add_simple("linux.bootargs.dyn.blspec", options); - ret = blspec_append_root(entry); - if (ret) - goto err_out; + appendroot = blspec_entry_var_get(entry, "linux-appendroot"); + if (appendroot) { + int val; + + ret = strtobool(appendroot, &val); + if (ret) { + pr_err("Invalid value \"%s\" for appendroot option\n", + appendroot); + goto err_out; + } + data.appendroot = val; + } pr_info("booting %s from %s\n", blspec_entry_var_get(entry, "title"), entry->cdev ? dev_name(entry->cdev->dev) : "none"); diff --git a/common/bootm.c b/common/bootm.c index 6d22aab289..cad8c73efe 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -48,6 +48,8 @@ static struct image_handler *bootm_find_handler(enum filetype filetype, return NULL; } +static int bootm_appendroot; + void bootm_data_init_defaults(struct bootm_data *data) { data->initrd_address = UIMAGE_INVALID_ADDRESS; @@ -58,6 +60,7 @@ void bootm_data_init_defaults(struct bootm_data *data) getenv_ul("global.bootm.initrd.loadaddr", &data->initrd_address); data->initrd_file = getenv_nonempty("global.bootm.initrd"); data->verify = bootm_get_verify_mode(); + data->appendroot = bootm_appendroot; } static enum bootm_verify bootm_verify_mode = BOOTM_VERIFY_HASH; @@ -576,6 +579,18 @@ int bootm_boot(struct bootm_data *bootm_data) } } + if (bootm_data->appendroot) { + char *rootarg; + + rootarg = path_get_linux_rootarg(data->os_file); + if (!IS_ERR(rootarg)) { + printf("Adding \"%s\" to Kernel commandline\n", rootarg); + globalvar_add_simple("linux.bootargs.bootm.appendroot", + rootarg); + free(rootarg); + } + } + printf("\nLoading %s '%s'", file_type_to_string(os_type), data->os_file); if (os_type == filetype_uimage && @@ -621,6 +636,7 @@ err_out: if (data->of_root_node && data->of_root_node != of_get_root_node()) of_delete_node(data->of_root_node); + globalvar_remove("linux.bootargs.bootm.appendroot"); free(data->os_file); free(data->oftree_file); free(data->initrd_file); @@ -634,6 +650,7 @@ static int bootm_init(void) globalvar_add_simple("bootm.image", NULL); globalvar_add_simple("bootm.image.loadaddr", NULL); globalvar_add_simple("bootm.oftree", NULL); + globalvar_add_simple_bool("bootm.appendroot", &bootm_appendroot); if (IS_ENABLED(CONFIG_CMD_BOOTM_INITRD)) { globalvar_add_simple("bootm.initrd", NULL); globalvar_add_simple("bootm.initrd.loadaddr", NULL); diff --git a/common/env.c b/common/env.c index 5f63e2dd27..6f736d5add 100644 --- a/common/env.c +++ b/common/env.c @@ -28,6 +28,7 @@ #include <xfuncs.h> #include <errno.h> #include <init.h> +#include <string.h> #include <environment.h> static struct env_context root = { @@ -323,20 +324,25 @@ int getenv_uint(const char *var , unsigned int *val) } EXPORT_SYMBOL(getenv_uint); +/** + * getenv_bool - get a boolean value from an environment variable + * @var - Variable name + * @val - The boolean value returned. + * + * This function treats + * - any positive (nonzero) number as true + * - "0" as false + * - "true" (case insensitive) as true + * - "false" (case insensitive) as false + * + * Returns 0 for success or negative error code if the variable does + * not exist or contains something this function does not recognize + * as true or false. + */ int getenv_bool(const char *var, int *val) { const char *valstr = getenv(var); - if (!valstr || !*valstr) - return -EINVAL; - - if (!*valstr) - *val = false; - else if (*valstr == '0') - *val = false; - else - *val = true; - - return 0; + return strtobool(valstr, val); } EXPORT_SYMBOL(getenv_bool); diff --git a/common/environment.c b/common/environment.c index fa6b59620e..c3ad25266a 100644 --- a/common/environment.c +++ b/common/environment.c @@ -89,6 +89,7 @@ static int do_compare_file(const char *filename, const char *base) } #else +#define ERASE_SIZE_ALL 0 static inline int protect(int fd, size_t count, unsigned long offset, int prot) { return 0; @@ -330,7 +331,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) goto out; } - ret = erase(envfd, ~0, 0); + ret = erase(envfd, ERASE_SIZE_ALL, 0); /* ENOSYS and EOPNOTSUPP aren't errors here, many devices don't need it */ if (ret && errno != ENOSYS && errno != EOPNOTSUPP) { diff --git a/common/filetype.c b/common/filetype.c index 74baf51446..a8666a1439 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -291,8 +291,6 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) if (bufsize < 64) return filetype_unknown; - if (buf8[0] == 'M' && buf8[1] == 'Z') - return filetype_exe; if (le32_to_cpu(buf[5]) == 0x504d5453) return filetype_mxs_bootstream; @@ -301,6 +299,9 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01) return filetype_arm_zimage; + if (buf8[0] == 'M' && buf8[1] == 'Z') + return filetype_exe; + if (bufsize < 512) return filetype_unknown; diff --git a/common/globalvar.c b/common/globalvar.c index bc1734d58d..5dad4f6a45 100644 --- a/common/globalvar.c +++ b/common/globalvar.c @@ -33,6 +33,16 @@ int globalvar_add(const char *name, return 0; } +void globalvar_remove(const char *name) +{ + struct param_d *param = get_param_by_name(&global_device, name); + + if (!param) + return; + + dev_remove_param(param); +} + static int nv_save(const char *name, const char *val) { int fd, ret; |