From c95e948870bdfc606946174facd9ea359ce84e58 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 25 Jan 2024 22:16:54 +0200 Subject: boot: pxe_utils: skip fdt setup in case legacy kernel is booted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, if boot with extlinux.conf and do not set the fdt U-Boot will provide its own device tree. This behavior is beneficial if the U-Boot device tree is in sync with Linux, but it totally halts the booting of pre-dtb kernels (3.4 for example) since it uses ATAGs. To fix this, pass `-` in the fdt extlinux field as a signal that no tree should be used. Suggested-by: Jonas Schwöbel Tested-by: Jethro Bull Signed-off-by: Svyatoslav Ryhel --- boot/pxe_utils.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'boot') diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index 83bc1677856..96205626750 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -634,7 +634,12 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) char *fdtfilefree = NULL; if (label->fdt) { - fdtfile = label->fdt; + if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) { + if (strcmp("-", label->fdt)) + fdtfile = label->fdt; + } else { + fdtfile = label->fdt; + } } else if (label->fdtdir) { char *f1, *f2, *f3, *f4, *slash; @@ -731,14 +736,26 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) zboot_argc = 5; } - if (!bootm_argv[3]) - bootm_argv[3] = env_get("fdt_addr"); + if (!bootm_argv[3]) { + if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) { + if (strcmp("-", label->fdt)) + bootm_argv[3] = env_get("fdt_addr"); + } else { + bootm_argv[3] = env_get("fdt_addr"); + } + } kernel_addr_r = genimg_get_kernel_addr(kernel_addr); buf = map_sysmem(kernel_addr_r, 0); - if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT) - bootm_argv[3] = env_get("fdtcontroladdr"); + if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT) { + if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) { + if (strcmp("-", label->fdt)) + bootm_argv[3] = env_get("fdtcontroladdr"); + } else { + bootm_argv[3] = env_get("fdtcontroladdr"); + } + } if (bootm_argv[3]) { if (!bootm_argv[2]) -- cgit v1.3.1 From 8987c06f46dfd192f765c738b15119850054f18b Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Mon, 12 Feb 2024 10:35:12 +0100 Subject: bootdev: drop unnecessary assert on bootflow->bdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not all flows have a device and the function already contains logic to handle this case. Fixes: eccb25cd5922 ("bootstd: Allow the bootdev to be optional in bootflows") Signed-off-by: Thomas Weißschuh --- boot/bootdev-uclass.c | 1 - 1 file changed, 1 deletion(-) (limited to 'boot') diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 35afb93c0e7..0fa6dad8b11 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -39,7 +39,6 @@ int bootdev_add_bootflow(struct bootflow *bflow) struct bootflow *new; int ret; - assert(bflow->dev); ret = bootstd_get_priv(&std); if (ret) return ret; -- cgit v1.3.1 From 14e110a1a439228e223b391a1fc83ec18753335d Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 15 Feb 2024 12:12:18 -0500 Subject: boot: Only define checksum algos when the hashes are enabled Don't define checksum algos when the underlying hashes are not enabled. This allows disabling these hashes in SPL (or U-Boot). Fixes: d16b38f4270 ("Add support for SHA384 and SHA512") Fixes: 646257d1f40 ("rsa: add sha256-rsa2048 algorithm") Signed-off-by: Sean Anderson --- boot/image-sig.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'boot') diff --git a/boot/image-sig.c b/boot/image-sig.c index b5692d58b24..0421a61b040 100644 --- a/boot/image-sig.c +++ b/boot/image-sig.c @@ -17,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; #define IMAGE_MAX_HASHED_NODES 100 struct checksum_algo checksum_algos[] = { +#if CONFIG_IS_ENABLED(SHA1) { .name = "sha1", .checksum_len = SHA1_SUM_LEN, @@ -24,6 +25,8 @@ struct checksum_algo checksum_algos[] = { .der_prefix = sha1_der_prefix, .calculate = hash_calculate, }, +#endif +#if CONFIG_IS_ENABLED(SHA256) { .name = "sha256", .checksum_len = SHA256_SUM_LEN, @@ -31,7 +34,8 @@ struct checksum_algo checksum_algos[] = { .der_prefix = sha256_der_prefix, .calculate = hash_calculate, }, -#ifdef CONFIG_SHA384 +#endif +#if CONFIG_IS_ENABLED(SHA384) { .name = "sha384", .checksum_len = SHA384_SUM_LEN, @@ -40,7 +44,7 @@ struct checksum_algo checksum_algos[] = { .calculate = hash_calculate, }, #endif -#ifdef CONFIG_SHA512 +#if CONFIG_IS_ENABLED(SHA512) { .name = "sha512", .checksum_len = SHA512_SUM_LEN, -- cgit v1.3.1 From 1132471405512619241dc879861f1b5beb95c48c Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Wed, 21 Feb 2024 13:41:44 +0100 Subject: bootstd: support scanning a single partition The "bootflow" command currently doesn't support scanning a single partition. This is inconvenient in setups with multiple bootable partitions within a single disk, but only one is desired. Support scanning a single disk partition. Specifically, support the syntax: bootflow scan mmc1:4 which scans only mmc device 1, partition 4. Signed-off-by: Nam Cao --- boot/bootdev-uclass.c | 35 +++++++++++++++++++++++++++++++++-- boot/bootflow.c | 3 +++ doc/develop/bootstd.rst | 4 ++++ include/bootflow.h | 3 +++ 4 files changed, 43 insertions(+), 2 deletions(-) (limited to 'boot') diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 0fa6dad8b11..46815ea2fdb 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -172,8 +172,10 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk, */ iter->max_part = MAX_PART_PER_BOOTDEV; - /* If this is the whole disk, check if we have bootable partitions */ - if (!iter->part) { + if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) { + /* a particular partition was specified, scan it without checking */ + } else if (!iter->part) { + /* This is the whole disk, check if we have bootable partitions */ iter->first_bootable = part_get_bootable(desc); log_debug("checking bootable=%d\n", iter->first_bootable); } else if (allow_any_part) { @@ -710,8 +712,37 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, struct udevice *bootstd, *dev = NULL; bool show = iter->flags & BOOTFLOWIF_SHOW; int method_flags; + char buf[32]; int ret; + if (label) { + const char *end = strchr(label, ':'); + + if (end) { + size_t len = (size_t)(end - label); + const char *part = end + 1; + + if (len + 1 > sizeof(buf)) { + log_err("label \"%s\" is way too long\n", label); + return -EINVAL; + } + + memcpy(buf, label, len); + buf[len] = '\0'; + label = buf; + + unsigned long tmp; + + if (strict_strtoul(part, 0, &tmp)) { + log_err("Invalid partition number: %s\n", part); + return -EINVAL; + } + + iter->flags |= BOOTFLOWIF_SINGLE_PARTITION; + iter->part = tmp; + } + } + ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd); if (ret) { log_err("Missing bootstd device\n"); diff --git a/boot/bootflow.c b/boot/bootflow.c index 05484fd5b1b..68bf99329ab 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -217,6 +217,9 @@ static int iter_incr(struct bootflow_iter *iter) } } + if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) + return BF_NO_MORE_DEVICES; + /* No more bootmeths; start at the first one, and... */ iter->cur_method = 0; iter->method = iter->method_order[iter->cur_method]; diff --git a/doc/develop/bootstd.rst b/doc/develop/bootstd.rst index 496e24bc7a6..a07a72581e7 100644 --- a/doc/develop/bootstd.rst +++ b/doc/develop/bootstd.rst @@ -531,6 +531,10 @@ Then the iterator is set up to according to the parameters given: `BOOTFLOWIF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev processes just the children of the media device. Hunters are used, in this example just the "mmc" hunter. + - If `label` indicates a particular partition in a particular media device + (e.g. "mmc1:3") then `BOOTFLOWIF_SINGLE_PARTITION` is set. In this case, + only a single partition within a bootdev is processed. Hunters are used, in + this example just the "mmc" hunter. - If `label` indicates a media uclass (e.g. "mmc") then `BOOTFLOWIF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass are used. Hunters are used, in this example just the "mmc" hunter diff --git a/include/bootflow.h b/include/bootflow.h index 42112874f64..080ee850122 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -133,6 +133,8 @@ struct bootflow { * this uclass (used with things like "mmc") * @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used * with things like "mmc1") + * @BOOTFLOWIF_SINGLE_PARTITION: (internal) Scan one partition in media device + * (used with things like "mmc1:3") */ enum bootflow_iter_flags_t { BOOTFLOWIF_FIXED = 1 << 0, @@ -148,6 +150,7 @@ enum bootflow_iter_flags_t { BOOTFLOWIF_SKIP_GLOBAL = 1 << 17, BOOTFLOWIF_SINGLE_UCLASS = 1 << 18, BOOTFLOWIF_SINGLE_MEDIA = 1 << 19, + BOOTFLOWIF_SINGLE_PARTITION = 1 << 20, }; /** -- cgit v1.3.1 From d545fe3b82ca319f699abb40f59f7ab5f8116de5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 2 Mar 2024 23:54:02 +0100 Subject: fdt: Fix bootm_low handling According to README CFG_SYS_BOOTMAPSZ section, in case both "bootm_low" and "bootm_size" variables are defined, "bootm_mapsize" variable is not defined and CFG_SYS_BOOTMAPSZ macro is not defined, all data for the Linux kernel must be between "bootm_low" and "bootm_low" + "bootm_size". Currently, for systems with DRAM between 0x4000_0000..0x7fff_ffff and with e.g. bootm_low=0x60000000 and bootm_size=0x10000000, the code will attempt to reserve memory from 0x4000_0000..0x4fff_ffff, which is incorrect. This is because "bootm_low" is not taken into consideration correctly. The last parameter of lmb_alloc_base() is the maximum physical address of the to be reserved LMB area. Currently this is the start of DRAM bank that is considered for LMB area reservation + min(DRAM bank size, bootm_size). In case bootm_low is set to non-zero, this maximum physical address has to be shifted upward, to min(DRAM bank start + size, bootm_low + bootm_size), otherwise the reserved memory may be below bootm_low address. In case of multiple DRAM banks, the current change reserves top part of the first bank, and reserves the rest of memory in the follow up banks. Signed-off-by: Marek Vasut --- boot/image-fdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'boot') diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 75bdd55f326..5e4aa9de0d2 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -217,14 +217,14 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) if (start + size < low) continue; - usable = min(size, (u64)mapsize); + usable = min(start + size, (u64)(low + mapsize)); /* * At least part of this DRAM bank is usable, try * using it for LMB allocation. */ of_start = map_sysmem((ulong)lmb_alloc_base(lmb, - of_len, 0x1000, start + usable), of_len); + of_len, 0x1000, usable), of_len); /* Allocation succeeded, use this block. */ if (of_start != NULL) break; -- cgit v1.3.1