diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-06-16 10:54:37 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-06-16 10:54:37 +0200 |
commit | bdc5a5d220edf8c8a2685f9f3f066798f521f9e8 (patch) | |
tree | 325523510c33b49db7980a33ac917b48f1eb856e /common | |
parent | a1ac6b5f64cda522ecdcb308a414b4aa21cc99be (diff) | |
parent | f8a6bc23fdfb5a6f17032fc73b3b7f3ca33c5d2a (diff) | |
download | barebox-bdc5a5d220edf8c8a2685f9f3f066798f521f9e8.tar.gz barebox-bdc5a5d220edf8c8a2685f9f3f066798f521f9e8.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'common')
-rw-r--r-- | common/boot.c | 4 | ||||
-rw-r--r-- | common/bootm.c | 181 | ||||
-rw-r--r-- | common/oftree.c | 42 | ||||
-rw-r--r-- | common/partitions/efi.c | 13 | ||||
-rw-r--r-- | common/partitions/parser.h | 2 |
5 files changed, 182 insertions, 60 deletions
diff --git a/common/boot.c b/common/boot.c index 07b67734d8..8220b8d3fb 100644 --- a/common/boot.c +++ b/common/boot.c @@ -138,7 +138,7 @@ int boot_entry(struct bootentry *be, int verbose, int dryrun) { int ret; - printf("Booting entry '%s'\n", be->title); + pr_info("Booting entry '%s'\n", be->title); if (IS_ENABLED(CONFIG_WATCHDOG) && boot_watchdog_timeout) { boot_enabled_watchdog = watchdog_get_default(); @@ -319,7 +319,7 @@ void bootsources_menu(struct bootentries *bootentries, int timeout) struct menu_entry *back_entry; if (!IS_ENABLED(CONFIG_MENU)) { - printf("no menu support available\n"); + pr_warn("no menu support available\n"); return; } diff --git a/common/bootm.c b/common/bootm.c index 092116beb9..644443a021 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -12,6 +12,7 @@ #include <environment.h> #include <linux/stat.h> #include <magicvar.h> +#include <uncompress.h> static LIST_HEAD(handler_list); @@ -111,7 +112,7 @@ int bootm_load_os(struct image_data *data, unsigned long load_address) data->os_res = request_sdram_region("kernel", load_address, kernel_size); if (!data->os_res) { - printf("unable to request SDRAM region for kernel at" + pr_err("unable to request SDRAM region for kernel at" "0x%08llx-0x%08llx\n", (unsigned long long)load_address, (unsigned long long)load_address + kernel_size - 1); @@ -175,7 +176,7 @@ static int bootm_open_initrd_uimage(struct image_data *data) if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) { ret = uimage_verify(data->initrd); if (ret) { - printf("Checking data crc failed with %s\n", + pr_err("Checking data crc failed with %s\n", strerror(-ret)); return ret; } @@ -231,21 +232,21 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address) load_address, initrd_size); if (!data->initrd_res) { - printf("unable to request SDRAM region for initrd at" + pr_err("unable to request SDRAM region for initrd at" "0x%08llx-0x%08llx\n", (unsigned long long)load_address, (unsigned long long)load_address + initrd_size - 1); return -ENOMEM; } memcpy((void *)load_address, initrd, initrd_size); - printf("Loaded initrd from FIT image\n"); + pr_info("Loaded initrd from FIT image\n"); goto done1; } type = file_name_detect_type(data->initrd_file); if ((int)type < 0) { - printf("could not open %s: %s\n", data->initrd_file, + pr_err("could not open %s: %s\n", data->initrd_file, strerror(-type)); return (int)type; } @@ -254,8 +255,8 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address) int num; ret = bootm_open_initrd_uimage(data); if (ret) { - printf("loading initrd failed with %s\n", - strerror(-ret)); + pr_err("loading initrd failed with %s\n", + strerror(-ret)); return ret; } @@ -275,13 +276,13 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address) done: - printf("Loaded initrd %s '%s'", file_type_to_string(type), + pr_info("Loaded initrd %s '%s'", file_type_to_string(type), data->initrd_file); if (type == filetype_uimage && data->initrd->header.ih_type == IH_TYPE_MULTI) - printf(", multifile image %s", data->initrd_part); - printf("\n"); + pr_info(", multifile image %s", data->initrd_part); + pr_info("\n"); done1: - printf("initrd is at %pa-%pa\n", + pr_info("initrd is at %pa-%pa\n", &data->initrd_res->start, &data->initrd_res->end); @@ -297,7 +298,7 @@ static int bootm_open_oftree_uimage(struct image_data *data, size_t *size, struct uimage_handle *of_handle; int release = 0; - printf("Loading devicetree from '%s'@%d\n", oftree, num); + pr_info("Loading devicetree from '%s'@%d\n", oftree, num); if (!IS_ENABLED(CONFIG_BOOTM_OFTREE_UIMAGE)) return -EINVAL; @@ -321,7 +322,7 @@ static int bootm_open_oftree_uimage(struct image_data *data, size_t *size, ft = file_detect_type(*fdt, *size); if (ft != filetype_oftree) { - printf("%s is not an oftree but %s\n", + pr_err("%s is not an oftree but %s\n", data->oftree_file, file_type_to_string(ft)); free(*fdt); return -EINVAL; @@ -367,8 +368,8 @@ void *bootm_get_devicetree(struct image_data *data) type = file_name_detect_type(data->oftree_file); if ((int)type < 0) { - printf("could not open %s: %s\n", data->oftree_file, - strerror(-type)); + pr_err("could not open %s: %s\n", data->oftree_file, + strerror(-type)); return ERR_PTR((int)type); } @@ -377,7 +378,7 @@ void *bootm_get_devicetree(struct image_data *data) ret = bootm_open_oftree_uimage(data, &size, &oftree); break; case filetype_oftree: - printf("Loading devicetree from '%s'\n", data->oftree_file); + pr_info("Loading devicetree from '%s'\n", data->oftree_file); ret = read_file_2(data->oftree_file, &size, (void *)&oftree, FILESIZE_MAX); break; @@ -448,7 +449,7 @@ int bootm_load_devicetree(struct image_data *data, void *fdt, data->oftree_res = request_sdram_region("oftree", load_address, fdt_size); if (!data->oftree_res) { - printf("unable to request SDRAM region for device tree at" + pr_err("unable to request SDRAM region for device tree at" "0x%08llx-0x%08llx\n", (unsigned long long)load_address, (unsigned long long)load_address + fdt_size - 1); @@ -497,7 +498,7 @@ static int bootm_open_os_uimage(struct image_data *data) if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) { ret = uimage_verify(data->os); if (ret) { - printf("Checking data crc failed with %s\n", + pr_err("Checking data crc failed with %s\n", strerror(-ret)); return ret; } @@ -506,7 +507,7 @@ static int bootm_open_os_uimage(struct image_data *data) uimage_print_contents(data->os); if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) { - printf("Unsupported Architecture 0x%x\n", + pr_err("Unsupported Architecture 0x%x\n", data->os->header.ih_arch); return -EINVAL; } @@ -526,7 +527,7 @@ static int bootm_open_elf(struct image_data *data) if (IS_ERR(data->elf)) return PTR_ERR(data->elf); - printf("Entry Point: %08llx\n", data->elf->entry); + pr_info("Entry Point: %08llx\n", data->elf->entry); data->os_address = data->elf->entry; @@ -578,7 +579,7 @@ int bootm_boot(struct bootm_data *bootm_data) size_t size; if (!bootm_data->os_file) { - printf("no image given\n"); + pr_err("no image given\n"); return -ENOENT; } @@ -599,7 +600,7 @@ int bootm_boot(struct bootm_data *bootm_data) ret = read_file_2(data->os_file, &size, &data->os_header, PAGE_SIZE); if (ret < 0 && ret != -EFBIG) { - printf("could not open %s: %s\n", data->os_file, + pr_err("could not open %s: %s\n", data->os_file, strerror(-ret)); goto err_out; } @@ -609,7 +610,7 @@ int bootm_boot(struct bootm_data *bootm_data) os_type = file_detect_type(data->os_header, PAGE_SIZE); if (!data->force && os_type == filetype_unknown) { - printf("Unknown OS filetype (try -f)\n"); + pr_err("Unknown OS filetype (try -f)\n"); ret = -EINVAL; goto err_out; } @@ -625,7 +626,7 @@ int bootm_boot(struct bootm_data *bootm_data) data->initrd_file = NULL; data->tee_file = NULL; if (os_type != filetype_oftree) { - printf("Signed boot and image is no FIT image, aborting\n"); + pr_err("Signed boot and image is no FIT image, aborting\n"); ret = -EINVAL; goto err_out; } @@ -637,7 +638,7 @@ int bootm_boot(struct bootm_data *bootm_data) fit = fit_open(data->os_file, data->verbose, data->verify); if (IS_ERR(fit)) { - printf("Loading FIT image %s failed with: %pe\n", data->os_file, fit); + pr_err("Loading FIT image %s failed with: %pe\n", data->os_file, fit); ret = PTR_ERR(fit); goto err_out; } @@ -647,7 +648,7 @@ int bootm_boot(struct bootm_data *bootm_data) 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", + pr_err("Cannot open FIT image configuration '%s'\n", data->os_part ? data->os_part : "default"); ret = PTR_ERR(data->fit_config); goto err_out; @@ -663,8 +664,8 @@ int bootm_boot(struct bootm_data *bootm_data) kernel_img, "load", &data->os_address); if (!ret) - printf("Load address from FIT '%s': 0x%lx\n", - kernel_img, data->os_address); + pr_info("Load address from FIT '%s': 0x%lx\n", + kernel_img, data->os_address); /* Note: Error case uses default value. */ } if (data->os_entry == UIMAGE_SOME_ADDRESS) { @@ -675,8 +676,8 @@ int bootm_boot(struct bootm_data *bootm_data) "entry", &entry); if (!ret) { data->os_entry = entry - data->os_address; - printf("Entry address from FIT '%s': 0x%lx\n", - kernel_img, entry); + pr_info("Entry address from FIT '%s': 0x%lx\n", + kernel_img, entry); } /* Note: Error case uses default value. */ } @@ -685,8 +686,8 @@ int bootm_boot(struct bootm_data *bootm_data) if (os_type == filetype_uimage) { ret = bootm_open_os_uimage(data); if (ret) { - printf("Loading OS image failed with: %s\n", - strerror(-ret)); + pr_err("Loading OS image failed with: %s\n", + strerror(-ret)); goto err_out; } } @@ -694,8 +695,8 @@ int bootm_boot(struct bootm_data *bootm_data) if (os_type == filetype_elf) { ret = bootm_open_elf(data); if (ret) { - printf("Loading ELF image failed with: %s\n", - strerror(-ret)); + pr_err("Loading ELF image failed with: %s\n", + strerror(-ret)); data->elf = NULL; goto err_out; } @@ -724,7 +725,7 @@ int bootm_boot(struct bootm_data *bootm_data) rootarg = path_get_linux_rootarg(data->os_file); } if (!IS_ERR(rootarg)) { - printf("Adding \"%s\" to Kernel commandline\n", rootarg); + pr_info("Adding \"%s\" to Kernel commandline\n", rootarg); globalvar_add_simple("linux.bootargs.bootm.appendroot", rootarg); free(rootarg); @@ -736,7 +737,7 @@ int bootm_boot(struct bootm_data *bootm_data) char *machine_id_bootarg; if (!machine_id) { - printf("Providing machine id is enabled but no machine id set\n"); + pr_err("Providing machine id is enabled but no machine id set\n"); ret = -EINVAL; goto err_out; } @@ -746,12 +747,12 @@ int bootm_boot(struct bootm_data *bootm_data) free(machine_id_bootarg); } - printf("\nLoading %s '%s'", file_type_to_string(os_type), - data->os_file); + pr_info("\nLoading %s '%s'", file_type_to_string(os_type), + data->os_file); if (os_type == filetype_uimage && data->os->header.ih_type == IH_TYPE_MULTI) - printf(", multifile image %d", uimage_part_num(data->os_part)); - printf("\n"); + pr_info(", multifile image %d", uimage_part_num(data->os_part)); + pr_info("\n"); if (data->os_address == UIMAGE_SOME_ADDRESS) data->os_address = UIMAGE_INVALID_ADDRESS; @@ -760,10 +761,10 @@ int bootm_boot(struct bootm_data *bootm_data) handler = bootm_find_handler(os_type, data); if (!handler) { - printf("no image handler found for image type %s\n", - file_type_to_string(os_type)); + pr_err("no image handler found for image type %s\n", + file_type_to_string(os_type)); if (os_type == filetype_uimage) - printf("and OS type: %d\n", data->os->header.ih_os); + pr_err("and OS type: %d\n", data->os->header.ih_os); ret = -ENODEV; goto err_out; } @@ -775,7 +776,7 @@ int bootm_boot(struct bootm_data *bootm_data) ret = handler->bootm(data); if (data->dryrun) - printf("Dryrun. Aborted\n"); + pr_info("Dryrun. Aborted\n"); err_out: if (data->os_res) @@ -808,6 +809,86 @@ err_out: return ret; } +static int do_bootm_compressed(struct image_data *img_data) +{ + struct bootm_data bootm_data = { + .oftree_file = img_data->oftree_file, + .initrd_file = img_data->initrd_file, + .tee_file = img_data->tee_file, + .verbose = img_data->verbose, + .verify = img_data->verify, + .force = img_data->force, + .dryrun = img_data->dryrun, + .initrd_address = img_data->initrd_address, + .os_address = img_data->os_address, + .os_entry = img_data->os_entry, + }; + int from, to, ret; + char *dstpath; + + from = open(img_data->os_file, O_RDONLY); + if (from < 0) + return -ENODEV; + + dstpath = make_temp("bootm-compressed"); + if (!dstpath) { + ret = -ENOMEM; + goto fail_from; + } + + to = open(dstpath, O_CREAT | O_WRONLY); + if (to < 0) { + ret = -ENODEV; + goto fail_make_temp; + } + + ret = uncompress_fd_to_fd(from, to, uncompress_err_stdout); + if (ret) + goto fail_to; + + bootm_data.os_file = dstpath; + ret = bootm_boot(&bootm_data); + +fail_to: + close(to); + unlink(dstpath); +fail_make_temp: + free(dstpath); +fail_from: + close(from); + return ret; +} + +static struct image_handler bzip2_bootm_handler = { + .name = "BZIP2 compressed file", + .bootm = do_bootm_compressed, + .filetype = filetype_bzip2, +}; + +static struct image_handler gzip_bootm_handler = { + .name = "GZIP compressed file", + .bootm = do_bootm_compressed, + .filetype = filetype_gzip, +}; + +static struct image_handler lzo_bootm_handler = { + .name = "LZO compressed file", + .bootm = do_bootm_compressed, + .filetype = filetype_lzo_compressed, +}; + +static struct image_handler lz4_bootm_handler = { + .name = "LZ4 compressed file", + .bootm = do_bootm_compressed, + .filetype = filetype_lz4_compressed, +}; + +static struct image_handler xz_bootm_handler = { + .name = "XZ compressed file", + .bootm = do_bootm_compressed, + .filetype = filetype_xz_compressed, +}; + static int bootm_init(void) { globalvar_add_simple("bootm.image", NULL); @@ -830,6 +911,18 @@ static int bootm_init(void) globalvar_add_simple_enum("bootm.verify", (unsigned int *)&bootm_verify_mode, bootm_verify_names, ARRAY_SIZE(bootm_verify_names)); + + if (IS_ENABLED(CONFIG_BZLIB)) + register_image_handler(&bzip2_bootm_handler); + if (IS_ENABLED(CONFIG_ZLIB)) + register_image_handler(&gzip_bootm_handler); + if (IS_ENABLED(CONFIG_LZO_DECOMPRESS)) + register_image_handler(&lzo_bootm_handler); + if (IS_ENABLED(CONFIG_LZ4_DECOMPRESS)) + register_image_handler(&lz4_bootm_handler); + if (IS_ENABLED(CONFIG_XZ_DECOMPRESS)) + register_image_handler(&xz_bootm_handler); + return 0; } late_initcall(bootm_init); diff --git a/common/oftree.c b/common/oftree.c index 60d4327155..5eaa63ad7e 100644 --- a/common/oftree.c +++ b/common/oftree.c @@ -16,6 +16,7 @@ #include <reset_source.h> #include <watchdog.h> #include <globalvar.h> +#include <magicvar.h> #define MAX_LEVEL 32 /* how deeply nested we will go */ @@ -115,7 +116,7 @@ void of_print_cmdline(struct device_node *root) cmdline = of_get_property(node, "bootargs", NULL); - printf("commandline: %s\n", cmdline); + pr_info("commandline: %s\n", cmdline); } static int of_fixup_bootargs_bootsource(struct device_node *root, @@ -161,16 +162,17 @@ static void watchdog_build_bootargs(struct watchdog *watchdog, struct device_nod free(buf); } -static int of_fixup_bootargs(struct device_node *root, void *unused) +static int bootargs_append = 0; +BAREBOX_MAGICVAR(global.linux.bootargs_append, "append to original oftree bootargs"); + +static int of_write_bootargs(struct device_node *node) { - struct device_node *node; const char *str; - int err; - int instance = reset_source_get_instance(); - struct device_d *dev; + char *buf = NULL; + int ret; if (IS_ENABLED(CONFIG_SYSTEMD_OF_WATCHDOG)) - watchdog_build_bootargs(boot_get_enabled_watchdog(), root); + watchdog_build_bootargs(boot_get_enabled_watchdog(), of_get_parent(node)); str = linux_bootargs_get(); if (!str) @@ -180,13 +182,36 @@ static int of_fixup_bootargs(struct device_node *root, void *unused) if (strlen(str) == 0) return 0; + if (bootargs_append) { + const char *oldstr; + + ret = of_property_read_string(node, "bootargs", &oldstr); + if (!ret) { + str = buf = basprintf("%s %s", oldstr, str); + if (!buf) + return -ENOMEM; + } + } + + ret = of_property_write_string(node, "bootargs", str); + free(buf); + return ret; +} + +static int of_fixup_bootargs(struct device_node *root, void *unused) +{ + struct device_node *node; + int err; + int instance = reset_source_get_instance(); + struct device_d *dev; + node = of_create_node(root, "/chosen"); if (!node) return -ENOMEM; of_property_write_string(node, "barebox-version", release_string); - err = of_property_write_string(node, "bootargs", str); + err = of_write_bootargs(node); if (err) return err; @@ -212,6 +237,7 @@ static int of_fixup_bootargs(struct device_node *root, void *unused) static int of_register_bootargs_fixup(void) { + globalvar_add_simple_bool("linux.bootargs_append", &bootargs_append); return of_register_fixup(of_fixup_bootargs, NULL); } late_initcall(of_register_bootargs_fixup); diff --git a/common/partitions/efi.c b/common/partitions/efi.c index 437c3d64f8..135b08901a 100644 --- a/common/partitions/efi.c +++ b/common/partitions/efi.c @@ -446,7 +446,14 @@ static void efi_partition(void *buf, struct block_device *blk, } nb_part = le32_to_cpu(gpt->num_partition_entries); - for (i = 0; i < MAX_PARTITION && i < nb_part; i++) { + + if (nb_part > MAX_PARTITION) { + dev_warn(blk->dev, "GPT has more partitions than we support (%d) > max partition number (%d)\n", + nb_part, MAX_PARTITION); + nb_part = MAX_PARTITION; + } + + for (i = 0; i < nb_part; i++) { if (!is_pte_valid(&ptes[i], last_lba(blk))) { dev_dbg(blk->dev, "Invalid pte %d\n", i); return; @@ -460,10 +467,6 @@ static void efi_partition(void *buf, struct block_device *blk, snprintf(pentry->partuuid, sizeof(pentry->partuuid), "%pUl", &ptes[i].unique_partition_guid); pd->used_entries++; } - - if (i > MAX_PARTITION) - dev_warn(blk->dev, "num_partition_entries (%d) > max partition number (%d)\n", - nb_part, MAX_PARTITION); } static struct partition_parser efi_partition_parser = { diff --git a/common/partitions/parser.h b/common/partitions/parser.h index 8ad134a9aa..69508932b3 100644 --- a/common/partitions/parser.h +++ b/common/partitions/parser.h @@ -11,7 +11,7 @@ #include <filetype.h> #include <linux/list.h> -#define MAX_PARTITION 8 +#define MAX_PARTITION 128 #define MAX_PARTITION_NAME 38 struct partition { |