diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 1 | ||||
-rw-r--r-- | common/bbu.c | 4 | ||||
-rw-r--r-- | common/boot.c | 2 | ||||
-rw-r--r-- | common/bootargs.c | 6 | ||||
-rw-r--r-- | common/bootm.c | 53 | ||||
-rw-r--r-- | common/env.c | 2 | ||||
-rw-r--r-- | common/filetype.c | 10 | ||||
-rw-r--r-- | common/image-fit.c | 411 | ||||
-rw-r--r-- | common/imd.c | 27 | ||||
-rw-r--r-- | common/ratp.c | 26 | ||||
-rw-r--r-- | common/startup.c | 6 | ||||
-rw-r--r-- | common/state/state.c | 14 | ||||
-rw-r--r-- | common/state/state.h | 2 |
13 files changed, 372 insertions, 192 deletions
diff --git a/common/Kconfig b/common/Kconfig index 57418cadc6..93b1d89274 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -947,7 +947,6 @@ config STATE_BACKWARD_COMPATIBLE config BOOTCHOOSER bool "bootchooser infrastructure" - depends on !SHELL_NONE select BOOT select BOOTM select ENVIRONMENT_VARIABLES diff --git a/common/bbu.c b/common/bbu.c index 3b372263b1..11e44f4a7d 100644 --- a/common/bbu.c +++ b/common/bbu.c @@ -159,7 +159,7 @@ static int bbu_check_of_compat(struct bbu_data *data) struct device_node *root_node; const char *machine, *str; int ret; - struct imd_header *of_compat; + const struct imd_header *of_compat; if (!IS_ENABLED(CONFIG_OFDEVICE) || !IS_ENABLED(CONFIG_IMD)) return 0; @@ -191,7 +191,7 @@ static int bbu_check_of_compat(struct bbu_data *data) static int bbu_check_metadata(struct bbu_data *data) { - struct imd_header *imd; + const struct imd_header *imd; int ret; char *str; diff --git a/common/boot.c b/common/boot.c index cef3d5e514..41bf1ce64b 100644 --- a/common/boot.c +++ b/common/boot.c @@ -289,7 +289,7 @@ int bootentry_create_from_name(struct bootentries *bootentries, found += ret; } - if (!found) { + if (IS_ENABLED(CONFIG_COMMAND_SUPPORT) && !found) { char *path; if (*name != '/') diff --git a/common/bootargs.c b/common/bootargs.c index a89f23a3f2..f0ab689158 100644 --- a/common/bootargs.c +++ b/common/bootargs.c @@ -56,19 +56,21 @@ const char *linux_bootargs_get(void) bootargs = basprintf("%s mtdparts=%s", linux_bootargs, parts); free(linux_bootargs); - free(parts); linux_bootargs = bootargs; } + free(parts); + parts = globalvar_get_match("linux.blkdevparts.", ";"); if (strlen(parts)) { bootargs = basprintf("%s blkdevparts=%s", linux_bootargs, parts); free(linux_bootargs); - free(parts); linux_bootargs = bootargs; } + free(parts); + return linux_bootargs; } diff --git a/common/bootm.c b/common/bootm.c index 05314a0a10..3e48ca1d88 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -111,13 +111,14 @@ int bootm_load_os(struct image_data *data, unsigned long load_address) return -EINVAL; if (data->os_fit) { + const void *kernel = data->fit_kernel; + unsigned long kernel_size = data->fit_kernel_size; + data->os_res = request_sdram_region("kernel", - load_address, - data->os_fit->kernel_size); + load_address, kernel_size); if (!data->os_res) return -ENOMEM; - memcpy((void *)load_address, data->os_fit->kernel, - data->os_fit->kernel_size); + memcpy((void *)load_address, kernel, kernel_size); return 0; } @@ -150,7 +151,8 @@ bool bootm_has_initrd(struct image_data *data) if (!IS_ENABLED(CONFIG_BOOTM_INITRD)) return false; - if (data->os_fit && data->os_fit->initrd) + if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit && + fit_has_image(data->os_fit, data->fit_config, "ramdisk")) return true; if (data->initrd_file) @@ -211,14 +213,20 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address) if (data->initrd_res) return 0; - if (data->os_fit && data->os_fit->initrd) { + if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit && + fit_has_image(data->os_fit, data->fit_config, "ramdisk")) { + const void *initrd; + unsigned long initrd_size; + + ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk", + &initrd, &initrd_size); + data->initrd_res = request_sdram_region("initrd", load_address, - data->os_fit->initrd_size); + initrd_size); if (!data->initrd_res) return -ENOMEM; - memcpy((void *)load_address, data->os_fit->initrd, - data->os_fit->initrd_size); + memcpy((void *)load_address, initrd, initrd_size); printf("Loaded initrd from FIT image\n"); goto done1; } @@ -335,11 +343,17 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) if (!IS_ENABLED(CONFIG_OFTREE)) return 0; - if (data->os_fit && data->os_fit->oftree) { - data->of_root_node = of_unflatten_dtb(data->os_fit->oftree); + if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit && + fit_has_image(data->os_fit, data->fit_config, "fdt")) { + const void *of_tree; + unsigned long of_size; - if (IS_ERR(data->of_root_node)) - data->of_root_node = NULL; + ret = fit_open_image(data->os_fit, data->fit_config, "fdt", + &of_tree, &of_size); + if (ret) + return ret; + + data->of_root_node = of_unflatten_dtb(of_tree); } else if (data->oftree_file) { size_t size; @@ -429,7 +443,7 @@ int bootm_get_os_size(struct image_data *data) if (data->os) return uimage_get_size(data->os, uimage_part_num(data->os_part)); if (data->os_fit) - return data->os_fit->kernel_size; + return data->fit_kernel_size; if (data->os_file) { struct stat s; @@ -578,12 +592,19 @@ int bootm_boot(struct bootm_data *bootm_data) data->os_fit = fit; - ret = fit_open_configuration(data->os_fit, data->os_part); - if (ret) { + data->fit_config = fit_open_configuration(data->os_fit, + data->os_part); + if (IS_ERR(data->fit_config)) { printf("Cannot open FIT image configuration '%s'\n", data->os_part ? data->os_part : "default"); + ret = PTR_ERR(data->fit_config); goto err_out; } + + ret = fit_open_image(data->os_fit, data->fit_config, "kernel", + &data->fit_kernel, &data->fit_kernel_size); + if (ret) + goto err_out; } if (os_type == filetype_uimage) { diff --git a/common/env.c b/common/env.c index 80d3f7ab50..323a82223e 100644 --- a/common/env.c +++ b/common/env.c @@ -266,7 +266,7 @@ int setenv(const char *_name, const char *value) if (strchr(name, '.')) { ret = dev_setenv(name, value); if (ret) - eprintf("Cannot set parameter: %s\n", strerror(-ret)); + eprintf("Cannot set parameter %s: %s\n", name, strerror(-ret)); goto out; } diff --git a/common/filetype.c b/common/filetype.c index f9c034ff2a..71691fd813 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -21,6 +21,7 @@ #include <asm/unaligned.h> #include <fcntl.h> #include <fs.h> +#include <libfile.h> #include <malloc.h> #include <errno.h> #include <envfs.h> @@ -343,13 +344,13 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) return filetype_unknown; } -enum filetype file_name_detect_type(const char *filename) +enum filetype file_name_detect_type_offset(const char *filename, loff_t pos) { int fd, ret; void *buf; enum filetype type = filetype_unknown; - fd = open(filename, O_RDONLY); + fd = open_and_lseek(filename, O_RDONLY, pos); if (fd < 0) return fd; @@ -368,6 +369,11 @@ err_out: return type; } +enum filetype file_name_detect_type(const char *filename) +{ + return file_name_detect_type_offset(filename, 0); +} + enum filetype cdev_detect_type(const char *name) { enum filetype type = filetype_unknown; diff --git a/common/image-fit.c b/common/image-fit.c index 12379a67ff..3fab52db2e 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -74,11 +74,11 @@ static int of_read_string_list(struct device_node *np, const char *name, struct return prop ? 0 : -EINVAL; } -static int fit_digest(void *fit, struct digest *digest, +static int fit_digest(const void *fit, struct digest *digest, struct string_list *inc_nodes, struct string_list *exc_props, uint32_t hashed_strings_start, uint32_t hashed_strings_size) { - struct fdt_header *fdt = fit; + const struct fdt_header *fdt = fit; uint32_t dt_struct; void *dt_strings; struct fdt_header f = {}; @@ -230,28 +230,18 @@ static int fit_digest(void *fit, struct digest *digest, return 0; } -/* - * The consistency of the FTD structure was already checked by of_unflatten_dtb() - */ -static int fit_verify_signature(struct device_node *sig_node, void *fit) +static struct digest *fit_alloc_digest(struct device_node *sig_node, + enum hash_algo *algo_out) { - uint32_t hashed_strings_start, hashed_strings_size; - struct string_list inc_nodes, exc_props; - struct rsa_public_key key = {}; struct digest *digest; - int sig_len; - const char *algo_name, *key_name, *sig_value; - char *key_path; - struct device_node *key_node; enum hash_algo algo; - void *hash; - int ret; + const char *algo_name; if (of_property_read_string(sig_node, "algo", &algo_name)) { - pr_err("algo not found\n"); - ret = -EINVAL; - goto out; + pr_err("algo property not found\n"); + return ERR_PTR(-EINVAL); } + if (strcmp(algo_name, "sha1,rsa2048") == 0) { algo = HASH_ALGO_SHA1; } else if (strcmp(algo_name, "sha256,rsa2048") == 0) { @@ -260,53 +250,87 @@ static int fit_verify_signature(struct device_node *sig_node, void *fit) algo = HASH_ALGO_SHA256; } else { pr_err("unknown algo %s\n", algo_name); - ret = -EINVAL; - goto out; + return ERR_PTR(-EINVAL); } + digest = digest_alloc_by_algo(algo); if (!digest) { pr_err("unsupported algo %s\n", algo_name); - ret = -EINVAL; - goto out; + return ERR_PTR(-EINVAL); } + digest_init(digest); + + *algo_out = algo; + + return digest; +} + +static int fit_check_rsa_signature(struct device_node *sig_node, + enum hash_algo algo, void *hash) +{ + struct rsa_public_key key = {}; + const char *key_name; + char *key_path; + struct device_node *key_node; + int sig_len; + const char *sig_value; + int ret; + sig_value = of_get_property(sig_node, "value", &sig_len); if (!sig_value) { pr_err("signature value not found in %s\n", sig_node->full_name); - ret = -EINVAL; - goto out_free_digest; + return -EINVAL; } if (of_property_read_string(sig_node, "key-name-hint", &key_name)) { pr_err("key name not found in %s\n", sig_node->full_name); - ret = -EINVAL; - goto out_free_digest; + return -EINVAL; } key_path = xasprintf("/signature/key-%s", key_name); key_node = of_find_node_by_path(key_path); free(key_path); if (!key_node) { pr_info("failed to find key node\n"); - ret = -ENOENT; - goto out_free_digest; + return -ENOENT; } ret = rsa_of_read_key(key_node, &key); if (ret) { pr_info("failed to read key in %s\n", key_node->full_name); - ret = -ENOENT; - goto out_free_digest; + return -ENOENT; } - if (of_property_read_u32_index(sig_node, "hashed-strings", 0, &hashed_strings_start)) { + ret = rsa_verify(&key, sig_value, sig_len, hash, algo); + if (ret) + pr_err("image signature BAD\n"); + else + pr_info("image signature OK\n"); + + return ret; +} + +/* + * The consistency of the FTD structure was already checked by of_unflatten_dtb() + */ +static int fit_verify_signature(struct device_node *sig_node, const void *fit) +{ + uint32_t hashed_strings_start, hashed_strings_size; + struct string_list inc_nodes, exc_props; + struct digest *digest; + void *hash; + enum hash_algo algo = 0; + int ret; + + if (of_property_read_u32_index(sig_node, "hashed-strings", 0, + &hashed_strings_start)) { pr_err("hashed-strings start not found in %s\n", sig_node->full_name); - ret = -EINVAL; - goto out_free_digest; + return -EINVAL; } - if (of_property_read_u32_index(sig_node, "hashed-strings", 1, &hashed_strings_size)) { + if (of_property_read_u32_index(sig_node, "hashed-strings", 1, + &hashed_strings_size)) { pr_err("hashed-strings size not found in %s\n", sig_node->full_name); - ret = -EINVAL; - goto out_free_digest; + return -EINVAL; } string_list_init(&inc_nodes); @@ -320,37 +344,60 @@ static int fit_verify_signature(struct device_node *sig_node, void *fit) string_list_add(&exc_props, "data"); - digest_init(digest); - ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start, hashed_strings_size); + digest = fit_alloc_digest(sig_node, &algo); + if (IS_ERR(digest)) { + ret = PTR_ERR(digest); + goto out_sl; + } + + ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start, + hashed_strings_size); hash = xzalloc(digest_length(digest)); digest_final(digest, hash); - ret = rsa_verify(&key, sig_value, sig_len, hash, algo); - if (ret) { - pr_info("image signature BAD\n"); - ret = -EBADMSG; - } else { - pr_info("image signature OK\n"); - ret = 0; - } + ret = fit_check_rsa_signature(sig_node, algo, hash); + if (ret) + goto out_free_hash; + ret = 0; + + out_free_hash: free(hash); + digest_free(digest); out_sl: string_list_free(&inc_nodes); string_list_free(&exc_props); - out_free_digest: - digest_free(digest); - out: + return ret; } -static int fit_verify_hash(struct device_node *hash, const void *data, int data_len) +static int fit_verify_hash(struct fit_handle *handle, struct device_node *image, + const void *data, int data_len) { struct digest *d; const char *algo; const char *value_read; char *value_calc; int hash_len, ret; + struct device_node *hash; + + switch (handle->verify) { + case BOOTM_VERIFY_NONE: + return 0; + case BOOTM_VERIFY_AVAILABLE: + ret = 0; + break; + default: + ret = -EINVAL; + } + + hash = of_get_child_by_name(image, "hash@1"); + if (!hash) { + if (ret) + pr_err("image %s does not have hashes\n", + image->full_name); + return ret; + } value_read = of_get_property(hash, "value", &hash_len); if (!value_read) { @@ -397,10 +444,57 @@ err_digest_free: return ret; } -int fit_has_image(struct fit_handle *handle, const char *name) +static int fit_image_verify_signature(struct fit_handle *handle, + struct device_node *image, + const void *data, int data_len) +{ + struct digest *digest; + struct device_node *sig_node; + enum hash_algo algo = 0; + void *hash; + int ret; + + if (!IS_ENABLED(CONFIG_FITIMAGE_SIGNATURE)) + return 0; + + switch (handle->verify) { + case BOOTM_VERIFY_NONE: + return 0; + case BOOTM_VERIFY_AVAILABLE: + ret = 0; + break; + default: + ret = -EINVAL; + } + + sig_node = of_get_child_by_name(image, "signature@1"); + if (!sig_node) { + pr_err("Image %s has no signature\n", image->full_name); + return ret; + } + + digest = fit_alloc_digest(sig_node, &algo); + if (IS_ERR(digest)) + return PTR_ERR(digest); + + digest_update(digest, data, data_len); + hash = xzalloc(digest_length(digest)); + digest_final(digest, hash); + + ret = fit_check_rsa_signature(sig_node, algo, hash); + + free(hash); + + digest_free(digest); + + return ret; +} + +int fit_has_image(struct fit_handle *handle, void *configuration, + const char *name) { const char *unit; - struct device_node *conf_node = handle->conf_node; + struct device_node *conf_node = configuration; if (!conf_node) return -EINVAL; @@ -411,29 +505,44 @@ int fit_has_image(struct fit_handle *handle, const char *name) return 1; } -int fit_open_image(struct fit_handle *handle, const char *name, - const void **outdata, unsigned long *outsize) +/** + * fit_open_image - Open an image in a FIT image + * @handle: The FIT image handle + * @name: The name of the image to open + * @outdata: The returned image + * @outsize: Size of the returned image + * + * Open an image in a FIT image. The returned image is freed during fit_close(). + * @configuration holds the cookie returned from fit_open_configuration() if + * the image is opened as part of a configuration, or NULL if the image is + * opened without a configuration. If @configuration is NULL then the RSA + * signature of the image is checked if desired, if @configuration is non NULL, + * then only the hash is checked (because opening the configuration already + * checks the RSA signature of all involved nodes). + * + * Return: 0 for success, negative error code otherwise + */ +int fit_open_image(struct fit_handle *handle, void *configuration, + const char *name, const void **outdata, + unsigned long *outsize) { - struct device_node *image = NULL, *hash; + struct device_node *image; const char *unit, *type = NULL, *desc= "(no description)"; const void *data; int data_len; int ret = 0; - struct device_node *conf_node = handle->conf_node; - - if (!conf_node) - return -EINVAL; + struct device_node *conf_node = configuration; - if (of_property_read_string(conf_node, name, &unit)) { - pr_err("No image named '%s'\n", name); - return -ENOENT; + if (conf_node) { + if (of_property_read_string(conf_node, name, &unit)) { + pr_err("No image named '%s'\n", name); + return -ENOENT; + } + } else { + unit = name; } - image = of_get_child_by_name(handle->root, "images"); - if (!image) - return -ENOENT; - - image = of_get_child_by_name(image, unit); + image = of_get_child_by_name(handle->images, unit); if (!image) return -ENOENT; @@ -452,24 +561,13 @@ int fit_open_image(struct fit_handle *handle, const char *name, return -EINVAL; } - if (handle->verify > BOOTM_VERIFY_NONE) { - if (handle->verify == BOOTM_VERIFY_AVAILABLE) - ret = 0; - else - ret = -EINVAL; - for_each_child_of_node(image, hash) { - if (handle->verbose) - of_print_nodes(hash, 0); - ret = fit_verify_hash(hash, data, data_len); - if (ret < 0) - return ret; - } + if (conf_node) + ret = fit_verify_hash(handle, image, data, data_len); + else + ret = fit_image_verify_signature(handle, image, data, data_len); - if (ret < 0) { - pr_err("image '%s': '%s' does not have hashes\n", unit, desc); - return ret; - } - } + if (ret < 0) + return ret; *outdata = data; *outsize = data_len; @@ -546,15 +644,25 @@ default_unit: return -ENOENT; } -int fit_open_configuration(struct fit_handle *handle, const char *name) +/** + * fit_open_configuration - open a FIT configuration + * @handle: The FIT image handle + * @name: The name of the configuration + * + * This opens a FIT configuration and eventually checks the signature + * depending on the verify mode the FIT image is opened with. + * + * Return: If successful a pointer to a valid configuration node, + * otherwise a ERR_PTR() + */ +void *fit_open_configuration(struct fit_handle *handle, const char *name) { - struct device_node *conf_node = NULL; + struct device_node *conf_node = handle->configurations; const char *unit, *desc = "(no description)"; int ret; - conf_node = of_get_child_by_name(handle->root, "configurations"); if (!conf_node) - return -ENOENT; + return ERR_PTR(-ENOENT); if (name) { unit = name; @@ -562,14 +670,14 @@ int fit_open_configuration(struct fit_handle *handle, const char *name) ret = fit_find_compatible_unit(conf_node, &unit); if (ret) { pr_info("Couldn't get a valid configuration. Aborting.\n"); - return ret; + return ERR_PTR(ret); } } conf_node = of_get_child_by_name(conf_node, unit); if (!conf_node) { pr_err("configuration '%s' not found\n", unit); - return -ENOENT; + return ERR_PTR(-ENOENT); } of_property_read_string(conf_node, "description", &desc); @@ -577,80 +685,115 @@ int fit_open_configuration(struct fit_handle *handle, const char *name) ret = fit_config_verify_signature(handle, conf_node); if (ret) - return ret; + return ERR_PTR(ret); - handle->conf_node = conf_node; + return conf_node; +} - if (fit_has_image(handle, "kernel")) { - ret = fit_open_image(handle, "kernel", &handle->kernel, - &handle->kernel_size); - if (ret) - return ret; - } +static int fit_do_open(struct fit_handle *handle) +{ + const char *desc = "(no description)"; + struct device_node *root; - if (fit_has_image(handle, "ramdisk")) { - ret = fit_open_image(handle, "ramdisk", &handle->initrd, - &handle->initrd_size); - if (ret) - return ret; - } + root = of_unflatten_dtb(handle->fit); + if (IS_ERR(root)) + return PTR_ERR(root); - if (fit_has_image(handle, "fdt")) { - ret = fit_open_image(handle, "fdt", &handle->oftree, - &handle->oftree_size); - if (ret) - return ret; - } + handle->root = root; + + handle->images = of_get_child_by_name(handle->root, "images"); + if (!handle->images) + return -ENOENT; + + handle->configurations = of_get_child_by_name(handle->root, + "configurations"); + + of_property_read_string(handle->root, "description", &desc); + pr_info("Opened FIT image: %s\n", desc); return 0; } +/** + * fit_open_buf - open a FIT image from a buffer + * @buf: The buffer containing the FIT image + * @size: Size of the FIT image + * @verbose: If true, be more verbose + * @verify: The verify mode + * + * This opens a FIT image found in buf. The returned handle is used as + * context for the other FIT functions. + * + * Return: A handle to a FIT image or a ERR_PTR + */ +struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose, + enum bootm_verify verify) +{ + struct fit_handle *handle; + int ret; + + handle = xzalloc(sizeof(struct fit_handle)); + + handle->verbose = verbose; + handle->fit = buf; + handle->size = size; + handle->verify = verify; + + ret = fit_do_open(handle); + if (ret) { + fit_close(handle); + return ERR_PTR(ret); + } + + return handle; +} + +/** + * fit_open - open a FIT image + * @filename: The filename of the FIT image + * @verbose: If true, be more verbose + * @verify: The verify mode + * + * This opens a FIT image found in @filename. The returned handle is used as + * context for the other FIT functions. + * + * Return: A handle to a FIT image or a ERR_PTR + */ struct fit_handle *fit_open(const char *filename, bool verbose, enum bootm_verify verify) { - struct fit_handle *handle = NULL; - const char *desc = "(no description)"; - struct device_node *root; + struct fit_handle *handle; int ret; handle = xzalloc(sizeof(struct fit_handle)); handle->verbose = verbose; + handle->verify = verify; - ret = read_file_2(filename, &handle->size, &handle->fit, FILESIZE_MAX); + ret = read_file_2(filename, &handle->size, &handle->fit_alloc, + FILESIZE_MAX); if (ret) { pr_err("unable to read %s: %s\n", filename, strerror(-ret)); - goto err; + return ERR_PTR(ret); } - root = of_unflatten_dtb(handle->fit); - if (IS_ERR(root)) { - ret = PTR_ERR(root); - goto err; - } - - handle->root = root; - handle->verify = verify; + handle->fit = handle->fit_alloc; - of_property_read_string(handle->root, "description", &desc); - pr_info("'%s': %s\n", filename, desc); + ret = fit_do_open(handle); + if (ret) { + fit_close(handle); + return ERR_PTR(ret); + } return handle; - err: - if (handle->root) - of_delete_node(handle->root); - free(handle->fit); - free(handle); - - return ERR_PTR(ret); } void fit_close(struct fit_handle *handle) { if (handle->root) of_delete_node(handle->root); - if (handle->fit) - free(handle->fit); + + free(handle->fit_alloc); free(handle); } diff --git a/common/imd.c b/common/imd.c index a8a10fc9bb..05e118e773 100644 --- a/common/imd.c +++ b/common/imd.c @@ -35,7 +35,7 @@ int imd_command_setenv(const char *variable_name, const char *value) * imd_next - return a pointer to the next metadata field. * @imd The current metadata field */ -struct imd_header *imd_next(struct imd_header *imd) +const struct imd_header *imd_next(const struct imd_header *imd) { int length; @@ -43,10 +43,11 @@ struct imd_header *imd_next(struct imd_header *imd) length = ALIGN(length, 4); length += 8; - return (void *)imd + length; + return (const void *)imd + length; } -struct imd_header *imd_find_type(struct imd_header *imd, uint32_t type) +const struct imd_header *imd_find_type(const struct imd_header *imd, + uint32_t type) { imd_for_each(imd, imd) if (imd_read_type(imd) == type) @@ -55,10 +56,10 @@ struct imd_header *imd_find_type(struct imd_header *imd, uint32_t type) return NULL; } -static int imd_next_validate(void *buf, int bufsize, int start_ofs) +static int imd_next_validate(const void *buf, int bufsize, int start_ofs) { int length, size; - struct imd_header *imd = buf + start_ofs; + const struct imd_header *imd = buf + start_ofs; size = bufsize - start_ofs; @@ -82,10 +83,10 @@ static int imd_next_validate(void *buf, int bufsize, int start_ofs) return length; } -static int imd_validate_tags(void *buf, int bufsize, int start_ofs) +static int imd_validate_tags(const void *buf, int bufsize, int start_ofs) { int ret; - struct imd_header *imd = buf + start_ofs; + const struct imd_header *imd = buf + start_ofs; while (1) { uint32_t type; @@ -122,7 +123,7 @@ static int imd_validate_tags(void *buf, int bufsize, int start_ofs) * * Return: a pointer to the image metadata or a ERR_PTR */ -struct imd_header *imd_get(void *buf, int size) +const struct imd_header *imd_get(const void *buf, int size) { int start_ofs = 0; int i, ret; @@ -206,7 +207,7 @@ static uint32_t imd_name_to_type(const char *name) * * Return: A pointer to the string or NULL if the string is not found */ -const char *imd_string_data(struct imd_header *imd, int index) +const char *imd_string_data(const struct imd_header *imd, int index) { int i, total = 0, l = 0; int len = imd_read_length(imd); @@ -233,7 +234,7 @@ const char *imd_string_data(struct imd_header *imd, int index) * * Return: A pointer to the string or NULL if the string is not found */ -char *imd_concat_strings(struct imd_header *imd) +char *imd_concat_strings(const struct imd_header *imd) { int i, len = imd_read_length(imd); char *str; @@ -266,9 +267,9 @@ char *imd_concat_strings(struct imd_header *imd) * * Return: A pointer to the value or NULL if the string is not found */ -const char *imd_get_param(struct imd_header *imd, const char *name) +const char *imd_get_param(const struct imd_header *imd, const char *name) { - struct imd_header *cur; + const struct imd_header *cur; int namelen = strlen(name); imd_for_each(imd, cur) { @@ -294,7 +295,7 @@ int imd_command(int argc, char *argv[]) void *buf; size_t size; uint32_t type = IMD_TYPE_INVALID; - struct imd_header *imd_start, *imd; + const struct imd_header *imd_start, *imd; const char *filename; const char *variable_name = NULL; char *str; diff --git a/common/ratp.c b/common/ratp.c index 7be86d49a1..80863f81fb 100644 --- a/common/ratp.c +++ b/common/ratp.c @@ -54,14 +54,8 @@ struct ratp_bb_command_return { struct ratp_ctx { struct console_device *cdev; struct ratp ratp; - int ratp_status; struct console_device ratp_console; int have_synch; - int in_ratp_console; - - u8 sendbuf[256]; - u8 sendbuf_len; - int old_active; struct kfifo *console_recv_fifo; @@ -204,7 +198,7 @@ static int ratp_bb_send_getenv_return(struct ratp_ctx *ctx, const char *val) } static char *ratp_command; -static struct ratp_ctx *ratp_command_ctx; +static struct ratp_ctx *ratp_ctx; static int ratp_bb_dispatch(struct ratp_ctx *ctx, const void *buf, int len) { @@ -220,7 +214,7 @@ static int ratp_bb_dispatch(struct ratp_ctx *ctx, const void *buf, int len) return 0; ratp_command = xmemdup_add_zero(&rbb->data, dlen); - ratp_command_ctx = ctx; + ratp_ctx = ctx; pr_debug("got command: %s\n", ratp_command); break; @@ -323,7 +317,7 @@ static int ratp_console_register(struct ratp_ctx *ctx) return 0; } -void ratp_run_command(void) +void barebox_ratp_command_run(void) { int ret; @@ -337,7 +331,7 @@ void ratp_run_command(void) free(ratp_command); ratp_command = NULL; - ratp_bb_send_command_return(ratp_command_ctx, ret); + ratp_bb_send_command_return(ratp_ctx, ret); } static const char *ratpfs_mount_path; @@ -400,7 +394,7 @@ out: int barebox_ratp_fs_call(struct ratp_bb_pkt *tx, struct ratp_bb_pkt **rx) { - struct ratp_ctx *ctx = ratp_command_ctx; + struct ratp_ctx *ctx = ratp_ctx; struct ratp_bb *rbb; int len; u64 start; @@ -446,11 +440,11 @@ int barebox_ratp(struct console_device *cdev) if (!cdev->getc || !cdev->putc) return -EINVAL; - if (ratp_command_ctx) { - ctx = ratp_command_ctx; + if (ratp_ctx) { + ctx = ratp_ctx; } else { ctx = xzalloc(sizeof(*ctx)); - ratp_command_ctx = ctx; + ratp_ctx = ctx; ctx->ratp.send = console_send; ctx->ratp.recv = console_recv; ctx->console_recv_fifo = kfifo_alloc(512); @@ -494,7 +488,7 @@ out: static void barebox_ratp_close(void) { - if (ratp_command_ctx && ratp_command_ctx->cdev) - ratp_console_unregister(ratp_command_ctx); + if (ratp_ctx && ratp_ctx->cdev) + ratp_console_unregister(ratp_ctx); } predevshutdown_exitcall(barebox_ratp_close); diff --git a/common/startup.c b/common/startup.c index 8553849cb3..8940674528 100644 --- a/common/startup.c +++ b/common/startup.c @@ -67,6 +67,9 @@ static int mount_root(void) mount("none", "pstore", "/pstore", NULL); } + if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) + defaultenv_load("/env", 0); + return 0; } fs_initcall(mount_root); @@ -79,9 +82,6 @@ static int load_environment(void) default_environment_path = default_environment_path_get(); - if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) - defaultenv_load("/env", 0); - envfs_load(default_environment_path, "/env", 0); nvvar_load(); diff --git a/common/state/state.c b/common/state/state.c index 6399bd3736..cb979328c1 100644 --- a/common/state/state.c +++ b/common/state/state.c @@ -99,6 +99,7 @@ static int state_do_load(struct state *state, enum state_flags flags) goto out; } + state->init_from_defaults = 0; state->dirty = 0; out: @@ -153,6 +154,11 @@ void state_backend_set_readonly(struct state *state) state_storage_set_readonly(&state->storage); } +static int state_set_deny(struct param_d *p, void *priv) +{ + return -EROFS; +} + static struct state *state_new(const char *name) { struct state *state; @@ -172,12 +178,16 @@ static struct state *state_new(const char *name) } state->dirty = 1; - dev_add_param_bool(&state->dev, "dirty", NULL, NULL, &state->dirty, + dev_add_param_bool(&state->dev, "dirty", state_set_deny, NULL, &state->dirty, NULL); + state->save_on_shutdown = 1; dev_add_param_bool(&state->dev, "save_on_shutdown", NULL, NULL, &state->save_on_shutdown, NULL); + dev_add_param_bool(&state->dev, "init_from_defaults", state_set_deny, NULL, + &state->init_from_defaults, NULL); + list_add_tail(&state->list, &state_list); return state; @@ -638,6 +648,8 @@ struct state *state_new_from_node(struct device_node *node, char *path, goto out_release_state; } + state->init_from_defaults = 1; + ret = of_register_fixup(of_state_fixup, state); if (ret) { goto out_release_state; diff --git a/common/state/state.h b/common/state/state.h index fcc6b9f5cd..da1c6acaeb 100644 --- a/common/state/state.h +++ b/common/state/state.h @@ -107,7 +107,9 @@ struct state { uint32_t magic; struct list_head variables; /* Sorted list of variables */ + unsigned int dirty; + unsigned int init_from_defaults; unsigned int save_on_shutdown; struct state_backend_format *format; |