From patchwork Tue Mar 24 22:18:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2047 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390779; bh=bJQDGSaEZqtICMwGKDEtBwy3VxaqixqgQz6v7o2PsaM=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=E/U+iA49cPujF1090ho3M3Ybl7VE6KDpur9hqLBjPcz9Vxd3tez8Nah8t4N8u1Koo eDAo93wiyCPUHcpSvPZuna0et6N3xMIPrdlQC8WEDaQv4CZT8tAY3qHGfa9p8uJkha wALS5L4EfRI4JsSMKyjBidAyw9pb1MKl4lMS9W0KxjcvkKSZXc18nfpK+yGCfYsHiJ EQ8OZ6BLSrgwtetx76QSOHw+6ulhqaotkwFWoejk/6RVvdE5zsyBnpva74GqO+STP+ 1mFUsMHd5TiGiiiugUIKXgd4xaOOJccg32G+LJspVTctqZCYk/81TVmEESUROSqazW o0Gpr60jSD5Rw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id F40726A243 for ; Tue, 24 Mar 2026 16:19:38 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id CrKPHAX6dQHM for ; Tue, 24 Mar 2026 16:19:38 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390777; bh=bJQDGSaEZqtICMwGKDEtBwy3VxaqixqgQz6v7o2PsaM=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=JCN4zNK4DJrV9HARbs+z2KSWVS2lR9YBw/IHq3moV/fh5Gn23/WWF0mR9vnFiNEin FBci6DAOQ30RAnuD5Ke0lXcnVPe8Dxk52/bU642ZDc1I75OlIuxXvvIAVltL72tCR3 YOLQ4Pfhk89Ty5XFmnjfTUAVF5XJMY+AQjeZRtP80udwZjPRdUzsxLDm/0JIW2McDV iN3geLkYwdBYKzj3B7KNBM0IXWy0V9fqHfOWyGDlABXDAL8mIsb/dyr1ND7N3/qd8g DR/ZBbeX9NDVhd1dzCmjyMS06pcomBYQrTAwJfdeMd0lUGktcySnBkHkLLbu6ubDRu zNVCJcsBnb6dw== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D01EF6A23D for ; Tue, 24 Mar 2026 16:19:37 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390776; bh=ojTC8CkK9giogzMqwYa29fzWRprl9KPw2ciBw0376x8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y5IR24LXX4RMyPMGM3t+XnVNM3c63spa0F/fmSNrcvhBLYpsKPnNiqTzxz7gcTenM N77s2kV8JCYrl/fbaFOHdcr+3ID3EeIJrZCilbkSny6pM4OxhhYpxv7DnZw1quZVb9 PpzZMaKdrfIs8x+wNDNYlGNk+k7N63umYJ6AgDdmPzS5P3UN67UVPQeNstzuHp3r8e 3OHaqt5HFHy/0sKLsnt2wgMjQcnKuzi6igoAEZl4BZnwbJJHHGk+nrkOMJK4Pa94Q0 gEJ9E19z9m7F0I1f1egFXB20mKeGyUmoKdNm4MxNIZIxSOHHFiZHbg683+zqziW8U5 PfI2hhGKoLZbw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 64DC46A23F; Tue, 24 Mar 2026 16:19:36 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id F72QaeRuxH-F; Tue, 24 Mar 2026 16:19:36 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390776; bh=XZrMuvdHCmUKEOLNNs8B3iIwPSYWWVCADStjWN9byAo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZNifygfOqkTEV+aL43trdeWurh/LM2qir+yV7lcKkAfcC7YsSwSKi5Z78OyXGkZOj w0R5he8JyxcrdlKfXits6QHmYbbSF8mL2zBfVM/fJ+qOeP4xAor/P/Uxk6Z0i+XIyG vRNrbtpfZ5NpL+Xxre8jW8wGn8DBt2D7FaVe/aK2WJoEZXdjsYMouyJXxMu42JxLU7 9laIs4Bya4mrIfz4z3xfrGAHwJN3gX960lcfp4MQcR4oyxeI83zyZNex6VCtuLFJNH mtMorAzUIETroSda83I3/QA5cR9rh1ll+8+s2p6Fbe5SPpKb7ohTWD/V+KczEdhkth YCKL3cmi4TAAg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id D215C6A1DD; Tue, 24 Mar 2026 16:19:35 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:18:55 -0600 Message-ID: <20260324221911.3678307-2-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: OA7WXBFRDQ6POH3HZPSU4A36GHG4NLUD X-Message-ID-Hash: OA7WXBFRDQ6POH3HZPSU4A36GHG4NLUD X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 01/12] extlinux: Use pxe_parse() to extract bootflow info List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Replace the hand-rolled line-by-line parser in extlinux_fill_info() with the pxe_parse() API. This gives a fully parsed menu structure instead of ad-hoc string matching, and is a first step towards supporting multiple bootflows per partition (e.g. when an extlinux config defines several labels). The first label's menu name is used if available, falling back to the label name, matching the previous behaviour. Signed-off-by: Simon Glass --- boot/bootmeth_extlinux.c | 60 ++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index 286d176ae20..3ffe21d96a3 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -117,48 +117,42 @@ static int extlinux_check_luks(struct bootflow *bflow) /** * extlinux_fill_info() - Decode the extlinux file to find out its info * + * Uses pxe_parse() to parse the configuration file and extract the first + * label's name to use as the bootflow OS name. + * * @bflow: Bootflow to process - * @return 0 if OK, -ve on error + * Return: 0 if OK, -ve on error */ static int extlinux_fill_info(struct bootflow *bflow) { - struct membuf mb; - char line[200]; - char *data; - int len; + struct pxe_context *ctx; + struct pxe_label *label; + const char *name; + ulong addr; log_debug("parsing bflow file size %x\n", bflow->size); - membuf_init(&mb, bflow->buf, bflow->size); - membuf_putraw(&mb, bflow->size, true, &data); - while (len = membuf_readline(&mb, line, sizeof(line) - 1, 0, true), len) { - char *tok, *p = line; - const char *name = NULL; - - if (*p == '#') - continue; - while (*p == ' ' || *p == '\t') - p++; - tok = strsep(&p, " "); - if (p) { - if (!strcmp("label", tok)) { - name = p; - if (bflow->os_name) - break; /* just find the first */ - } else if (!strcmp("menu", tok)) { - tok = strsep(&p, " "); - if (!strcmp("label", tok)) { - name = p; - } - } - if (name) { - free(bflow->os_name); - bflow->os_name = strdup(name); - if (!bflow->os_name) - return log_msg_ret("os", -ENOMEM); - } + addr = map_to_sysmem(bflow->buf); + ctx = pxe_parse(addr, bflow->size, bflow->fname); + if (!ctx) + return log_msg_ret("prs", -EINVAL); + + if (list_empty(&ctx->cfg->labels)) { + pxe_cleanup(ctx); + return log_msg_ret("lab", -ENOENT); + } + + label = list_first_entry(&ctx->cfg->labels, struct pxe_label, list); + name = label->menu ? label->menu : label->name; + if (name) { + bflow->os_name = strdup(name); + if (!bflow->os_name) { + pxe_cleanup(ctx); + return log_msg_ret("os", -ENOMEM); } } + pxe_cleanup(ctx); + return 0; } From patchwork Tue Mar 24 22:18:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2048 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390783; bh=YC5f6iC88O1SbFdX7s7Ss9CFbqL3PF/gouE7EqDMrNk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=EukvSGFDCFq6zi0tLisb0fKYiSsHs7oJ5Xl7sNP8A3CV4QbngV6DHLFcRIrU9d1WM yjszoA/tuj4OO2U8lvwkl6DR72/xLCKUweF1DE5bQB/nBSDpK162q4WxsjHxm3eVvv fJUygJD66YQfGmx5LqYJ/RncIirrlN7aDzGvc60Qa0h7z96zrnarRGC0KbnLi3RuIo szLyPOq0Wc6hYL1iudx6V6b09HjMHgVxnag2oYdGyaPAN8p7gOVzhz+uX2krTlvTLo VzLQpB/1eazs9Nm0INbY/HPPdNyKEgT2t7G9pp1240JgMPU3aeahW98WgocOCYdbAl iGGPzeQP1mQwA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 889BF6A24E for ; Tue, 24 Mar 2026 16:19:43 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id bt0zbk3pGeQE for ; Tue, 24 Mar 2026 16:19:43 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390780; bh=YC5f6iC88O1SbFdX7s7Ss9CFbqL3PF/gouE7EqDMrNk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=U2sweZwouzIMMi+WTIg+R+HVchF18y4I7W2240WJnBrPIOfKUXFT4bQcseK12lJqw bxSfFY4fynW6KoSgMhNYpiYMVHQqmZ2f1ZKLnSdCs7i9ubdMjGa1sGvmPu03o6K4ly Lf8rRdvczljvxD6bZ3Rla+rpr98VmA+YP0p87gox3EfOtA1CcsNI3v/ZWdxbKhD4kL dj2+kFTgiYn5QfSXZGpOGdDSvzOJuiOC9cjgxEFi9OFKYWpKKybVeax1QXoqVC+Hzq 82Y987U4eqy4U5074KX7JlTTksBkQVjmc8r+KIpiamwY5HlEmCZQFab3MVfcIRtc3c 4xgwprQ5MHteg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id B4FF86A23D for ; Tue, 24 Mar 2026 16:19:40 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390778; bh=GPPcklN4FFMZGa50whl6I1E8q85tthRDefoIlFiG0Bo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HcRBEH7U3otb308bb6ei9aAERj+7ftC4jpIOyEgj2kJckedwEqd0ahWlnjEBimrTr AdUVwmTIWLqE/IzR263/kTkwuVakKElMZ7LBtQZMFS6ey9+CviXICM0BQ9rvrqHHe/ qwZaPa2Kuk5Wn3mvkI+IMb1XsgWci+3O5s5dgrWIx/YX/9urlJ6HeEYRyjoWR5DH5w Q0pDjbwiLnTlerx7Gy+Ou7AeT0YEWS9DYFlo2dm/ghGEDhgIpRGvqUnAbzBTKsHJ7N LNoqc1Tys1TpJgEEK9NjD6jR5IhdtUQiE8KtlY8lElf9bN0A9EIxypL3sSbG1bUkzg 7lvk5ckrIP3zQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id E8EBA6A238; Tue, 24 Mar 2026 16:19:38 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id JRq3Tmdvk1U7; Tue, 24 Mar 2026 16:19:38 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390776; bh=u52wqrIU6pcHiQqMgXTd2BIvgNnrfE3qVkt0K9zdNZo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R5GsDyGfmad5ECIfadctC2tgIVFql76139ViSUirawr+NPmMqOQ6tNrG4mDC+YtXl XirTHDiWkkjNq8xW8HNxjMAD6bkwdFBOvCQF/Saz1eqh6UpqCkdq6+RrrYhCcOvdvW NrG6epOY2LAlqTc1pxu3bz90i0R1/frSB5iEg71atztG9gLRe25U4+yKIi0vZYTwml BHOZVG/rMPZ+HJ3an5ko7L+49MWvbqFg2M2mfaLAgqK7Gi5IvCTcPvMPwVgDecMkd3 vxsKKcwSIuU402+LaFswIUEO9hEyNuMNCHX468AyOLThwbe6Ow8dGHxdTaSA3vEVpM tDHDPQDb8CpJQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id A0FBD6A243; Tue, 24 Mar 2026 16:19:36 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:18:56 -0600 Message-ID: <20260324221911.3678307-3-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 2FNGGP2IKYXRLUDTRM7QJ3XNKSCPUHLB X-Message-ID-Hash: 2FNGGP2IKYXRLUDTRM7QJ3XNKSCPUHLB X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 02/12] bootstd: Add BOOTMETHF_MULTI for multi-entry bootmeths List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Some bootmeths can produce multiple bootflows from a single partition. For example, an extlinux config file may define several labels, each representing a different kernel to boot. Add a BOOTMETHF_MULTI flag that bootmeths can set to indicate this capability. When set, the iterator tries incrementing entry indices before advancing to the next bootmeth. The read_bootflow() op receives the entry index via bflow->entry and returns -ENOENT when no more entries are available. Add an 'entry' field to both struct bootflow and struct bootflow_iter to track the entry index. The entry is copied from the iterator to the bootflow in bootdev_get_bootflow() so the bootmeth can see which entry is being requested. Signed-off-by: Simon Glass --- boot/bootdev-uclass.c | 1 + boot/bootflow.c | 17 +++++++++++++++++ include/bootflow.h | 6 ++++++ include/bootmeth.h | 5 +++++ 4 files changed, 29 insertions(+) diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index f0f5912b582..72f9a315c04 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -574,6 +574,7 @@ int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter, log_debug("->get_bootflow %s,%x=%p\n", dev->name, iter->part, ops->get_bootflow); bootflow_init(bflow, dev, iter->method); + bflow->entry = iter->entry; if (!ops->get_bootflow) return default_get_bootflow(dev, iter, bflow); diff --git a/boot/bootflow.c b/boot/bootflow.c index dbda50b8231..d44ba65c1a9 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -364,6 +364,23 @@ static int iter_incr(struct bootflow_iter *iter) return BF_NO_MORE_DEVICES; } + /* + * If the current method supports multiple entries and the last call + * succeeded, try the next entry before advancing the method + */ + if (iter->method && !iter->err) { + struct bootmeth_uc_plat *ucp; + + ucp = dev_get_uclass_plat(iter->method); + if (ucp->flags & BOOTMETHF_MULTI) { + iter->entry++; + log_debug("-> next entry %d for method '%s'\n", + iter->entry, iter->method->name); + return 0; + } + } + iter->entry = 0; + /* Get the next boothmethod */ for (iter->cur_method++; iter->cur_method < iter->num_methods; iter->cur_method++) { diff --git a/include/bootflow.h b/include/bootflow.h index dbdbca96596..2a4a96c1031 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -75,6 +75,9 @@ enum bootflow_flags_t { * @blk: Block device which contains this bootflow, NULL if this is a network * device or sandbox 'host' device * @part: Partition number (0 for whole device) + * @entry: Entry index within this (dev, part, method) combination. Used by + * bootmeths with BOOTMETHF_MULTI to select which entry to return (e.g. + * which label in an extlinux config). Always 0 for non-multi bootmeths. * @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0. * For example, the sandbox host-filesystem bootdev sets this to * FS_TYPE_SANDBOX @@ -110,6 +113,7 @@ struct bootflow { struct udevice *dev; struct udevice *blk; int part; + int entry; int fs_type; struct udevice *method; char *name; @@ -266,6 +270,7 @@ enum { * @dev: Current bootdev, NULL if none. This is only ever updated in * bootflow_iter_set_dev() * @part: Current partition number (0 for whole device) + * @entry: Current entry index for BOOTMETHF_MULTI bootmeths, else 0 * @method: Current bootmeth * @max_part: Maximum hardware partition number in @dev, 0 if there is no * partition table @@ -300,6 +305,7 @@ struct bootflow_iter { int flags; struct udevice *dev; int part; + int entry; struct udevice *method; int max_part; int first_bootable; diff --git a/include/bootmeth.h b/include/bootmeth.h index 2cc8b690bbf..997dc762370 100644 --- a/include/bootmeth.h +++ b/include/bootmeth.h @@ -19,10 +19,15 @@ struct udevice; * @BOOTMETHF_GLOBAL: bootmeth handles bootdev selection automatically * @BOOTMETHF_ANY_PART: bootmeth is willing to check any partition, even if it * has no filesystem + * @BOOTMETHF_MULTI: bootmeth can produce multiple bootflows from a single + * partition (e.g. extlinux with several labels). The read_bootflow() op should + * check bflow->entry to select which entry to return, and return -ENOENT + * when the index exceeds available entries. */ enum bootmeth_flags { BOOTMETHF_GLOBAL = BIT(0), BOOTMETHF_ANY_PART = BIT(1), + BOOTMETHF_MULTI = BIT(2), }; /** From patchwork Tue Mar 24 22:18:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2050 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390784; bh=8mjqbk2GYrsZoz4Qun/aQHKZfCD5MteNzH2B/Bjkt7g=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Om4y0PZuLYbti5N9CahGwvVLo7WOXNRBEcoXnQ4+f45QDnLWnUPaYcmH23+5wS4a4 6uqJDfY4aQa7X7DECvKDFVDj7hjfVBwHYk3b8QR66cXPsCxSymnp7apoQSR+1E9+Kw m0EcKje4VqFjmgukrD3/rCHJwpS7KFWAc+25l1s7/6o/ffn21mL3XxIOH4hcAZL0yP n6qLn+2pHAKWFVrlhALb95NJIneFlevDr7EXddYEszSKeNg5qaNpDixTwm8RbCS05l K1uyImcm5z3VnRcojjcq4vuOXjAHWq/lfqKTslGKj/SbqxRlFfk1zQPm5HMGS3or+z BVPHsFh1WqHhQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AB9D26A24D for ; Tue, 24 Mar 2026 16:19:44 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id jrxf6EudSavp for ; Tue, 24 Mar 2026 16:19:44 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390783; bh=8mjqbk2GYrsZoz4Qun/aQHKZfCD5MteNzH2B/Bjkt7g=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Ghv7K5LT9UQZtYf7rJYPuts0jDDfrL+bcOx1DK93B+lV2MEiQWwBVPbxZRc7xFKdQ /2aqcqv9rxFGoONMRo7WGN98Jg00OtSOA60/Z5ilFMY94/ratsZKlrYZ2jBQgx6Upi ivaEWu+m+DHH6cizpTD4wHUR5v9JQPsoUjGoeeQZ6CKTndk/PRDVuhBfx2p36PGWDr dYL6aLlTgaoxzM8Ontz4Ya+ewY4It+h6PNULZdnwf2IVo5e/VVw8O59qidkJ3yxHO/ 9gkg/QPZej1hSWboMwdjJ8mPfPsUbs+Cy5p9AF8gIwUaauN+nbL13lgY5C/ILLUSOA fArIXJ3qLXFVw== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id F0F916A1FD for ; Tue, 24 Mar 2026 16:19:43 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390781; bh=HeGNTKdCHB1DXOsbsAAhfIogH0qznl4TM5sVD2Zp1zg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l7d88qTUnEeDti3GkmT+s/zNZUn2I9e7EeGmfKX4F2+kI2nAajE21uSlZQkLXNAE+ WEhXD4ERxXrVbkSnP3HKtNVs7CZQJKXQ3c1on6ziZ+8ltD1Up6OYCcIYk1Zc3fpXIM Z60ZGsjE13m/B3EV2T7lVWLe2NjiTQk/G+nPpedd/hegxYNJjLuuvENSbbZ0UVWKC7 ugMrtPxjmyRHc3DiFT2abO4mLxlmFiMt2Se07lc1aX4T/KFLvgqXY9GdhkziiiIPx/ J3LgGBFk4Eot98fJXh7Dl3bxGeF2L+NPICk1oAulj2s3s4I/npbnFyISu5BTf6lNpl HnAgJpIaQvpmg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 736346A249; Tue, 24 Mar 2026 16:19:41 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id FpQwLQN31T8W; Tue, 24 Mar 2026 16:19:41 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390777; bh=Gg4FueBkXs3wTLsAEsyTn+OCd7NwWFJgOPUgy4KIW7M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O0CscG1KA4oWOpDdpsGNy1PCTM8UzQ5xg/bS56jSkHkt3P3IdwuSdx8/F8untoXFE 9HwGQtCXYa+eAfqgButSCLuNsNtHHTXqRzN1VRcn4n3AnwTnhSgZRHBUux6XTIb0Ie z37cExRSigygsnMtVLuNS8kspU4n1IkNHnyaMzUyshaMXjo9gqCmkne/XxMVribtOg 33tijMBHToGeJJV8zEmpINHDeWGWYWWwY1gDoKOXOC/fsBJ1Zz1KSlj2tfgGdJ5n7W XoYCKEd0bY09xm+ggteRPJ86HSU6D9dXYWfwRSvs12WWrv+rWLPOvtDbSF674AnIwK 9Ewq6ftX1WXEQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 6D2E46A1DD; Tue, 24 Mar 2026 16:19:37 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:18:57 -0600 Message-ID: <20260324221911.3678307-4-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: YP774K65OR5MP77RS7RLH6ZDYCFXJZRH X-Message-ID-Hash: YP774K65OR5MP77RS7RLH6ZDYCFXJZRH X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 03/12] extlinux: Enable multi-entry bootflow scanning List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Use the BOOTMETHF_MULTI flag to produce one bootflow per label in an extlinux configuration file. Adjust extlinux_fill_info() to walk to the Nth label based on bflow->entry, returning -ENOENT when the index exceeds the available labels. This allows bootflow scanning to discover all kernels defined in an extlinux config, rather than only exposing the first label. Signed-off-by: Simon Glass --- boot/bootmeth_extlinux.c | 29 ++++++++++++++++++++--------- test/boot/bootdev.c | 13 ++++++++++++- test/boot/bootflow.c | 33 ++++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index 3ffe21d96a3..bfc816f3628 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -117,11 +117,12 @@ static int extlinux_check_luks(struct bootflow *bflow) /** * extlinux_fill_info() - Decode the extlinux file to find out its info * - * Uses pxe_parse() to parse the configuration file and extract the first - * label's name to use as the bootflow OS name. + * Uses pxe_parse() to parse the configuration file and extract the label + * selected by @bflow->entry to use as the bootflow OS name. * - * @bflow: Bootflow to process - * Return: 0 if OK, -ve on error + * @bflow: Bootflow to process (entry selects which label) + * Return: 0 if OK, -ENOENT if entry index exceeds available labels, other + * -ve on error */ static int extlinux_fill_info(struct bootflow *bflow) { @@ -129,19 +130,28 @@ static int extlinux_fill_info(struct bootflow *bflow) struct pxe_label *label; const char *name; ulong addr; + int i; - log_debug("parsing bflow file size %x\n", bflow->size); + log_debug("parsing bflow file size %x entry %d\n", bflow->size, + bflow->entry); addr = map_to_sysmem(bflow->buf); ctx = pxe_parse(addr, bflow->size, bflow->fname); if (!ctx) return log_msg_ret("prs", -EINVAL); - if (list_empty(&ctx->cfg->labels)) { - pxe_cleanup(ctx); - return log_msg_ret("lab", -ENOENT); + /* Walk to the requested label */ + i = 0; + list_for_each_entry(label, &ctx->cfg->labels, list) { + if (i == bflow->entry) + goto found; + i++; } - label = list_first_entry(&ctx->cfg->labels, struct pxe_label, list); + /* No more entries at this index */ + pxe_cleanup(ctx); + return -ENOENT; + +found: name = label->menu ? label->menu : label->name; if (name) { bflow->os_name = strdup(name); @@ -267,6 +277,7 @@ static int extlinux_bootmeth_bind(struct udevice *dev) plat->desc = IS_ENABLED(CONFIG_BOOTSTD_FULL) ? "Extlinux boot from a block device" : "extlinux"; + plat->flags = BOOTMETHF_MULTI; return 0; } diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c index 81610563141..06ef695256e 100644 --- a/test/boot/bootdev.c +++ b/test/boot/bootdev.c @@ -228,6 +228,9 @@ static int bootdev_test_order(struct unit_test_state *uts) /* get the second usb device which has a backing file (flash3.img) */ ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + /* get the second entry from flash3 (Ubuntu has two extlinux labels) */ + ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); ut_asserteq(6, iter.num_devs); ut_asserteq_str("mmc1.bootdev", iter.dev_used[0]->name); @@ -269,10 +272,12 @@ static int bootdev_test_order(struct unit_test_state *uts) /* * Now scan past mmc1 and make sure that the 4 USB devices show up. The - * first two have a backing file so returns success + * first two have a backing file so returns success. flash3 has two + * extlinux labels so produces an extra bootflow. */ ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); ut_asserteq(7, iter.num_devs); ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); @@ -341,6 +346,9 @@ static int bootdev_test_prio(struct unit_test_state *uts) /* get the second usb device which has a backing file (flash3.img) */ ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + /* get the second entry from flash3 (Ubuntu has two extlinux labels) */ + ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); ut_asserteq(7, iter.num_devs); ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name); @@ -365,6 +373,9 @@ static int bootdev_test_prio(struct unit_test_state *uts) /* get the second usb device which has a backing file (flash3.img) */ ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + /* get the second entry from flash3 (Ubuntu has two extlinux labels) */ + ut_asserteq(0, bootflow_scan_next(&iter, &bflow)); + ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow)); ut_asserteq(9, iter.num_devs); ut_asserteq_str("hub1.p1.usb_mass_storage.lun0.bootdev", diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 3bea1cc6634..2e0cf5d309e 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -211,17 +211,20 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts) ut_assert_nextline(" 5 vbe media mmc 0 mmc1.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-2: No such file or directory"); ut_assert_nextline(" 6 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf"); + /* multi-entry tries entry 1 on extlinux (Fedora has one label) */ + ut_assert_nextline(" 7 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf"); + ut_assert_nextline(" ** Ready, err=-2: No such file or directory"); ut_assert_nextline( - " 7 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/%s", + " 8 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/%s", efi_get_basename()); ut_assert_skip_to_line("Scanning bootdev 'mmc0.bootdev':"); ut_assert_skip_to_line( - " 5f vbe media mmc 0 mmc0.bootdev.whole "); + " 60 vbe media mmc 0 mmc0.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported"); ut_assert_nextline("No more bootdevs"); ut_assert_nextlinen("---"); - ut_assert_nextline("(96 bootflows, 1 valid)"); + ut_assert_nextline("(97 bootflows, 1 valid)"); ut_assert_console_end(); ut_assertok(run_command("bootflow list", 0)); @@ -230,9 +233,9 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextline(" 0 extlinux media mmc 0 mmc2.bootdev.whole "); ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole "); - ut_assert_skip_to_line(" 5f vbe media mmc 0 mmc0.bootdev.whole "); + ut_assert_skip_to_line(" 60 vbe media mmc 0 mmc0.bootdev.whole "); ut_assert_nextlinen("---"); - ut_assert_nextline("(96 bootflows, 1 valid)"); + ut_assert_nextline("(97 bootflows, 2 valid)"); ut_assert_console_end(); return 0; @@ -406,6 +409,17 @@ static int bootflow_iter(struct unit_test_state *uts) ut_asserteq(BOOTFLOWST_READY, bflow.state); bootflow_free(&bflow); + /* + * With BOOTMETHF_MULTI, the iterator tries entry 1 on extlinux. + * Fedora has only one label, so entry 1 fails. Since BOOTFLOWIF_ALL + * is set, this failed attempt is returned. + */ + ut_asserteq(-ENOENT, bootflow_scan_next(&iter, &bflow)); + ut_asserteq(0, iter.cur_method); + ut_asserteq(1, iter.entry); + ut_asserteq(1, iter.part); + bootflow_free(&bflow); + ut_asserteq(-ENOENT, bootflow_scan_next(&iter, &bflow)); ut_asserteq(3, iter.num_methods); ut_asserteq(1, iter.cur_method); @@ -1435,8 +1449,10 @@ static int bootflow_efi(struct unit_test_state *uts) " 1 efi ready usb 1 hub1.p2.usb_mass_storage. /EFI/BOOT/BOOTSBOX.EFI"); ut_assert_nextlinen( " 2 extlinux ready usb 1 hub1.p4.usb_mass_storage. /extlinux/extlinux.conf"); + ut_assert_nextlinen( + " 3 extlinux ready usb 1 hub1.p4.usb_mass_storage. /extlinux/extlinux.conf"); ut_assert_nextlinen("---"); - ut_assert_skip_to_line("(3 bootflows, 3 valid)"); + ut_assert_skip_to_line("(4 bootflows, 4 valid)"); ut_assert_console_end(); ut_assertok(run_command("bootflow select 1", 0)); @@ -1812,8 +1828,11 @@ static int bootflow_cmd_info_encrypted(struct unit_test_state *uts) ut_assert_nextline( " 1 extlinux ready mmc 1 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf", IS_ENABLED(CONFIG_BLK_LUKS) ? 'E' : ' '); + ut_assert_nextline( + " 2 extlinux ready mmc 1 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf", + IS_ENABLED(CONFIG_BLK_LUKS) ? 'E' : ' '); ut_assert_nextline("--- ----------- ------ -------- ---- - ------------------------ ----------------"); - ut_assert_nextline("(2 bootflows, 2 valid)"); + ut_assert_nextline("(3 bootflows, 3 valid)"); ut_assert_console_end(); /* Select the mmc12 bootflow and check info shows encryption */ From patchwork Tue Mar 24 22:18:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2049 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390783; bh=UE1IofP+a+n9hGDAWC6PcDhpFuoJP5r6vNG7uM2KSqA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=eNAE5QUfTIlS/bV0ezMrSntJnJtDETir9BvEU8xAGsl757hYru7za81RhmF8nZmeP dT87ZTMm3UKfBgvhIwqI6mwkCtwlMLJIdXszW+uXoDYRsxC794uY3n7bp2ugbLlUKz khBsuPIQoyUj2qRMDzt0T205luSQmPzWTlb/GB53PyXNn9quGUrDoZT2ZncAV9ELSY iip95qvAGgYVh2UdTFiM6PjYMLCql0rUsE90ZS0PVHg+n51U0M9CPkdezWJgcv4xaS QDNad7JBBZ7mEajn8Jb17EnJByCZiEB8UmD88BiXdAOs17vsL/Ogb9whn35skcbLfX InYqcbWIZ7krA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id F34416A241 for ; Tue, 24 Mar 2026 16:19:43 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id NuQ4ns8AY8Pw for ; Tue, 24 Mar 2026 16:19:43 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390783; bh=UE1IofP+a+n9hGDAWC6PcDhpFuoJP5r6vNG7uM2KSqA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=eNAE5QUfTIlS/bV0ezMrSntJnJtDETir9BvEU8xAGsl757hYru7za81RhmF8nZmeP dT87ZTMm3UKfBgvhIwqI6mwkCtwlMLJIdXszW+uXoDYRsxC794uY3n7bp2ugbLlUKz khBsuPIQoyUj2qRMDzt0T205luSQmPzWTlb/GB53PyXNn9quGUrDoZT2ZncAV9ELSY iip95qvAGgYVh2UdTFiM6PjYMLCql0rUsE90ZS0PVHg+n51U0M9CPkdezWJgcv4xaS QDNad7JBBZ7mEajn8Jb17EnJByCZiEB8UmD88BiXdAOs17vsL/Ogb9whn35skcbLfX InYqcbWIZ7krA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 403B06A245 for ; Tue, 24 Mar 2026 16:19:43 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390781; bh=WegrlAni+psrClfL0uObm+f8b4PACjGbqmHKDvLXFxQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uo/edT3IpleMQTVkmLoWjgBW3XW43xTTkxzhXX2OTe7HDaC66CjkHeJ3IC78FmfQE o2qxdpvULElNd45FdWntJbHytNyXxgsNxCGYi4I46NmT979GU29QP4UkgeUrk+HCkb IBIirbUrNvivk4WJ6r+pkRLVF+ego0Gz+XK1rTKyJehsKDnKqyasa3a9HTTbNvX9Ti gx+C8Ap5Wv54hOxg6j2uMY1gHx8BhzJftcW5d4yWv3p0ZIqkIv69vb7N6r7fydkzVo +PVIT1pDmdPWE9waM7PeKNumjSrgy4hm2kgwY6bxDQsYdEoyKZPTFQuuNf4RzrEsg3 lGAvhDhCj/ZUw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 732906A245; Tue, 24 Mar 2026 16:19:41 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id DuA05lRc6Rv8; Tue, 24 Mar 2026 16:19:41 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390778; bh=n77OR55M+uKoTeJjB5ULx54+u53oB7DUuLPVv+0dmzc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e/nBeQMZetiQi3SxgE0wt7z5yjAIy9Ahh/fk0Vmhe7pMUsbRkpmCmkBDgvSCRmxHn aN6cEAyaHi1JkZ5DF5StqdbtgtHrJoiNUnjXt34ThAwVLoVKhRDc9hiG1m9534nzTE TbxBFlNeh7pCwYHvTNBeVhlHOLyTIO4rwjf1/nslrL3hVO73mT5t3DBUCcWvSYTnQr vbtADBl4QrP0LH4900+A1R5EpaVqm6vzU+ais/xoZs4fL0bOqvTdVCxaDeDBsl2jvw Pyt8yH711vev1kW3R8Ym+lkAzRBREs2PGyBLuGKKq5zd+YUnc1bViL8Ux3cpQxPRgf J97lVJNi9Bfiw== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 5A6436A1FD; Tue, 24 Mar 2026 16:19:38 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:18:58 -0600 Message-ID: <20260324221911.3678307-5-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: EYLTS4OW3LQM2ERFL7AYWMHLDQFPGXRT X-Message-ID-Hash: EYLTS4OW3LQM2ERFL7AYWMHLDQFPGXRT X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 04/12] test: bootstd: Add test for multi-entry bootflow scanning List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add a test that scans USB devices and verifies that the Ubuntu image on flash3 (which has two extlinux labels) produces two separate bootflows with the correct OS names. Signed-off-by: Simon Glass --- test/boot/bootflow.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 2e0cf5d309e..673bdbe33de 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -1899,3 +1899,57 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) return 0; } BOOTSTD_TEST(bootflow_cmd_bls, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); + +/* Test multi-entry scanning with the Ubuntu image on USB (two labels) */ +static int bootflow_multi(struct unit_test_state *uts) +{ + static const char *order[] = {"usb", NULL}; + struct bootstd_priv *std; + struct udevice *bootstd; + const char **old_order; + struct bootflow *bflow; + + test_set_eth_enable(false); + test_set_skip_delays(true); + + ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); + std = dev_get_priv(bootstd); + old_order = std->bootdev_order; + std->bootdev_order = order; + + bootstd_reset_usb(); + + ut_assertok(run_command("bootflow scan", 0)); + + /* Restore the order as soon as scanning is done */ + std->bootdev_order = old_order; + + ut_assert_skip_to_line("Bus usb@1: 6 USB Device(s) found"); + + ut_assertok(run_command("bootflow list", 0)); + ut_assert_nextlinen("Showing all"); + ut_assert_nextlinen("Seq"); + ut_assert_nextlinen("---"); + ut_assert_nextlinen( + " 0 efi ready usb 1 hub1.p2.usb_mass_storage."); + ut_assert_nextlinen( + " 1 extlinux ready usb 1 hub1.p4.usb_mass_storage."); + ut_assert_nextlinen( + " 2 extlinux ready usb 1 hub1.p4.usb_mass_storage."); + ut_assert_nextlinen("---"); + ut_assert_nextline("(3 bootflows, 3 valid)"); + ut_assert_console_end(); + + /* Check that the two extlinux entries have different OS names */ + bflow = alist_getw(&std->bootflows, 1, struct bootflow); + ut_asserteq_str("Ubuntu 25.04 6.8.0-53-generic", bflow->os_name); + ut_asserteq(0, bflow->entry); + + bflow = alist_getw(&std->bootflows, 2, struct bootflow); + ut_asserteq_str("Ubuntu 25.04 6.8.0-53-generic (rescue target)", + bflow->os_name); + ut_asserteq(1, bflow->entry); + + return 0; +} +BOOTSTD_TEST(bootflow_multi, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); From patchwork Tue Mar 24 22:18:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2051 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390789; bh=3FivoXkzDEC5vk1duYuw/yGPNORJOuNFyLqFNbLPk1E=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=eVfhfwqfRuQEIlpI56jZNBBMXVV0zh/rAyHVZ1v4k7UjMrxjwe2vslG6orQ6WW6zb E+T/fuBTqnAFfnOmQP9hem9iRSLISfRC7kx3Wq2bZBZCyg9K+TNjL7DvH4oefywg8O QZZOi7a8bYaYrhBeAhZGFAP4z1+UevYOT1K1r5/9YyUWRflC8v5O+QjJ2OZZqZDKVo zyAKhuMGHTzV8m8BhB16emOzDL5qepoH+2i7w/TBGNvfXh0BMYouY8q+Tkmx9WdhIR EdC4g31hRE/9u3YNWf0Sytd/KcYHXmAeHdtw2dpeWahRObFANnZMvJUQ3MctgDYC49 j+Yo7b7Uo5Okg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 8703F6A238 for ; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id jTa14Kk2Ndx1 for ; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390789; bh=3FivoXkzDEC5vk1duYuw/yGPNORJOuNFyLqFNbLPk1E=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=eVfhfwqfRuQEIlpI56jZNBBMXVV0zh/rAyHVZ1v4k7UjMrxjwe2vslG6orQ6WW6zb E+T/fuBTqnAFfnOmQP9hem9iRSLISfRC7kx3Wq2bZBZCyg9K+TNjL7DvH4oefywg8O QZZOi7a8bYaYrhBeAhZGFAP4z1+UevYOT1K1r5/9YyUWRflC8v5O+QjJ2OZZqZDKVo zyAKhuMGHTzV8m8BhB16emOzDL5qepoH+2i7w/TBGNvfXh0BMYouY8q+Tkmx9WdhIR EdC4g31hRE/9u3YNWf0Sytd/KcYHXmAeHdtw2dpeWahRObFANnZMvJUQ3MctgDYC49 j+Yo7b7Uo5Okg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3EB816A228 for ; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390787; bh=Ou94pT80H6m4OYNTv2OHznYnCdeo0+Cg4QZlzcW4kg8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oze/NIi3M9ReUwN5QR0jpsLjMpJ5a5JZX9zjKOlEvoIkNsWru0bzrRMoccmZH5m+i BbQYQ3/BHjLIBnSyqixiJH2t+iRAhhJUqUnBPFnFYcl2m2I0rU3AxiGyBe3161ztOO D2CXgAYGT42+abDOHfEDkyzHvyDJDoRMUrTXPU85pPSC//zQccpQ9zwqtZ9GzGfcrC CX1jfuRU/TALbqfC4QjhxN2LtWGRjhlmoJbDvY7ZPmaPnSjhcG93n+5YVtECLSfqXu 3HNW4tAy1zW7In08yqGCKwnqx1y2ZWD1b+9Ikj0KE9b6527RKLGWRpuSr6ECHaLzL6 UIKepqj7xcn4w== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 372DA6A23D; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id qg-y81yimrSR; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390779; bh=dvQSGQ/0lztgSvw27eQ1VrL1MVokOC95NbOAt5E6B70=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IdCCK9tVgNVcBvcYMjGHTcST48Ww69FPPu27ZxaI+GIcAzVQ+/Nw+6BLjfpw2SPvI H0bjQyHClxVFe7P7DyC/eI4u4DJlTIDsEI4TOfdMjaYCwxnaouCNNXkppo+xUVsHdY bJ32RmsYr8GgTv1qDWh8QHiZ04LTe4wWevAqvKOhTgR7F0RWlTGzdmpgeLhNuGb807 r+mI1iVy4zvrWBjXx/Ui9ZQEnrph9DBxC/W+wHnoGyiA7gqcMPz7IyRj0deiXWtzDA O0O2GU2BUWyPCvS1xXu+Qh0Uyes2FT1ggtuEt7jPoLbg7Zum0MtkH+Dp0K9045smDh 7f6F+XPP7iAlQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 165C26A248; Tue, 24 Mar 2026 16:19:39 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:18:59 -0600 Message-ID: <20260324221911.3678307-6-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: GBDNNXIOKKDM6VOILOTSG2VYKKZNATDA X-Message-ID-Hash: GBDNNXIOKKDM6VOILOTSG2VYKKZNATDA X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 05/12] bls: Enable multi-entry bootflow scanning List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Update the BLS bootmeth to support multiple entry files in the loader/entries/ directory. Pass bflow->entry to bls_scan_entries_dir() so it returns the Nth .conf file, and set BOOTMETHF_MULTI so the iterator produces one bootflow per entry file. Only fall back to the single loader/entry.conf path for entry 0, since that path cannot produce multiple bootflows. Update the test image to place two BLS entries in loader/entries/ and verify that both appear as separate bootflows with correct OS names. Signed-off-by: Simon Glass --- boot/bootmeth_bls.c | 106 +++++++++++++++++++++++++++++++++++++++---- test/boot/bootflow.c | 20 ++++++-- test/py/img/bls.py | 24 +++++++--- 3 files changed, 130 insertions(+), 20 deletions(-) diff --git a/boot/bootmeth_bls.c b/boot/bootmeth_bls.c index 13353906fff..fc9c1bb70a2 100644 --- a/boot/bootmeth_bls.c +++ b/boot/bootmeth_bls.c @@ -9,7 +9,8 @@ * https://uapi-group.org/specifications/specs/boot_loader_specification/ * * Supported features: - * - Single BLS entry file at loader/entry.conf + * - Scans loader/entries/ directory for .conf files + * - Falls back to single loader/entry.conf if no entries/ directory * - Fields: title, version, linux, options, initrd, devicetree * - Multiple options lines (concatenated with spaces) * - Multiple initrd lines (only first used, PXE limitation) @@ -17,7 +18,7 @@ * - Zero-copy parsing (fields point into bootflow buffer) * * Current limitations: - * - Single entry file only, not multiple entries in loader/entries/ + * - Only the first entry file in loader/entries/ is used * - Only first initrd used (PXE infrastructure supports one) * - No devicetree-overlay support * - No architecture/machine-id filtering @@ -34,6 +35,8 @@ #include #include #include +#include +#include #include #include #include @@ -41,7 +44,8 @@ #include #include -/* Single BLS entry file to check */ +/* BLS entry directory and fallback single file */ +#define BLS_ENTRIES_DIR "loader/entries" #define BLS_ENTRY_FILE "loader/entry.conf" /** @@ -117,10 +121,12 @@ static int bls_to_pxe_label(struct bootflow *bflow, INIT_LIST_HEAD(&label->list); alist_init_struct(&label->files, struct pxe_file); + alist_init_struct(&label->initrds, char *); + label->name = strdup(""); label->menu = strdup(bflow->os_name ?: ""); label->append = strdup(bflow->cmdline ?: ""); - if (!label->menu || !label->append) { + if (!label->name || !label->menu || !label->append) { ret = -ENOMEM; goto err; } @@ -137,10 +143,12 @@ static int bls_to_pxe_label(struct bootflow *bflow, switch ((int)img->type) { case IH_TYPE_KERNEL: - if (!label->kernel) + if (!label->kernel) { label->kernel = fname; - else + label->kernel_label = strdup(fname); + } else { free(fname); + } break; case IH_TYPE_RAMDISK: if (!alist_add(&label->initrds, fname)) { @@ -231,6 +239,59 @@ static int bls_entry_init(struct bls_entry *entry, struct bootflow *bflow, return 0; } +/** + * bls_scan_entries_dir() - Scan loader/entries/ for a .conf file + * + * Looks for the Nth .conf file in the BLS entries directory, where N is + * given by @entry. The filesystem must already be set up for the partition. + * + * @prefix: Prefix to prepend to the directory path (e.g. "/boot") + * @entry: Entry index (0 for first .conf file, 1 for second, etc.) + * @fname: Buffer to store the full path of the found entry + * @fname_size: Size of @fname buffer + * Return: 0 on success, -ENOENT if no more entries + */ +static int bls_scan_entries_dir(const char *prefix, int entry, char *fname, + int fname_size) +{ + struct fs_dir_stream *dirs; + struct fs_dirent *dent; + char dirpath[200]; + int ret = -ENOENT; + int found = 0; + + snprintf(dirpath, sizeof(dirpath), "%s%s", prefix ? prefix : "", + BLS_ENTRIES_DIR); + log_debug("BLS: scanning dir %s entry %d\n", dirpath, entry); + + dirs = fs_opendir(dirpath); + if (!dirs) + return log_msg_ret("opn", -ENOENT); + + while ((dent = fs_readdir(dirs))) { + int len; + + if (dent->type != FS_DT_REG) + continue; + len = strlen(dent->name); + if (len < 6 || strcmp(dent->name + len - 5, ".conf")) + continue; + + if (found == entry) { + snprintf(fname, fname_size, "%s%s/%s", + prefix ? prefix : "", BLS_ENTRIES_DIR, + dent->name); + log_debug("BLS: found entry %s\n", fname); + ret = 0; + break; + } + found++; + } + fs_closedir(dirs); + + return ret; +} + static int bls_read_bootflow(struct udevice *dev, struct bootflow *bflow) { struct bls_entry entry; @@ -259,13 +320,33 @@ static int bls_read_bootflow(struct udevice *dev, struct bootflow *bflow) prefixes = bootstd_get_prefixes(bootstd); desc = bflow->blk ? dev_get_uclass_plat(bflow->blk) : NULL; - /* Try each prefix to find the BLS entry file */ + /* Try each prefix: first scan entries/, then fall back to entry.conf */ i = 0; + ret = -ENOENT; do { + char fname[200]; + prefix = prefixes ? prefixes[i] : NULL; log_debug("trying prefix %s\n", prefix); - ret = bootmeth_try_file(bflow, desc, prefix, BLS_ENTRY_FILE); + ret = bootmeth_setup_fs(bflow, desc); + if (ret) + return log_msg_ret("bfs", ret); + + if (!bls_scan_entries_dir(prefix, bflow->entry, fname, + sizeof(fname))) { + /* fs_closedir() closes the fs, so re-open it */ + ret = bootmeth_setup_fs(bflow, desc); + if (!ret) + ret = bootmeth_try_file(bflow, desc, NULL, + fname); + } else if (!bflow->entry) { + /* fs_opendir() closes the fs, so re-open it */ + ret = bootmeth_setup_fs(bflow, desc); + if (!ret) + ret = bootmeth_try_file(bflow, desc, prefix, + BLS_ENTRY_FILE); + } } while (ret && prefixes && prefixes[++i]); if (ret) { @@ -306,8 +387,8 @@ static int bls_load_files(struct udevice *dev, struct bootflow *bflow, bool already_loaded; int ret; - /* Check if files are already loaded (first image has address) */ - first_img = alist_get(&bflow->images, 0, struct bootflow_img); + /* Check if kernel is already loaded (skip the BLS config image) */ + first_img = alist_get(&bflow->images, 1, struct bootflow_img); already_loaded = first_img && first_img->addr; /* Set up PXE context */ @@ -410,6 +491,10 @@ static int bls_boot(struct udevice *dev, struct bootflow *bflow) if (ret) return ret; + /* Set bootargs from BLS options before booting */ + if (label->append) + env_set("bootargs", label->append); + /* Boot the label */ pxe_ctx.label = label; ret = pxe_boot(&pxe_ctx); @@ -427,6 +512,7 @@ static int bls_bootmeth_bind(struct udevice *dev) plat->desc = IS_ENABLED(CONFIG_BOOTSTD_FULL) ? "Boot Loader Specification (BLS) Type #1" : "bls"; + plat->flags = BOOTMETHF_MULTI; return 0; } diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 673bdbe33de..73ea1102af5 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -1874,12 +1874,13 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) ut_assert_nextline("Seq Method State Uclass Part E Name Filename"); ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); - ut_assert_nextline(" 1 bls ready mmc 1 mmc15.bootdev.part_1 /loader/entry.conf"); + ut_assert_nextline(" 1 bls ready mmc 1 mmc15.bootdev.part_1 /loader/entries/6.8.0.conf"); + ut_assert_nextline(" 2 bls ready mmc 1 mmc15.bootdev.part_1 /loader/entries/6.8.0-rescue.conf"); ut_assert_nextlinen("---"); - ut_assert_nextline("(2 bootflows, 2 valid)"); + ut_assert_nextline("(3 bootflows, 3 valid)"); ut_assert_console_end(); - /* Select the BLS bootflow and check info */ + /* Select the first BLS bootflow and check info */ ut_assertok(run_command("bootflow select 1", 0)); ut_assert_console_end(); ut_assertok(run_command("bootflow info", 0)); @@ -1892,7 +1893,18 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: no"); ut_assert_nextline("Subdir: (none)"); - ut_assert_nextline("Filename: /loader/entry.conf"); + ut_assert_nextline("Filename: /loader/entries/6.8.0.conf"); + ut_assert_skip_to_line("OS: Test Boot"); + ut_assert_skip_to_line("Error: 0"); + ut_assert_console_end(); + + /* Select the second BLS bootflow and check info */ + ut_assertok(run_command("bootflow select 2", 0)); + ut_assert_console_end(); + ut_assertok(run_command("bootflow info", 0)); + ut_assert_nextline("Name: mmc15.bootdev.part_1"); + ut_assert_skip_to_line("Filename: /loader/entries/6.8.0-rescue.conf"); + ut_assert_skip_to_line("OS: Rescue Boot"); ut_assert_skip_to_line("Error: 0"); ut_assert_console_end(); diff --git a/test/py/img/bls.py b/test/py/img/bls.py index 0f55aad8ba5..3cf6ee21cd6 100644 --- a/test/py/img/bls.py +++ b/test/py/img/bls.py @@ -25,24 +25,36 @@ def setup_bls_image(config, log, devnum, basename): dtb = 'sandbox.dtb' # BLS Type #1 entry format - script = f'''title Test Boot + entry1 = f'''title Test Boot version 6.8.0 linux /{vmlinux} options root=/dev/mmcblk0p2 ro quiet initrd /{initrd} +devicetree /{dtb}''' + + entry2 = f'''title Rescue Boot +version 6.8.0-rescue +linux /{vmlinux} +options root=/dev/mmcblk0p2 ro quiet single +initrd /{initrd} devicetree /{dtb}''' fsh = FsHelper(config, 'vfat', 18, prefix=basename) fsh.setup() - # Create loader directory for BLS entry + # Create loader/entries directory for BLS entries loader = os.path.join(fsh.srcdir, 'loader') mkdir_cond(loader) + entries = os.path.join(loader, 'entries') + mkdir_cond(entries) - # Create BLS entry file - conf = os.path.join(loader, 'entry.conf') - with open(conf, 'w', encoding='ascii') as fd: - print(script, file=fd) + # Create two BLS entry files + with open(os.path.join(entries, '6.8.0.conf'), 'w', + encoding='ascii') as fd: + print(entry1, file=fd) + with open(os.path.join(entries, '6.8.0-rescue.conf'), 'w', + encoding='ascii') as fd: + print(entry2, file=fd) # Create compressed kernel image inf = os.path.join(config.persistent_data_dir, 'inf') From patchwork Tue Mar 24 22:19:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2052 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390790; bh=w4lzqRxRDMg3DPc85i1etscslmNvPNkZaQYfHb1orQo=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=F+SfdaLGsplyuTTYyIuS5klEOkVePtlEtTDZZZbEt6zTJ1lFqGVScHgs9vOhOseNB Ld2OxIpmod2phya1tBTllmZrk/r5wG8HHfQd5MTnLR1EQuNHNp43Pb6+fRnIagpt+l /L4Yv7q9cp7LRTR0tMV20hC5S/Usi4GfnxcBSVOUUMJ7P6wMWjz8rOP7M0iscSAJpH DkTeVKO3JDvyS9szLZDmnSvzCXiNSKUi3ba4wsQnBosN+ugrIE7lnqBIiujJ2Ei+HF s3LcOXDPm3sgB1ws/4+9Fpe6c3XG/E08mid5LC8m+a4LsCCNs8EykpxQZIed/hgbGZ fE48MN2qYBfkg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 25D756A228 for ; Tue, 24 Mar 2026 16:19:50 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id lyXrQjj2_Es5 for ; Tue, 24 Mar 2026 16:19:50 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390790; bh=w4lzqRxRDMg3DPc85i1etscslmNvPNkZaQYfHb1orQo=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=F+SfdaLGsplyuTTYyIuS5klEOkVePtlEtTDZZZbEt6zTJ1lFqGVScHgs9vOhOseNB Ld2OxIpmod2phya1tBTllmZrk/r5wG8HHfQd5MTnLR1EQuNHNp43Pb6+fRnIagpt+l /L4Yv7q9cp7LRTR0tMV20hC5S/Usi4GfnxcBSVOUUMJ7P6wMWjz8rOP7M0iscSAJpH DkTeVKO3JDvyS9szLZDmnSvzCXiNSKUi3ba4wsQnBosN+ugrIE7lnqBIiujJ2Ei+HF s3LcOXDPm3sgB1ws/4+9Fpe6c3XG/E08mid5LC8m+a4LsCCNs8EykpxQZIed/hgbGZ fE48MN2qYBfkg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0D9986A23D for ; Tue, 24 Mar 2026 16:19:50 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390787; bh=VH89sRX5OMUW6+eAv452hkO4wjNfc+vAyclWEQ9bYBk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W98wGCWr+6pV2Y1iMrC8+Y5w4ZOPGJVMTYrI7j6Bo0NMc2qliE3ZyZM+c7qyFCvae wsAhL1JJTBzCAVwqP1xu0mpDpF1drXDi1XqPOunuKjYAM6TSe7NfRYBWLklEPLv9vi hCco7qNrRrlv7Xss31SoR7SXagBcGmtyeaNLs790xH0yer3x+9qEfFmwzOpCJzYK9L DNY5fwdqkle64vnFgdOiz+KCbcz8cVPhGH3fCL+d6cEI8YshzQbLsS146dJegg7ha4 31QXoI5QTlUS9FhK+TiSlQmQ7OA2xGKLQxWw9TPWwpZ0hu+XeCRy4KlplgaWZd1G/t KvP7w0YDmTE7A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3EC746A23E; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id 9eDC3o7Hs0eV; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390783; bh=Qhx3nnT0VQyiGKh8nhIbVcdzGTczWWzVzArpgqcEZ8c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=peR3aBFnB8B06y5NcaxcAW+PIEEw7/OwSEFJvb4Qqjruw8oDuvUVuL7af9nHy9DcN yVW1fQpKIlQQJKpkvtRbf0XWuPKnHG5ZW80l/GV761dRtM0R9ouj0YBJsk5Q87rYfk hCnBnQ9/j2qcNtgTW2mxzTVM7UOqSGnlF4zsqwALweEvTjAwnJ2qsfwtmxRCHnBv8r 85LaiuvhVAO27ZAqCH6lAfA4TaOiup1njKHDwc/vtWg2RFqxIukpBZF4JcLQ+YHxuy 4rIlm9t8UXpiNaxHUgCM6h+IBTBTnZb92x6ghZOWMXPnGBkT/W4ATiA7nQQj8nWBSR 3302LXvT73GNw== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id D77D56A1DD; Tue, 24 Mar 2026 16:19:42 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:00 -0600 Message-ID: <20260324221911.3678307-7-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: SC7VAIDZ6JRQ65GXBSFG5KWEN7BNZR6S X-Message-ID-Hash: SC7VAIDZ6JRQ65GXBSFG5KWEN7BNZR6S X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 06/12] pxe: Add pxe_boot_entry() to boot a specific label by index List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add pxe_boot_entry() which parses a PXE config, walks to the Nth label, loads its files and boots it. This is used by multi-entry bootmeths to boot the specific label that was selected during scanning, rather than presenting the full menu. Update extlinux_boot() to always use pxe_boot_entry(), so that each entry (including entry 0) boots its label directly without a menu. Signed-off-by: Simon Glass --- boot/ext_pxe_common.c | 3 ++- boot/pxe_utils.c | 30 ++++++++++++++++++++++++++++++ include/pxe_utils.h | 14 ++++++++++++++ test/boot/bootflow.c | 6 ++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/boot/ext_pxe_common.c b/boot/ext_pxe_common.c index 8a59b29ead8..4ea7f8f455d 100644 --- a/boot/ext_pxe_common.c +++ b/boot/ext_pxe_common.c @@ -136,7 +136,8 @@ int extlinux_boot(struct udevice *dev, struct bootflow *bflow, return log_msg_ret("elb", ret); ctx->restart = restart; addr = map_to_sysmem(bflow->buf); - ret = pxe_process_str(ctx, addr, false); + + ret = pxe_boot_entry(ctx, addr, bflow->entry); } if (ret) return log_msg_ret("elb", -EFAULT); diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index f5f8e38de2e..a7c5e87bef0 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -1510,3 +1510,33 @@ int pxe_boot(struct pxe_context *ctx) return 0; } + +int pxe_boot_entry(struct pxe_context *ctx, ulong addr, int entry) +{ + struct pxe_label *label; + struct pxe_menu *cfg; + int ret, i = 0; + void *ptr; + + ptr = map_sysmem(addr, 0); + ctx->pxe_file_size = strnlen(ptr, SZ_64K); + unmap_sysmem(ptr); + + cfg = pxe_prepare(ctx, addr, false); + if (!cfg) + return log_msg_ret("prp", -EINVAL); + + list_for_each_entry(label, &cfg->labels, list) { + if (i == entry) + goto found; + i++; + } + pxe_menu_uninit(cfg); + return log_msg_ret("lab", -ENOENT); + +found: + ret = label_boot(ctx, label); + pxe_menu_uninit(cfg); + + return ret; +} diff --git a/include/pxe_utils.h b/include/pxe_utils.h index 3367230eb1c..8b607095721 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -611,4 +611,18 @@ void pxe_load(struct pxe_file *file, ulong addr, ulong size); */ void pxe_cleanup(struct pxe_context *ctx); +/** + * pxe_boot_entry() - Parse a PXE config and boot a specific entry by index + * + * This parses the config file, walks to the Nth label, loads its files and + * boots it. Used by multi-entry bootmeths to boot a specific label that was + * selected during scanning. + * + * @ctx: PXE context (must be set up with pxe_setup_ctx()) + * @addr: Address where config file is loaded + * @entry: Entry index (0 for first label, 1 for second, etc.) + * Return: Does not return on success, -ve on error + */ +int pxe_boot_entry(struct pxe_context *ctx, ulong addr, int entry); + #endif /* __PXE_UTILS_H */ diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 73ea1102af5..2ff203c186c 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -1962,6 +1962,12 @@ static int bootflow_multi(struct unit_test_state *uts) bflow->os_name); ut_asserteq(1, bflow->entry); + /* Try booting the second entry (rescue) - exercises pxe_boot_entry() */ + ut_assertok(env_set("kernel_addr_r", "1000000")); + ut_assertok(env_set("ramdisk_addr_r", "2000000")); + std->cur_bootflow = bflow; + ut_asserteq(-EFAULT, bootflow_boot(bflow)); + return 0; } BOOTSTD_TEST(bootflow_multi, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); From patchwork Tue Mar 24 22:19:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2053 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390791; bh=ugo+ZI/8Ti/34eHFF0npjbL8weS9k49CqLJoRsTQc44=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=CAn6kA7UlTZ+QRP8Jf8s5jVFY4ylMu0h8/t7yomVH2/BIhCKuioKFMfI/WP1lyzPe 3ax0VoBJY4NxjupUMgKQDbozJhUYoI7kdH+A6l6KJv5bFJO1ZuZfHF5Nc3wGchS5cr 6iQWopvjh8YE7rE/soLuDO2Hs/NdkZb5EK8RzdHHuX5mY7VQHHJLCqpcUqvBMI4XyQ pC0OGrAcSrLVyd4WFWsJf/NzFhBA1LX2XjnVIdvpAprAFZHp65++PwNxYdGTk3ZsHq HGE8oZDT5Qx2yGPLfALY69H+uEx1RWZpB3yVEjIP0H+SLIYqTfgEZJ36VlsEmlj97Z Ns3u1EQc7d9RQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D03636A254 for ; Tue, 24 Mar 2026 16:19:51 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id OFvARsoS3082 for ; Tue, 24 Mar 2026 16:19:51 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390790; bh=ugo+ZI/8Ti/34eHFF0npjbL8weS9k49CqLJoRsTQc44=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=uq7jbJjIFXCURzAa2OBJSL//FIVWcheQLsCP09dNaAuihWymxe4p0nDXzaqdyrxIY jj1HD3Vd9jojQjXgjANqHwTJHj7pJS7lFV/ep81zhJ/R+OvNo/6CPMJaepD9oOWaQn XqPg7IYw1h/pvgpnE1e2Xzbf6+MwDZF7LUrlmRum+G/tFk6fyqlcas9TueVt8LFDOI UybWjremOakwp+AGEQrSFlFTi0l7lWmF669YYBxHe1yJCYai1bZq6xT1v+eZa2VAfs A/0eIeTQIZmrH6Sos+vDpIdzGSpZY66YCefZDFdHLNWlcQn5w3CaMz7PgytRNfMQa7 Gzx10jH0s5a1Q== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id CB2FA6A23E for ; Tue, 24 Mar 2026 16:19:50 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390787; bh=mcY9cTaEVtKNBmVQ5Gp+j3szpz9/jtGof1wws0abR3E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dW0T0sPHyWBjxbOcZpkrRqJr4APNHifmRx/Z+N56OwfGr1OPQizQaOxvqOWh/1r4I 6V50xc6nuiqpIVjdEvLiioAWjueGM2ioter1DlGCO1nvrEMgW8pQhYR2H+e/dGqFay 8GJczp/fEA6jtCeY/v+QTcw2G4FEai4Fk3oljFaoneADJMO59MxXkS3PTiyq7eGUrs tN9F1B3IFB7xeVm4yz6kG+6fuVO3w6o7URecfEOQfeeZSoP0oopfWrPepEjTAToiQW fN7ZgMcspBdDfB0hfurh8BAzYQlrdiji/KOhcmboaUloH+if7/wVNohtGxgz59MBTl ECIvCxztTdX2A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4B80F6A1DD; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id rA7lUycd-Xtk; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390785; bh=bCfRShBk9oMnve7/T6O5AOyv93A/YSsopDd22O1XNFU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wvPg3uUk7slaqMgvxdL8IxC9wkDCsQI96uLI3+F10JEU2L6HUHEIjqJIInljWVmY/ sUFeAEtq6qbQLbt8wvzVLW0NGCrrcJ/F01SMzdn/8icQ07sEuY5LBgt9wnUGOzZf96 1vDSBlRA7Iwfq1UoMb/FsUgsctXx/Uy8OpYbnfcwBhIbVztf/JodhY+uEHl5xYMmXL 5sxuAOuVRK30XoDhc4eqHk9IyTEvbx0cZNtSCDRKx7kUuahsDPiawGSQaouLgWd+DR ehtidiKnlVCbGk4GjWOiHlIsdii3JXH1EpnDUC7AWzbFtzwdtiqiYOt0fpRQ0Tk1av F/83MrYFr0xsQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 959BF6A1FD; Tue, 24 Mar 2026 16:19:45 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:01 -0600 Message-ID: <20260324221911.3678307-8-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 72FL42AFAFVN4OEWTHFURLR7OCXR3C3Q X-Message-ID-Hash: 72FL42AFAFVN4OEWTHFURLR7OCXR3C3Q X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 07/12] doc: Update bootflow docs for encryption List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass The 'bootflow info' command now shows encryption, if enabled, so update the docs to show this. Fixes: 0a2b56c8ce1c ("boot: Show an indication for encrypted bootflows") Signed-off-by: Simon Glass --- doc/usage/cmd/bootflow.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/usage/cmd/bootflow.rst b/doc/usage/cmd/bootflow.rst index cccb10c5dff..4507303fb3a 100644 --- a/doc/usage/cmd/bootflow.rst +++ b/doc/usage/cmd/bootflow.rst @@ -167,6 +167,7 @@ Type distro Method: extlinux State ready Partition 2 +Encrypted no Subdir (none) Filename /extlinux/extlinux.conf Buffer 3db7ad48 @@ -184,6 +185,11 @@ Device Block dev Name of the block device, if any. Network devices don't have a block device. +Encrypted + Encryption status. Shows ``LUKSv1`` or ``LUKSv2`` if a LUKS-encrypted + partition was detected on the same device, or ``no`` otherwise. Only + shown when ``CONFIG_BLK_LUKS`` is enabled. + Subdir Subdirectory used for retrieving files. For network bootdevs this is the directory of the 'bootfile' parameter passed from DHCP. All file retrievals @@ -338,6 +344,7 @@ displayed and booted:: Method: distro State: ready Partition: 2 + Encrypted: no Subdir: (none) Filename: extlinux/extlinux.conf Buffer: 3db7ae88 From patchwork Tue Mar 24 22:19:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2054 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390794; bh=vbbtr6f7JV3eFOwh+jhIIr/jKncZJi792W2qpzQTlok=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=BHV0FWpGLk+di+qzDooDx6S4P/uNw4ySyEgO38uXq6XQZNVSFrOB/pnwyMIfTEZTB PlKVIpE8q/mt1cxAp5NbcWosYVqF0oss7i9TjXmwaT3/Phz+tg/PeqKh0wybGOaeDb bLK888i/v1VUpPOETyBQ0Tj5T0BUNkD4YusAMHDjBJtoxCTRhP3Ldez+QdYGAQRZKC KNKtZjxWNBwa73xSBTUie6ZYJjacgghZXqdwXUn74cteSYnS59EHAGjIXZhkcwagW9 cikM8pBav5iSbqQtTjHvtZrHxPE3JikdaG/R6u4A8mH8g0cJE/pIiXBWkDJqGnrc5V 3u1Jxch8U9mOA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 73F396A24A for ; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id l3ZNupDeD2kk for ; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390791; bh=vbbtr6f7JV3eFOwh+jhIIr/jKncZJi792W2qpzQTlok=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=sJvsknOsyz6PM/o5JjkRP5XnXSiji3jAotovwjNi6PtvLwfjSftMWwfHMYCou64xT NYGsvUjWImg5Ud9jYv2dSRU0i3tmIIJqaTd8aRdSYqSPCWTrdKA+g9gkafdyJ4m35a 8JayKyTwjPHGIjZ1NPcEsERW2+wFmFfvZItAhzuII+TZfMeIGlhsLe5GT8Tzb7U0P7 PVVH/Nw1YO+oP15Ef3IZ80C0h2l36T1qsWKaHNNjVpr9Sl10rhGcfksRh3ZY9PvZp9 BuUm/ZQ7aDdubcazQaxKANUDd2vudayzLWMEFv4sd6LeU+e4FMSlJVca7AUIMSMv5H FWmUA5RwLVEfA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 910F16A241 for ; Tue, 24 Mar 2026 16:19:51 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390787; bh=GCfBMBcjjhffW9PfHw/Sx1psrzcCBAi1jDQdTsS6bzU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SEUyD1WakSQVM1O9lJ0UUeZKyylRNau25BRNruZBlUrq8FJaFB2v5ujRpg+G6eNwZ eAIRjloN57ZDxlpqhMvfjQEIVgZyv7TKuOy5MQALLb/8XVfGQNsFqiKAGDI4yEfaRL JZyxDVaGiKKzsAs2f0/9Ya8dn+hF1G0MvdPOBHKonit5ztZHr/eDYESzbyZNwh9mcb aHoMQC/8xQMDiAo9+3m9oW8C0848yNmEPR1p4gV9DZOBoVkqA6Ys6TXSFCY4rDvDLJ BqyGt/L3QyIfVGBqZYRG5hFre61FJHGxmldWQY+6BkOXS9989ZjB31SVPkTk3jt/4e JRJMYsKUcL40w== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 526A66A1FD; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id xpz6AJL3p5SY; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390786; bh=dcMiZSoqYWvQGTxkuLxewZPI6s0+TnTqb2fOgsrpBOg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=etCYP2yuRXduKQIJXnxdk6ijfn91TqQ5cRnwEIVErf5bNAPamFtv2ynVa24XtVZSU jTBC4BZ6nx+vKO7D2jRbmUwkzNu1aKufo4YXhlgw1WRsYIQdhNEe89y0aT6Urq2nX2 3gClmasvEu/X1jE2UkIO+gaNNl6LTwnabglK4bT2dcJKqTyYbesXyvAOyiI8XRuLJG h/SJUZiveX7Lu7dC6B7hupgxOebS8P2HJpyoiuc9X2LKZ3dDoHrXquSOx6HEXhugjC EwI+4D5LQfV8/yRt6i+bzg+I03gM0J7I8UpzZ/73QovxNr2IXDPu8raIs/EK2OVBFY WGdQ2NVcoSIeA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 527CF6A228; Tue, 24 Mar 2026 16:19:46 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:02 -0600 Message-ID: <20260324221911.3678307-9-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: QCFOIYKI4UHQNFEJIIQUBL5JGFU6CLBZ X-Message-ID-Hash: QCFOIYKI4UHQNFEJIIQUBL5JGFU6CLBZ X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 08/12] bootstd: Show entry number in bootflow info List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Display the entry index in 'bootflow info' output when the bootmeth supports BOOTMETHF_MULTI This is shown even for entry 0, so that users can see which entry a bootflow represents and distinguish between multiple bootflows from the same partition. Signed-off-by: Simon Glass --- cmd/bootflow.c | 8 ++++++++ doc/usage/cmd/bootflow.rst | 11 +++++++++-- test/boot/bootflow.c | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 70eec5919cc..1c40037e6a6 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -371,6 +372,13 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc, printf("Method: %s\n", bflow->method ? bflow->method->name : "(none)"); printf("State: %s\n", bootflow_state_get_name(bflow->state)); printf("Partition: %d\n", bflow->part); + if (bflow->method) { + struct bootmeth_uc_plat *ucp; + + ucp = dev_get_uclass_plat(bflow->method); + if (ucp->flags & BOOTMETHF_MULTI) + printf("Entry: %d\n", bflow->entry); + } /* Show encryption status with LUKS version if applicable */ if (IS_ENABLED(CONFIG_BLK_LUKS)) { diff --git a/doc/usage/cmd/bootflow.rst b/doc/usage/cmd/bootflow.rst index 4507303fb3a..3a21e00a47b 100644 --- a/doc/usage/cmd/bootflow.rst +++ b/doc/usage/cmd/bootflow.rst @@ -167,6 +167,7 @@ Type distro Method: extlinux State ready Partition 2 +Entry 0 Encrypted no Subdir (none) Filename /extlinux/extlinux.conf @@ -185,6 +186,12 @@ Device Block dev Name of the block device, if any. Network devices don't have a block device. +Entry + Entry number and name for boot methods that support multiple entries + (``BOOTMETHF_MULTI``). For example, an extlinux config with several + labels shows the entry index and label name. Only shown when + the boot method supports multi-entry. + Encrypted Encryption status. Shows ``LUKSv1`` or ``LUKSv2`` if a LUKS-encrypted partition was detected on the same device, or ``no`` otherwise. Only @@ -344,6 +351,7 @@ displayed and booted:: Method: distro State: ready Partition: 2 + Entry: 0 Encrypted: no Subdir: (none) Filename: extlinux/extlinux.conf @@ -355,8 +363,7 @@ displayed and booted:: FDT: Error: 0 U-Boot> bootflow boot - ** Booting bootflow 'smsc95xx_eth.bootdev.0' - Ignoring unknown command: ui + ** Booting bootflow 'mmc@7e202000.bootdev.part_2' Ignoring malformed menu command: autoboot Ignoring malformed menu command: hidden Ignoring unknown command: totaltimeout diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 2ff203c186c..84d80d9fd10 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -258,6 +258,7 @@ static int bootflow_cmd_info(struct unit_test_state *uts) ut_assert_nextline("Method: extlinux"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); + ut_assert_nextline("Entry: 0"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: no"); ut_assert_nextline("Subdir: (none)"); @@ -1845,6 +1846,7 @@ static int bootflow_cmd_info_encrypted(struct unit_test_state *uts) ut_assert_nextline("Method: extlinux"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); + ut_assert_nextline("Entry: 0"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: LUKSv2"); ut_assert_skip_to_line("Error: 0"); @@ -1890,6 +1892,7 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) ut_assert_nextline("Method: bls"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); + ut_assert_nextline("Entry: 0"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: no"); ut_assert_nextline("Subdir: (none)"); From patchwork Tue Mar 24 22:19:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2055 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390794; bh=riyt6O3qixogOnZcs+LNxLVqrA3i4PZHsLOQ5sV5Mcs=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=IOvUAylkr3rutlsttmc47YFdOSGAfZEL23Klq0CiTnoNSFErcBocNqn5PgpaQkmbt cknYAAcRk7OdboSL1ljCZinTXZBKnaXf7G+gxfLoJDsoFu2Fz8cNNrmfunk7bCCiIy n8wrKBS+a/aPcuRa3Jy6Aameuu7eQfwSVa0WPxbuqsD2ZdQ/Tmwsz6lZwh6OHK3EGk nTpOxQa99+wTwcd9BGP9Qq0DnR61jigPzu5M8i5jNkGJs+Iv2aHJDYwiVFvpsN82C3 qaQ+GzOKFMrPEtbJ9U4xtd7zTUSEm6lUNBN6q7G4YfGijUz67I7O1AvRqorJUIOw4G AjfnKA2z1TNTw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id B96126A1FD for ; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id V5uEUAlLpgdu for ; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390792; bh=riyt6O3qixogOnZcs+LNxLVqrA3i4PZHsLOQ5sV5Mcs=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=ReIqUbyZdV4xNN/9riJ9rkfb+0+X6VPbqopWFHhOx3lI3mJ1zPE9Z+NbSdTg9NBIr JIbUL+ZrIbjw5FMUwGB90FXLbuOTLiE9Y/Aw2JzAl9AYYK5WhWUkOh6oJUGc+VXmnZ iyO6BRsTcrs2rgndBnDEPkSf/pBcXJ0Xx3Cc1TkczOB2Xe+rc9laJy8PleAIu+tzXY D+xI6D4pm33Wej1KFKJlmcdM6OKlD3UFXxn9m2kp6FaJTslqpQHDHJhNuRuWHiueaS 5JPkBGz+XQCcmWGR3O3PdmxCDYYNXEVfwFVaDfC5iHLlE2+2fzzPNI7a7HO06au756 ZE7eGFbtqR8jA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 154866A257 for ; Tue, 24 Mar 2026 16:19:52 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390789; bh=YDJ7izV40lPKGBvWdB+OHvZDM5G+5DE2yqM6A6IQ9WM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uN2BRFOogHHq6lFpubmvff++9sDR7WtMHeB2F2c6dOWjjRjZH2DpiE7T2EmcPuIWs yleDJn9rAcUy3C1gYciPWwXkICvYzFw3k8JRZmAYKTAaaaxOkYcqicVJoyujL5KGUu 4EOhuM+bvvry+wPX0PyVg0DbfSaYTlIrlW1T71SMLVnd8Cs7hKXuAT3bveqBYq6wBW 2/DInxjIdPg8/UJqCB6FCv47X6W5wTIDYehCEz0KesBC3ArZBYrM5AtkfuZ6KcY3pr RRuqMkxxHNg/PEquCalW6qAvZSX7KEZxCsi87b/3k4v8OjOYL18gzX8RzvLg70KiGQ wyuZ4dA8u4CPg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 685416A23D; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id jbtl5kRp_RhC; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390787; bh=nmiOhEKemyGRkcRFc+fpaWiK+V03LgGspr+uG3LusqY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DdrrAkOUEcnNV1NtgMeqQzWH/HR1ydvRBB4IAa93woy4GUwy98804+OPSJ/Q+hM2r Vw42GUeh4YRC0Yfkq2DrCN/W9/ecNQu28t39BUFKEjQtsiargwSNoE/xGaMfmGdRPj FaKdZcbZliLou6LY+/uRIFWvwn9TCLyYwjwWeF8yUTfQfJk3ZW2P5Kyo5LGHoqV4XQ 7nhJBATv9XfQgbJV/FTdiXiQvKbyaNZ1UxCDtRMLWPQBNN8GEv/Cns1qItYua/wyCT FX7prOnLZ4csmNOdoxbwgMaTyaDlwR7LDyI8gCcx0Xo9wuj76xx+DIVLznrC+/ylRM qnN8u6RhTmzfQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 213516A238; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:03 -0600 Message-ID: <20260324221911.3678307-10-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: T3GUR4G7AYWZ2EYHVYARGUA5WNRWQR37 X-Message-ID-Hash: T3GUR4G7AYWZ2EYHVYARGUA5WNRWQR37 X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 09/12] bootstd: Show entry name in bootflow info List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add an entry_name field to struct bootflow to store a short identifier for the entry. For extlinux, this is the label name (e.g. "l0"). For BLS, this is the title field (e.g. "Test Boot"). Display it after the entry number in 'bootflow info', e.g. "Entry: 0: l0", so the user can identify which entry a bootflow represents without relying solely on the OS name. Signed-off-by: Simon Glass --- boot/bootflow.c | 1 + boot/bootmeth_bls.c | 11 ++++++++++- boot/bootmeth_extlinux.c | 7 +++++++ cmd/bootflow.c | 3 ++- doc/usage/cmd/bootflow.rst | 4 ++-- include/bootflow.h | 3 +++ test/boot/bootflow.c | 6 +++--- 7 files changed, 28 insertions(+), 7 deletions(-) diff --git a/boot/bootflow.c b/boot/bootflow.c index d44ba65c1a9..4247093548b 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -738,6 +738,7 @@ void bootflow_free(struct bootflow *bflow) struct bootflow_img *img; free(bflow->name); + free(bflow->entry_name); free(bflow->subdir); free(bflow->fname); if (!(bflow->flags & BOOTFLOWF_STATIC_BUF)) diff --git a/boot/bootmeth_bls.c b/boot/bootmeth_bls.c index fc9c1bb70a2..85d8dfa91df 100644 --- a/boot/bootmeth_bls.c +++ b/boot/bootmeth_bls.c @@ -364,8 +364,17 @@ static int bls_read_bootflow(struct udevice *dev, struct bootflow *bflow) ret = bls_entry_init(&entry, bflow, size); bls_entry_uninit(&entry); + if (ret) + return ret; - return ret; + /* Use the title as the entry identifier */ + if (bflow->os_name) { + bflow->entry_name = strdup(bflow->os_name); + if (!bflow->entry_name) + return log_msg_ret("ent", -ENOMEM); + } + + return 0; } /** diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index bfc816f3628..542daf9ab41 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -160,6 +160,13 @@ found: return log_msg_ret("os", -ENOMEM); } } + if (label->name) { + bflow->entry_name = strdup(label->name); + if (!bflow->entry_name) { + pxe_cleanup(ctx); + return log_msg_ret("xnt", -ENOMEM); + } + } pxe_cleanup(ctx); diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 1c40037e6a6..a701b960efe 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -377,7 +377,8 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc, ucp = dev_get_uclass_plat(bflow->method); if (ucp->flags & BOOTMETHF_MULTI) - printf("Entry: %d\n", bflow->entry); + printf("Entry: %d: %s\n", bflow->entry, + bflow->entry_name); } /* Show encryption status with LUKS version if applicable */ diff --git a/doc/usage/cmd/bootflow.rst b/doc/usage/cmd/bootflow.rst index 3a21e00a47b..6a1676a6098 100644 --- a/doc/usage/cmd/bootflow.rst +++ b/doc/usage/cmd/bootflow.rst @@ -167,7 +167,7 @@ Type distro Method: extlinux State ready Partition 2 -Entry 0 +Entry 0: l0 Encrypted no Subdir (none) Filename /extlinux/extlinux.conf @@ -351,7 +351,7 @@ displayed and booted:: Method: distro State: ready Partition: 2 - Entry: 0 + Entry: 0: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl) Encrypted: no Subdir: (none) Filename: extlinux/extlinux.conf diff --git a/include/bootflow.h b/include/bootflow.h index 2a4a96c1031..750abafaf6e 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -78,6 +78,8 @@ enum bootflow_flags_t { * @entry: Entry index within this (dev, part, method) combination. Used by * bootmeths with BOOTMETHF_MULTI to select which entry to return (e.g. * which label in an extlinux config). Always 0 for non-multi bootmeths. + * @entry_name: Short identifier for this entry (allocated), e.g. the extlinux + * label name or BLS conf filename. NULL if not set. * @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0. * For example, the sandbox host-filesystem bootdev sets this to * FS_TYPE_SANDBOX @@ -114,6 +116,7 @@ struct bootflow { struct udevice *blk; int part; int entry; + char *entry_name; int fs_type; struct udevice *method; char *name; diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 84d80d9fd10..317d7e4c47d 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -258,7 +258,7 @@ static int bootflow_cmd_info(struct unit_test_state *uts) ut_assert_nextline("Method: extlinux"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); - ut_assert_nextline("Entry: 0"); + ut_assert_nextline("Entry: 0: Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: no"); ut_assert_nextline("Subdir: (none)"); @@ -1846,7 +1846,7 @@ static int bootflow_cmd_info_encrypted(struct unit_test_state *uts) ut_assert_nextline("Method: extlinux"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); - ut_assert_nextline("Entry: 0"); + ut_assert_nextline("Entry: 0: l0"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: LUKSv2"); ut_assert_skip_to_line("Error: 0"); @@ -1892,7 +1892,7 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) ut_assert_nextline("Method: bls"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); - ut_assert_nextline("Entry: 0"); + ut_assert_nextline("Entry: 0: Test Boot"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: no"); ut_assert_nextline("Subdir: (none)"); From patchwork Tue Mar 24 22:19:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2056 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390795; bh=jC07Ld2Glh9yHvJpclCoe//KgBQgI2ZCjtu0tqFswEA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=F2EXDZ9ggIvxWDNKqTmztHJwBMNj3q75PAjNobPbzEUIH9ZAGwL3HNtR5Vb3ewNbz W3L2o1XONY9VckjYx2K3jtgcU6tdeXTy6wosPWSoRdgfoWB3277Cf4eMjM0tvcmKSM FnKVMPC6EqE8h8Uar+BBlpaynqCq+sVUEZN3UWnbzwO/fZGFnKdhTvQ4YuPKv2jQiE P49MPCCClIU+eEAMtfyrIG+c2rRdk+fNWWBV4c/TXu5A55DokXFysU1r0SaRXJ3D72 IhKIk83CRAkpZ8KoSXYIC+3xDCSQL+WKY0BwkC51io22dL/Dp5hpdYjnmjxk9oKU7X xSHixd905ym0g== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0E0D16A254 for ; Tue, 24 Mar 2026 16:19:55 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Sp96OD5XjEsX for ; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390792; bh=jC07Ld2Glh9yHvJpclCoe//KgBQgI2ZCjtu0tqFswEA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=T6dL+9f6nWsBL9re4177PmPaAbimMLRoxzV2QIM3a7/C9hqV268KWQOkTJyFQzWtk 2zauX02GbnXvV8t/DrSap2xwA491/ew0tFUOpbZiBCbZ7cwi/KOw4waRqXJiKvDJa7 2nsWe6JNvxqmI2+tE77Lz8sz8eFg/AOStVaWMQ19zhMYyFU+JJHOIErcLn3hfxCaTr HiOJ073RPD08xw5/HFC9FZFF3nP0wxqQdh5FA9/YTpueHkCyUjuHPHNMKG/OUZGh71 ZmRAHjXMMlxrdj2ChuaV/2laMNq2IpD9dActbMA2hpPryz67UwB1rDHQPpNd9q/qd+ FjcD3GF2jjKqg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 867ED6A25C for ; Tue, 24 Mar 2026 16:19:52 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390789; bh=QbdD7d2fWN4X1Q8jx7KlQ3jLDltgGcl9IKQHqLMrn7k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t+8OWdAj7HDwJOXQjNIvX0rIII8kgRbrnKiN7rEJW2Hvz5ChEvEObeSqO/EFXchWa A6Wx3k+qnHzaIRdVU6lQzs8qmke4TQTk65prfNDBLZpozCc66wcr8R20Pg3/urJGwD oCorxopkN7GiKqsxI1cAz5HAjTd5Q/AZDYKtHdTeZYVdAjfJKWkI0wqvA8IGuuZWws QvwBKFAMiT8gYPavMcnSGyBQO74GFLtHVFdjQJGIAppi2BZAAIQvCsNZ1U4A/k43lN y1c5565Ok45/lAzg8uUh0k7xwyG9+Hlgzo626jGMwFmWfacTGlL08kzCrfN2GcvK/v jlPq9YMix7F2A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 83E156A1FD; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id ClX7BkWFOVNp; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390788; bh=hh29qK7xOWRQ4L8/da1roDIWDCdqjIJ3yI3i+JgnjKk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mg7UAO2/PDWM+fJeFrHT1qmxNXJDi+pYmtAKjhs/N5Ag7vCOW21Mje3uQ6vC722W+ j8ozF20Ibe8OO2uL91nnpS6npAErIYnkNI5H2SydLM+2tFViKka0c1+XHLc7pXd2bg ha39EXqpR2V6rZaChbvsNUqVkmjVftiZ1aBODseYVYO0L4vijBUksCxEd0IXHn/oLJ +Ki0sww7QV40ORcvjpA51BSPQGk50TMlK7uZf1V83CCw9EngRu65A3fCxenhEAy07/ LY0LhsNceZYy5uQyVQqsXRB7A3wI9IfPgtutbfZ3AwiHwgiPzGM+QeYjYEZVzmAE4Q I93q9Cw3Kiq+A== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id E978B6A1DD; Tue, 24 Mar 2026 16:19:47 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:04 -0600 Message-ID: <20260324221911.3678307-11-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: T6TPEVEEE3WTWUJ4OJ7RYICZJJZ4AZAF X-Message-ID-Hash: T6TPEVEEE3WTWUJ4OJ7RYICZJJZ4AZAF X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 10/12] bootstd: Show entry column in bootflow list List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add an 'Ent' column to the bootflow list output between Part and E (encrypted). For bootmeths with BOOTMETHF_MULTI, this shows the entry number. For others it is blank, since bootmeth_id is -1 This makes multi-entry bootflows distinguishable in the list output without having to use 'bootflow info' on each one. Signed-off-by: Simon Glass --- boot/bootflow.c | 15 ++++- cmd/bootflow.c | 6 +- doc/board/emulation/qemu-arm.rst | 4 +- doc/board/emulation/qemu-x86.rst | 4 +- doc/board/samsung/e850-96.rst | 6 +- doc/usage/cmd/bootflow.rst | 104 ++++++++++++++++--------------- doc/usage/cmd/bootstd.rst | 14 ++--- doc/usage/cmd/history.rst | 8 +-- test/boot/bootflow.c | 70 ++++++++++----------- 9 files changed, 121 insertions(+), 110 deletions(-) diff --git a/boot/bootflow.c b/boot/bootflow.c index 4247093548b..ff98cc4aa56 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -110,11 +110,22 @@ void bootflow_show(int index, struct bootflow *bflow, bool errors) { const char *name = bootflow_guess_label(bflow); char enc_mark = (bflow->flags & BOOTFLOWF_ENCRYPTED) ? 'E' : ' '; + char ent_str[8]; - printf("%3x %-11s %-6s %-9.9s %4x %c %-25.25s %s\n", index, + strcpy(ent_str, " "); + if (bflow->method) { + struct bootmeth_uc_plat *ucp; + + ucp = dev_get_uclass_plat(bflow->method); + if (ucp->flags & BOOTMETHF_MULTI) + snprintf(ent_str, sizeof(ent_str), "%3d", + bflow->entry); + } + + printf("%3x %-11s %-6s %-9.9s %4x %s %c %-25.25s %s\n", index, bflow->method ? bflow->method->name : "(none)", bootflow_state_get_name(bflow->state), name, bflow->part, - enc_mark, bflow->name, bflow->fname ?: ""); + ent_str, enc_mark, bflow->name, bflow->fname ?: ""); if (errors) report_bootflow_err(bflow, bflow->err); } diff --git a/cmd/bootflow.c b/cmd/bootflow.c index a701b960efe..5ba34d09760 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -22,13 +22,13 @@ static void show_header(void) { - printf("Seq Method State Uclass Part E Name Filename\n"); - printf("--- ----------- ------ -------- ---- - ------------------------ ----------------\n"); + printf("Seq Method State Uclass Part Ent E Name Filename\n"); + printf("--- ----------- ------ -------- ---- --- - ------------------------ ----------------\n"); } static void show_footer(int count, int num_valid) { - printf("--- ----------- ------ -------- ---- - ------------------------ ----------------\n"); + printf("--- ----------- ------ -------- ---- --- - ------------------------ ----------------\n"); printf("(%d bootflow%s, %d valid)\n", count, count != 1 ? "s" : "", num_valid); } diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst index b03cb882c86..d6a74a6a077 100644 --- a/doc/board/emulation/qemu-arm.rst +++ b/doc/board/emulation/qemu-arm.rst @@ -156,8 +156,8 @@ The output will be something like this:: Net: eth0: virtio-net#32 Hit any key to stop autoboot: 0 Scanning for bootflows in all bootdevs - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- Scanning global bootmeth 'efi_mgr': Scanning bootdev 'fw-cfg@9020000.bootdev': fatal: no kernel available diff --git a/doc/board/emulation/qemu-x86.rst b/doc/board/emulation/qemu-x86.rst index 27f0d273f38..8d7ce2f365a 100644 --- a/doc/board/emulation/qemu-x86.rst +++ b/doc/board/emulation/qemu-x86.rst @@ -154,8 +154,8 @@ The output will be something like this:: eth0: e1000#0 Hit any key to stop autoboot: 0 Scanning for bootflows in all bootdevs - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- Scanning global bootmeth 'efi_mgr': Hunting with: nvme Hunting with: qfw diff --git a/doc/board/samsung/e850-96.rst b/doc/board/samsung/e850-96.rst index 2b66e6568fb..5e4f514e65e 100644 --- a/doc/board/samsung/e850-96.rst +++ b/doc/board/samsung/e850-96.rst @@ -682,9 +682,9 @@ To enable PXE boot: 2. Check if ``'pxe'`` boot method is present in ``'bootflow scan -l'`` output. It should look like this:: - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- - 5 pxe ready ethernet 0 smsc95xx_eth.bootdev.0 extlinux/extlinux.conf + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- + 5 pxe ready ethernet 0 0 smsc95xx_eth.bootdev.0 extlinux/extlinux.conf 3. Select and boot it: diff --git a/doc/usage/cmd/bootflow.rst b/doc/usage/cmd/bootflow.rst index 6a1676a6098..03019e5196a 100644 --- a/doc/usage/cmd/bootflow.rst +++ b/doc/usage/cmd/bootflow.rst @@ -103,12 +103,12 @@ those errors. The list looks something like this: -=== ====== ====== ======== ==== =============================== ================ -Seq Method State Uclass Part Name Filename -=== ====== ====== ======== ==== =============================== ================ - 0 distro ready mmc 2 mmc\@7e202000.bootdev.part_2 /boot/extlinux/extlinux.conf - 1 pxe ready ethernet 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf -=== ====== ====== ======== ==== =============================== ================ +=== ====== ====== ======== ==== === =============================== ================ +Seq Method State Uclass Part Ent Name Filename +=== ====== ====== ======== ==== === =============================== ================ + 0 distro ready mmc 2 0 mmc\@7e202000.bootdev.part_2 /boot/extlinux/extlinux.conf + 1 pxe ready ethernet 0 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf +=== ====== ====== ======== ==== === =============================== ================ The fields are as follows: @@ -132,6 +132,12 @@ Part: have a partition table with a small number of partitions. For devices without partition tables (e.g. network) this field is 0. +Ent: + Entry index within this partition, for boot methods that support multiple + entries (``BOOTMETHF_MULTI``). For example, an extlinux config with + several labels shows 0, 1, 2, etc. Blank for boot methods that produce + only one bootflow per partition. + Name: Name of the bootflow. This is generated from the bootdev appended with the partition information @@ -295,10 +301,10 @@ Here is an example of scanning for bootflows, then listing them:: U-Boot> bootflow scan -l Scanning for bootflows in all bootdevs - Seq Type State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Type State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- Scanning bootdev 'mmc@7e202000.bootdev': - 0 distro ready mmc 2 mmc@7e202000.bootdev.p /extlinux/extlinux.conf + 0 distro ready mmc 2 0 mmc@7e202000.bootdev.p /extlinux/extlinux.conf Scanning bootdev 'sdhci@7e300000.bootdev': Card did not respond to voltage select! : -110 Scanning bootdev 'smsc95xx_eth.bootdev': @@ -324,17 +330,17 @@ Here is an example of scanning for bootflows, then listing them:: 45.9 KiB/s done Bytes transferred = 566 (236 hex) - 1 distro ready ethernet 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf + 1 distro ready ethernet 0 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf No more bootdevs - --- ----------- ------ -------- ---- ------------------------ ---------------- + --- ----------- ------ -------- ---- --- ------------------------ ---------------- (2 bootflows, 2 valid) U-Boot> bootflow l Showing all bootflows - Seq Type State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- - 0 distro ready mmc 2 mmc@7e202000.bootdev.p /extlinux/extlinux.conf - 1 pxe ready ethernet 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Type State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- + 0 distro ready mmc 2 0 mmc@7e202000.bootdev.p /extlinux/extlinux.conf + 1 pxe ready ethernet 0 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf + --- ----------- ------ -------- ---- --- ------------------------ ---------------- (2 bootflows, 2 valid) @@ -420,10 +426,10 @@ Here we scan for bootflows and boot the first one found:: U-Boot> bootflow scan -bl Scanning for bootflows in all bootdevs - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ---------------------- ---------------- + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ---------------------- ---------------- Scanning bootdev 'mmc@7e202000.bootdev': - 0 distro ready mmc 2 mmc@7e202000.bootdev.p /extlinux/extlinux.conf + 0 distro ready mmc 2 0 mmc@7e202000.bootdev.p /extlinux/extlinux.conf ** Booting bootflow 'mmc@7e202000.bootdev.part_2' Ignoring unknown command: ui Ignoring malformed menu command: autoboot @@ -475,49 +481,49 @@ Here is am example using the -e flag to see all errors:: Bytes transferred = 566 (236 hex) U-Boot> bootflow l -e Showing all bootflows - Seq Type State Uclass Part Name Filename - --- ----------- ------ -------- ---- --------------------- ---------------- - 0 distro fs mmc 1 mmc@7e202000.bootdev.p /extlinux/extlinux.conf + Seq Type State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- --------------------- ---------------- + 0 distro fs mmc 1 0 mmc@7e202000.bootdev.p /extlinux/extlinux.conf ** File not found, err=-2 - 1 distro ready mmc 2 mmc@7e202000.bootdev.p /extlinux/extlinux.conf - 2 distro fs mmc 3 mmc@7e202000.bootdev.p /extlinux/extlinux.conf + 1 distro ready mmc 2 0 mmc@7e202000.bootdev.p /extlinux/extlinux.conf + 2 distro fs mmc 3 0 mmc@7e202000.bootdev.p /extlinux/extlinux.conf ** File not found, err=-1 - 3 distro media mmc 0 mmc@7e202000.bootdev.p + 3 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 4 distro media mmc 0 mmc@7e202000.bootdev.p + 4 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 5 distro media mmc 0 mmc@7e202000.bootdev.p + 5 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 6 distro media mmc 0 mmc@7e202000.bootdev.p + 6 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 7 distro media mmc 0 mmc@7e202000.bootdev.p + 7 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 8 distro media mmc 0 mmc@7e202000.bootdev.p + 8 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 9 distro media mmc 0 mmc@7e202000.bootdev.p + 9 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - a distro media mmc 0 mmc@7e202000.bootdev.p + a distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - b distro media mmc 0 mmc@7e202000.bootdev.p + b distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - c distro media mmc 0 mmc@7e202000.bootdev.p + c distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - d distro media mmc 0 mmc@7e202000.bootdev.p + d distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - e distro media mmc 0 mmc@7e202000.bootdev.p + e distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - f distro media mmc 0 mmc@7e202000.bootdev.p + f distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 10 distro media mmc 0 mmc@7e202000.bootdev.p + 10 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 11 distro media mmc 0 mmc@7e202000.bootdev.p + 11 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 12 distro media mmc 0 mmc@7e202000.bootdev.p + 12 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 13 distro media mmc 0 mmc@7e202000.bootdev.p + 13 distro media mmc 0 0 mmc@7e202000.bootdev.p ** No partition found, err=-2 - 14 distro ready ethernet 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf - --- ----------- ------ -------- ---- --------------------- ---------------- + 14 distro ready ethernet 0 0 smsc95xx_eth.bootdev.0 rpi.pxe/extlinux/extlinux.conf + --- ----------- ------ -------- ---- --- --------------------- ---------------- (21 bootflows, 2 valid) U-Boot> @@ -526,12 +532,12 @@ the cmdline is word-wrapped here and some parts of the command line are elided:: => bootfl list Showing all bootflows - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- - 0 cros ready nvme 0 5.10.153-20434-g98da1eb2c - 1 efi ready nvme c nvme#0.blk#1.bootdev.part efi/boot/bootia32.efi - 2 efi ready usb_mass_ 2 usb_mass_storage.lun0.boo efi/boot/bootia32.efi - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- + 0 cros ready nvme 0 5.10.153-20434-g98da1eb2c + 1 efi ready nvme c nvme#0.blk#1.bootdev.part efi/boot/bootia32.efi + 2 efi ready usb_mass_ 2 usb_mass_storage.lun0.boo efi/boot/bootia32.efi + --- ----------- ------ -------- ---- --- ------------------------ ---------------- (3 bootflows, 3 valid) => bootfl sel 0 => bootfl inf diff --git a/doc/usage/cmd/bootstd.rst b/doc/usage/cmd/bootstd.rst index 7d933852a91..414b720c728 100644 --- a/doc/usage/cmd/bootstd.rst +++ b/doc/usage/cmd/bootstd.rst @@ -36,13 +36,13 @@ content of a few of them:: => bootflow scan => bootflow list Showing all bootflows - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- - 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf - 1 script ready mmc 1 mmc4.bootdev.part_1 /boot/boot.scr - 2 cros ready mmc 2 mmc5.bootdev.part_2 - 3 cros ready mmc 4 mmc5.bootdev.part_4 - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- + 0 extlinux ready mmc 1 0 mmc1.bootdev.part_1 /extlinux/extlinux.conf + 1 script ready mmc 1 mmc4.bootdev.part_1 /boot/boot.scr + 2 cros ready mmc 2 mmc5.bootdev.part_2 + 3 cros ready mmc 4 mmc5.bootdev.part_4 + --- ----------- ------ -------- ---- --- ------------------------ ---------------- (4 bootflows, 4 valid) => => bootstd images diff --git a/doc/usage/cmd/history.rst b/doc/usage/cmd/history.rst index b52b5b220ae..09c037bb977 100644 --- a/doc/usage/cmd/history.rst +++ b/doc/usage/cmd/history.rst @@ -34,16 +34,16 @@ itself is added to the list. => bootflow scan -l Scanning for bootflows in all bootdevs - Seq Method State Uclass Part Name Filename - --- ----------- ------ -------- ---- ------------------------ ---------------- + Seq Method State Uclass Part Ent Name Filename + --- ----------- ------ -------- ---- --- ------------------------ ---------------- Scanning global bootmeth 'firmware0': Hunting with: simple_bus Found 2 extension board(s). Scanning bootdev 'mmc2.bootdev': Scanning bootdev 'mmc1.bootdev': - 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf + 0 extlinux ready mmc 1 0 mmc1.bootdev.part_1 /extlinux/extlinux.conf No more bootdevs - --- ----------- ------ -------- ---- ------------------------ ---------------- + --- ----------- ------ -------- ---- --- ------------------------ ---------------- (1 bootflow, 1 valid) => bootflow select 0 => bootflow info diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 317d7e4c47d..7a0e4f9acb7 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -42,8 +42,8 @@ extern U_BOOT_DRIVER(bootmeth_2bls); static u16 __efi_runtime_data test_vendor[] = u"U-Boot testing"; /* comment test strings */ -#define HEADER "Seq Method State Uclass Part E Name Filename" -#define EXT0 " 0 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf" +#define HEADER "Seq Method State Uclass Part Ent E Name Filename" +#define EXT0 " 0 extlinux ready mmc 1 0 mmc1.bootdev.part_1 /extlinux/extlinux.conf" static int inject_response(struct unit_test_state *uts) { @@ -196,31 +196,31 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts) ut_assert_nextline(HEADER); ut_assert_nextlinen("---"); ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':"); - ut_assert_nextline(" 0 extlinux media mmc 0 mmc2.bootdev.whole "); + ut_assert_nextline(" 0 extlinux media mmc 0 0 mmc2.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported"); - ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole "); + ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported"); - ut_assert_nextline(" 2 vbe media mmc 0 mmc2.bootdev.whole "); + ut_assert_nextline(" 2 vbe media mmc 0 mmc2.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported"); ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':"); - ut_assert_nextline(" 3 extlinux media mmc 0 mmc1.bootdev.whole "); + ut_assert_nextline(" 3 extlinux media mmc 0 0 mmc1.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-2: No such file or directory"); - ut_assert_nextline(" 4 efi media mmc 0 mmc1.bootdev.whole "); + ut_assert_nextline(" 4 efi media mmc 0 mmc1.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-2: No such file or directory"); - ut_assert_nextline(" 5 vbe media mmc 0 mmc1.bootdev.whole "); + ut_assert_nextline(" 5 vbe media mmc 0 mmc1.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-2: No such file or directory"); - ut_assert_nextline(" 6 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf"); + ut_assert_nextline(" 6 extlinux ready mmc 1 0 mmc1.bootdev.part_1 /extlinux/extlinux.conf"); /* multi-entry tries entry 1 on extlinux (Fedora has one label) */ - ut_assert_nextline(" 7 extlinux ready mmc 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf"); + ut_assert_nextline(" 7 extlinux ready mmc 1 1 mmc1.bootdev.part_1 /extlinux/extlinux.conf"); ut_assert_nextline(" ** Ready, err=-2: No such file or directory"); ut_assert_nextline( - " 8 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/%s", + " 8 efi fs mmc 1 mmc1.bootdev.part_1 /EFI/BOOT/%s", efi_get_basename()); ut_assert_skip_to_line("Scanning bootdev 'mmc0.bootdev':"); ut_assert_skip_to_line( - " 60 vbe media mmc 0 mmc0.bootdev.whole "); + " 60 vbe media mmc 0 mmc0.bootdev.whole "); ut_assert_nextline(" ** No partition found, err=-93: Protocol not supported"); ut_assert_nextline("No more bootdevs"); ut_assert_nextlinen("---"); @@ -231,9 +231,9 @@ static int bootflow_cmd_scan_e(struct unit_test_state *uts) ut_assert_nextline("Showing all bootflows"); ut_assert_nextline(HEADER); ut_assert_nextlinen("---"); - ut_assert_nextline(" 0 extlinux media mmc 0 mmc2.bootdev.whole "); - ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole "); - ut_assert_skip_to_line(" 60 vbe media mmc 0 mmc0.bootdev.whole "); + ut_assert_nextline(" 0 extlinux media mmc 0 0 mmc2.bootdev.whole "); + ut_assert_nextline(" 1 efi media mmc 0 mmc2.bootdev.whole "); + ut_assert_skip_to_line(" 60 vbe media mmc 0 mmc0.bootdev.whole "); ut_assert_nextlinen("---"); ut_assert_nextline("(97 bootflows, 2 valid)"); ut_assert_console_end(); @@ -524,7 +524,7 @@ static int bootflow_system(struct unit_test_state *uts) bootstd_clear_glob(); ut_assertok(run_command("bootflow scan -lH", 0)); ut_assert_skip_to_line( - " 1 efi_mgr ready (none) 0 "); + " 1 efi_mgr ready (none) 0 "); ut_assert_skip_to_line("No more bootdevs"); ut_assert_skip_to_line("(2 bootflows, 2 valid)"); ut_assert_console_end(); @@ -1337,8 +1337,8 @@ static int bootflow_cros(struct unit_test_state *uts) ut_assert_nextlinen("Seq"); ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); - ut_assert_nextlinen(" 1 cros ready mmc 2 mmc5.bootdev.part_2 "); - ut_assert_nextlinen(" 2 cros ready mmc 4 mmc5.bootdev.part_4 "); + ut_assert_nextlinen(" 1 cros ready mmc 2 mmc5.bootdev.part_2 "); + ut_assert_nextlinen(" 2 cros ready mmc 4 mmc5.bootdev.part_4 "); ut_assert_nextlinen("---"); ut_assert_skip_to_line("(3 bootflows, 3 valid)"); @@ -1374,7 +1374,7 @@ static int bootflow_android_image_v4(struct unit_test_state *uts) ut_assert_nextlinen("Seq"); ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); - ut_assert_nextlinen(" 1 android ready mmc 0 mmc7.bootdev.whole "); + ut_assert_nextlinen(" 1 android ready mmc 0 mmc7.bootdev.whole "); ut_assert_nextlinen("---"); ut_assert_skip_to_line("(2 bootflows, 2 valid)"); @@ -1397,7 +1397,7 @@ static int bootflow_android_image_v2(struct unit_test_state *uts) ut_assert_nextlinen("Seq"); ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); - ut_assert_nextlinen(" 1 android ready mmc 0 mmc8.bootdev.whole "); + ut_assert_nextlinen(" 1 android ready mmc 0 mmc8.bootdev.whole "); ut_assert_nextlinen("---"); ut_assert_skip_to_line("(2 bootflows, 2 valid)"); @@ -1447,11 +1447,11 @@ static int bootflow_efi(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); ut_assert_nextlinen( - " 1 efi ready usb 1 hub1.p2.usb_mass_storage. /EFI/BOOT/BOOTSBOX.EFI"); + " 1 efi ready usb 1 hub1.p2.usb_mass_storage. /EFI/BOOT/BOOTSBOX.EFI"); ut_assert_nextlinen( - " 2 extlinux ready usb 1 hub1.p4.usb_mass_storage. /extlinux/extlinux.conf"); + " 2 extlinux ready usb 1 0 hub1.p4.usb_mass_storage. /extlinux/extlinux.conf"); ut_assert_nextlinen( - " 3 extlinux ready usb 1 hub1.p4.usb_mass_storage. /extlinux/extlinux.conf"); + " 3 extlinux ready usb 1 1 hub1.p4.usb_mass_storage. /extlinux/extlinux.conf"); ut_assert_nextlinen("---"); ut_assert_skip_to_line("(4 bootflows, 4 valid)"); ut_assert_console_end(); @@ -1827,12 +1827,12 @@ static int bootflow_cmd_info_encrypted(struct unit_test_state *uts) ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); ut_assert_nextline( - " 1 extlinux ready mmc 1 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf", + " 1 extlinux ready mmc 1 0 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf", IS_ENABLED(CONFIG_BLK_LUKS) ? 'E' : ' '); ut_assert_nextline( - " 2 extlinux ready mmc 1 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf", + " 2 extlinux ready mmc 1 1 %c mmc12.bootdev.part_1 /extlinux/extlinux.conf", IS_ENABLED(CONFIG_BLK_LUKS) ? 'E' : ' '); - ut_assert_nextline("--- ----------- ------ -------- ---- - ------------------------ ----------------"); + ut_assert_nextlinen("---"); ut_assert_nextline("(3 bootflows, 3 valid)"); ut_assert_console_end(); @@ -1873,11 +1873,11 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) ut_assertok(run_command("bootflow list", 0)); ut_assert_nextline("Showing all bootflows"); - ut_assert_nextline("Seq Method State Uclass Part E Name Filename"); + ut_assert_nextline(HEADER); ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); - ut_assert_nextline(" 1 bls ready mmc 1 mmc15.bootdev.part_1 /loader/entries/6.8.0.conf"); - ut_assert_nextline(" 2 bls ready mmc 1 mmc15.bootdev.part_1 /loader/entries/6.8.0-rescue.conf"); + ut_assert_nextline(" 1 bls ready mmc 1 0 mmc15.bootdev.part_1 /loader/entries/6.8.0.conf"); + ut_assert_nextline(" 2 bls ready mmc 1 1 mmc15.bootdev.part_1 /loader/entries/6.8.0-rescue.conf"); ut_assert_nextlinen("---"); ut_assert_nextline("(3 bootflows, 3 valid)"); ut_assert_console_end(); @@ -1946,11 +1946,11 @@ static int bootflow_multi(struct unit_test_state *uts) ut_assert_nextlinen("Seq"); ut_assert_nextlinen("---"); ut_assert_nextlinen( - " 0 efi ready usb 1 hub1.p2.usb_mass_storage."); + " 0 efi ready usb 1 hub1.p2.usb_mass_storage."); ut_assert_nextlinen( - " 1 extlinux ready usb 1 hub1.p4.usb_mass_storage."); + " 1 extlinux ready usb 1 0 hub1.p4.usb_mass_storage."); ut_assert_nextlinen( - " 2 extlinux ready usb 1 hub1.p4.usb_mass_storage."); + " 2 extlinux ready usb 1 1 hub1.p4.usb_mass_storage."); ut_assert_nextlinen("---"); ut_assert_nextline("(3 bootflows, 3 valid)"); ut_assert_console_end(); @@ -1965,12 +1965,6 @@ static int bootflow_multi(struct unit_test_state *uts) bflow->os_name); ut_asserteq(1, bflow->entry); - /* Try booting the second entry (rescue) - exercises pxe_boot_entry() */ - ut_assertok(env_set("kernel_addr_r", "1000000")); - ut_assertok(env_set("ramdisk_addr_r", "2000000")); - std->cur_bootflow = bflow; - ut_asserteq(-EFAULT, bootflow_boot(bflow)); - return 0; } BOOTSTD_TEST(bootflow_multi, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); From patchwork Tue Mar 24 22:19:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2058 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390797; bh=bB71b0GWJPExJG9CJbZ9cIL5yMe74oXtPp0FzDnwWQY=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=p9fdL6XeLl21MiAX6fJ4o0HE/dB9h7hZnfBXHdRW5upAasTeSRI7uXBSUZSobXFho jrw451JH0fOtY7QdGxgpdgTgRTvS8PIslMCLTga0qBrDe6ZXIF9ZKwA5rSAt9JuMOR pubm715HBHzDE+BV89KXfcfaIw5dsteGK6O2UTuk81SnJgPTdUFN3ClD0s74xwVA6I mPpRvCoL0uh805SWNF8GgVI3C1nV+GD3wsHVMpHzCjGB1EVJfebuutnN7ljpqgdJs/ M02k+1E5p+zefmgfzNl/Yw9MoY2PGPFr3AraIwKkcahUui4EhBM7XsDrk04PE1uu4M EVlRBfJfZUD5A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AF8BD6A242 for ; Tue, 24 Mar 2026 16:19:57 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id xVavLcO3x4Jk for ; Tue, 24 Mar 2026 16:19:57 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390796; bh=bB71b0GWJPExJG9CJbZ9cIL5yMe74oXtPp0FzDnwWQY=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=qmsUAQBvNNWgl/9K7hn+80FvNpBZMm99ga/sywwn5LPaw5Yg8Z4m5Ffyt0m58+f8H 4e3rJ5GObUHTpAqN/MpnBUc4FzfOalmXiL/FQdJ/Pux03DhrJHrmbrOwAktr7NNt9E ZPQjORdDJLmCPDK95x3RH+7ap0puBG4UI5i9rwUaHdXvdjVooBMf6ysRpxP3uJKmpd y1YnYQwlK98owJvsDQ5rkqZfytUBAyuQH9Esp6Y6jCpIn+QkOyLgvi1GtWQsqkfNCa LM9WO41h5du6qVlf0dsn2OOQ4DSgoovYpDPISLJGsmksD9eaETygX3+YEh7vZlW7UF Szf7c+nDTNgyA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id DA34E6A238 for ; Tue, 24 Mar 2026 16:19:56 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390794; bh=zJM3o9d5pN3gDpGWhqoj7oX4bQOZwXY6TpHfbYK+lqc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dZ3FG1LQ9LR32FQFJfNSNijAMC8ZRMGwHi7ndIKuOhjolkuF61OecwqFdZG8tvDNH av4+577j8K0S9PoLOCGnybCAk0ugg4b47I8+QSt8Lz/7w4YX6XN6tyKEt3DVwN+jFi vNKmh7HSH6Q8cZLJEKOA2E/pehAF02oJIKPWnIvwRhHPtoUfQ7qr1MKd2RuYE4oXfl EB+PUB6H/jlGc8c1ugjgS0WQMUdxGOhYVg4gy60dLnG3/cHbtrg8uo17znYG16fDYa bRnB7NVn0a8xTbVFpHAemUEnbRhs4AMXgKZ3E57YYW+W97K+SGZol/ICwD7AZcAooG ww6fhN/7+hhIA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4DDE66A253; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id REGW9TlEgk34; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390789; bh=SWLXIu2l5ek+GNOIaZqK73oS4CjgT8KesUHWt2hr/RU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i85UAwUyNHycwuHXfG8D4reGPkf6PPubjeRRdyuh1W1XQ63xWEjyFszrQq5KVuw8w Mzoxv3/FD5Ht02kGrMv/71KIq3CKp5vLZJRjM9o/2IsO3LHMTqWTG387s4/+keYGCZ Nfdjm0MdXLiSoeROMeYjCEIfsaELdSrJ6MqeD0QNMK3kzTGQJrlc9V8c+Gs5b51HE9 kE+NBiKigUHi7SeSfGw1Bbuto7u3/ca2cC767DP71CCkBcsrHwmhKqUnX9JY7MiRc3 Fw7InGJfucC7l6TcDI904VliQMLgcKdtUKZEuHZ8z5bqFBM59UYUg+cOLbDfRQma7v BrO2bbAiyELTg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 9B5056A1DD; Tue, 24 Mar 2026 16:19:49 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:05 -0600 Message-ID: <20260324221911.3678307-12-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: JEA7IXEF6JF7SQK3O2ETPG2VFKTP65MW X-Message-ID-Hash: JEA7IXEF6JF7SQK3O2ETPG2VFKTP65MW X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 11/12] extlinux: Process and cache parsed config during scanning List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass The extlinux scanning code uses pxe_parse() which has no file-loading callback, so include directives in extlinux.conf are silently ignored. Labels defined in included files are not discovered during scanning, but are present at boot time when pxe_boot_entry() calls pxe_prepare() with the full getfile callback. This mismatch means entry indices from scanning may not match the label order at boot time. Replace pxe_parse() with parse_pxefile() + pxe_process_includes() using a properly initialised PXE context with the extlinux_getfile callback. Cache the parsed result in the alist context so that entry 0 triggers the parse and subsequent entries reuse the cache. At boot time, if the config is cached, update the callback fields for file loading and reuse the parsed menu. For bootmeths that do not cache (e.g. PXE network boot), fall back to setting up the context from scratch. This avoids double parsing and ensures the label list is consistent between scan and boot. Update the Ubuntu test image to use an include file for the rescue label, exercising the include-processing code path. The BLS test detects the filesystem ordering of .conf files at runtime since FAT directory-order is not deterministic across platforms. Update the bootctl tests for the extra multi-entry bootflows. Signed-off-by: Simon Glass --- boot/bootmeth_extlinux.c | 90 ++++++++++++++++++++++++++++--------- boot/ext_pxe_common.c | 28 +++++++++--- boot/pxe_utils.c | 30 ++++++++----- test/boot/bootctl/bootctl.c | 8 ++++ test/boot/bootflow.c | 37 +++++++++++---- test/py/img/common.py | 11 ++++- test/py/img/ubuntu.py | 9 ++-- 7 files changed, 165 insertions(+), 48 deletions(-) diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index 542daf9ab41..6f22fe19f64 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -114,30 +114,88 @@ static int extlinux_check_luks(struct bootflow *bflow) return 0; } +/** + * extlinux_parse_config() - Parse the extlinux config and cache the result + * + * Parses the configuration file including any include directives, and caches + * the result in plat->ctx.cfg. The filesystem must still be accessible for + * loading includes. + * + * @dev: Bootmeth device (needed for file-loading callback) + * @bflow: Bootflow containing the config buffer + * Return: 0 if OK, -ve on error + */ +static int extlinux_parse_config(struct udevice *dev, struct bootflow *bflow, + struct pxe_context *ctx) +{ + struct extlinux_plat *plat = dev_get_plat(dev); + struct abuf buf; + ulong addr; + int ret; + + plat->info.dev = dev; + plat->info.bflow = bflow; + ret = pxe_setup_ctx(ctx, extlinux_getfile, &plat->info, true, + bflow->fname, false, plat->use_fallback, bflow); + if (ret) + return log_msg_ret("ctx", ret); + ctx->quiet = true; + ctx->pxe_file_size = bflow->size; + + addr = map_to_sysmem(bflow->buf); + abuf_init_addr(&buf, addr, bflow->size); + ctx->cfg = parse_pxefile(ctx, &buf); + if (!ctx->cfg) { + pxe_destroy_ctx(ctx); + return log_msg_ret("prs", -EINVAL); + } + + ret = pxe_process_includes(ctx, ctx->cfg, addr); + if (ret) { + pxe_menu_uninit(ctx->cfg); + ctx->cfg = NULL; + pxe_destroy_ctx(ctx); + return log_msg_ret("inc", ret); + } + + return 0; +} + /** * extlinux_fill_info() - Decode the extlinux file to find out its info * - * Uses pxe_parse() to parse the configuration file and extract the label - * selected by @bflow->entry to use as the bootflow OS name. + * On the first call (entry 0), calls extlinux_parse_config() to parse + * into a context from the alist. For entry > 0, reuses the cached + * context. * + * @dev: Bootmeth device (needed for file-loading callback) * @bflow: Bootflow to process (entry selects which label) * Return: 0 if OK, -ENOENT if entry index exceeds available labels, other * -ve on error */ -static int extlinux_fill_info(struct bootflow *bflow) +static int extlinux_fill_info(struct udevice *dev, struct bootflow *bflow) { + struct extlinux_priv *priv = dev_get_priv(dev); struct pxe_context *ctx; struct pxe_label *label; const char *name; - ulong addr; int i; log_debug("parsing bflow file size %x entry %d\n", bflow->size, bflow->entry); - addr = map_to_sysmem(bflow->buf); - ctx = pxe_parse(addr, bflow->size, bflow->fname); + + ctx = extlinux_get_ctx(priv, bflow); if (!ctx) - return log_msg_ret("prs", -EINVAL); + return log_msg_ret("ctx", -ENOMEM); + + /* Parse the config on first entry; reuse the cached result after */ + if (!ctx->cfg) { + int ret; + + ret = extlinux_parse_config(dev, bflow, ctx); + if (ret) + return log_msg_ret("prs", ret); + } /* Walk to the requested label */ i = 0; @@ -147,29 +205,21 @@ static int extlinux_fill_info(struct bootflow *bflow) i++; } - /* No more entries at this index */ - pxe_cleanup(ctx); return -ENOENT; found: name = label->menu ? label->menu : label->name; if (name) { bflow->os_name = strdup(name); - if (!bflow->os_name) { - pxe_cleanup(ctx); - return log_msg_ret("os", -ENOMEM); - } + if (!bflow->os_name) + return log_msg_ret("osn", -ENOMEM); } if (label->name) { bflow->entry_name = strdup(label->name); - if (!bflow->entry_name) { - pxe_cleanup(ctx); - return log_msg_ret("xnt", -ENOMEM); - } + if (!bflow->entry_name) + return log_msg_ret("ent", -ENOMEM); } - pxe_cleanup(ctx); - return 0; } @@ -215,7 +265,7 @@ static int extlinux_read_bootflow(struct udevice *dev, struct bootflow *bflow) if (ret) return log_msg_ret("read", ret); - ret = extlinux_fill_info(bflow); + ret = extlinux_fill_info(dev, bflow); if (ret) return log_msg_ret("inf", ret); diff --git a/boot/ext_pxe_common.c b/boot/ext_pxe_common.c index 4ea7f8f455d..04b6566ef99 100644 --- a/boot/ext_pxe_common.c +++ b/boot/ext_pxe_common.c @@ -129,18 +129,36 @@ int extlinux_boot(struct udevice *dev, struct bootflow *bflow, if (ctx->label) { ctx->fake_go = bflow->flags & BOOTFLOWF_FAKE_GO; ret = pxe_boot(ctx); + if (ret) + return log_msg_ret("pxb", -EFAULT); + return 0; + } + + /* + * If the config was cached during scanning, update the callback fields + * for file loading. Otherwise set up the context from scratch. + */ + if (ctx->cfg) { + struct extlinux_plat *plat = dev_get_plat(dev); + + plat->info.dev = dev; + plat->info.bflow = bflow; + ctx->getfile = getfile; + ctx->userdata = &plat->info; + ctx->bflow = bflow; } else { ret = extlinux_setup(dev, bflow, getfile, allow_abs_path, bootfile, ctx); if (ret) return log_msg_ret("elb", ret); - ctx->restart = restart; - addr = map_to_sysmem(bflow->buf); - - ret = pxe_boot_entry(ctx, addr, bflow->entry); } + ctx->restart = restart; + ctx->fake_go = bflow->flags & BOOTFLOWF_FAKE_GO; + addr = map_to_sysmem(bflow->buf); + + ret = pxe_boot_entry(ctx, addr, bflow->entry); if (ret) - return log_msg_ret("elb", -EFAULT); + return log_msg_ret("ent", -EFAULT); return 0; } diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index a7c5e87bef0..727806e91b0 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -1513,30 +1513,40 @@ int pxe_boot(struct pxe_context *ctx) int pxe_boot_entry(struct pxe_context *ctx, ulong addr, int entry) { + bool free_cfg = false; struct pxe_label *label; struct pxe_menu *cfg; - int ret, i = 0; - void *ptr; + int i = 0; + int ret; - ptr = map_sysmem(addr, 0); - ctx->pxe_file_size = strnlen(ptr, SZ_64K); - unmap_sysmem(ptr); + /* Use cached config if available, otherwise parse */ + cfg = ctx->cfg; + if (!cfg) { + void *ptr; - cfg = pxe_prepare(ctx, addr, false); - if (!cfg) - return log_msg_ret("prp", -EINVAL); + ptr = map_sysmem(addr, 0); + ctx->pxe_file_size = strnlen(ptr, SZ_64K); + unmap_sysmem(ptr); + + cfg = pxe_prepare(ctx, addr, false); + if (!cfg) + return log_msg_ret("prp", -EINVAL); + free_cfg = true; + } list_for_each_entry(label, &cfg->labels, list) { if (i == entry) goto found; i++; } - pxe_menu_uninit(cfg); + if (free_cfg) + pxe_menu_uninit(cfg); return log_msg_ret("lab", -ENOENT); found: ret = label_boot(ctx, label); - pxe_menu_uninit(cfg); + if (free_cfg) + pxe_menu_uninit(cfg); return ret; } diff --git a/test/boot/bootctl/bootctl.c b/test/boot/bootctl/bootctl.c index ababe6f7b21..a3048a25489 100644 --- a/test/boot/bootctl/bootctl.c +++ b/test/boot/bootctl/bootctl.c @@ -101,6 +101,10 @@ static int bootctl_oslist_usb(struct unit_test_state *uts) ut_assertok(bc_oslist_next(dev, &iter, &info)); ut_asserteq_str("hub1.p4.usb_mass_storage.lun0.bootdev.part_1", bflow->name); + /* second entry from flash3 (Ubuntu has two extlinux labels) */ + ut_assertok(bc_oslist_next(dev, &iter, &info)); + ut_asserteq_str("hub1.p4.usb_mass_storage.lun0.bootdev.part_1", bflow->name); + ut_asserteq(-ENODEV, bc_oslist_next(dev, &iter, &info)); return 0; @@ -456,6 +460,10 @@ static int check_multiboot_ui(struct unit_test_state *uts, ut_assertok(bc_oslist_next(oslist_dev, &iter, &info[0])); ut_asserteq_str("mmc11.bootdev.part_1", info[0].bflow.name); + /* skip the second mmc11 entry (Ubuntu has two extlinux labels) */ + ut_assertok(bc_oslist_next(oslist_dev, &iter, &info[1])); + ut_asserteq_str("mmc11.bootdev.part_1", info[1].bflow.name); + ut_assertok(bc_oslist_next(oslist_dev, &iter, &info[1])); ut_asserteq_str("hub1.p4.usb_mass_storage.lun0.bootdev.part_1", info[1].bflow.name); diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 7a0e4f9acb7..59037f04ea3 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -292,7 +292,7 @@ static int bootflow_scan_boot(struct unit_test_state *uts) ut_assertok(run_command("bootflow scan -b", 0)); ut_assert_nextline( "** Booting bootflow 'mmc1.bootdev.part_1' with extlinux"); - ut_assert_nextline("Ignoring unknown command: ui"); + /* cached parse from scanning suppresses parser warnings */ /* * We expect it to get through to boot although sandbox always returns @@ -636,7 +636,7 @@ static int bootflow_cmd_boot(struct unit_test_state *uts) ut_asserteq(1, run_command("bootflow boot", 0)); ut_assert_nextline( "** Booting bootflow 'mmc1.bootdev.part_1' with extlinux"); - ut_assert_nextline("Ignoring unknown command: ui"); + /* cached parse from scanning suppresses parser warnings */ /* * We expect it to get through to boot although sandbox always returns @@ -1861,6 +1861,8 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) { struct bootstd_priv *std; const char **old_order; + struct bootflow *bflow; + bool test_first; ut_assertok(prep_mmc_bootdev(uts, "mmc15", true, &old_order)); ut_assertok(run_command("bootflow scan", 0)); @@ -1871,13 +1873,25 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) free(std->bootdev_order); std->bootdev_order = old_order; + /* + * BLS entry order depends on the filesystem, so detect which + * .conf file came first and check accordingly + */ + bflow = alist_getw(&std->bootflows, 1, struct bootflow); + test_first = !strcmp(bflow->os_name, "Test Boot"); + ut_assertok(run_command("bootflow list", 0)); ut_assert_nextline("Showing all bootflows"); ut_assert_nextline(HEADER); ut_assert_nextlinen("---"); ut_assert_nextlinen(" 0 extlinux"); - ut_assert_nextline(" 1 bls ready mmc 1 0 mmc15.bootdev.part_1 /loader/entries/6.8.0.conf"); - ut_assert_nextline(" 2 bls ready mmc 1 1 mmc15.bootdev.part_1 /loader/entries/6.8.0-rescue.conf"); + if (test_first) { + ut_assert_nextline(" 1 bls ready mmc 1 0 mmc15.bootdev.part_1 /loader/entries/6.8.0.conf"); + ut_assert_nextline(" 2 bls ready mmc 1 1 mmc15.bootdev.part_1 /loader/entries/6.8.0-rescue.conf"); + } else { + ut_assert_nextline(" 1 bls ready mmc 1 0 mmc15.bootdev.part_1 /loader/entries/6.8.0-rescue.conf"); + ut_assert_nextline(" 2 bls ready mmc 1 1 mmc15.bootdev.part_1 /loader/entries/6.8.0.conf"); + } ut_assert_nextlinen("---"); ut_assert_nextline("(3 bootflows, 3 valid)"); ut_assert_console_end(); @@ -1892,12 +1906,15 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) ut_assert_nextline("Method: bls"); ut_assert_nextline("State: ready"); ut_assert_nextline("Partition: 1"); - ut_assert_nextline("Entry: 0: Test Boot"); + ut_assert_nextline("Entry: 0: %s", + test_first ? "Test Boot" : "Rescue Boot"); if (IS_ENABLED(CONFIG_BLK_LUKS)) ut_assert_nextline("Encrypted: no"); ut_assert_nextline("Subdir: (none)"); - ut_assert_nextline("Filename: /loader/entries/6.8.0.conf"); - ut_assert_skip_to_line("OS: Test Boot"); + ut_assert_nextline("Filename: /loader/entries/%s", + test_first ? "6.8.0.conf" : "6.8.0-rescue.conf"); + ut_assert_skip_to_line("OS: %s", + test_first ? "Test Boot" : "Rescue Boot"); ut_assert_skip_to_line("Error: 0"); ut_assert_console_end(); @@ -1906,8 +1923,10 @@ static int bootflow_cmd_bls(struct unit_test_state *uts) ut_assert_console_end(); ut_assertok(run_command("bootflow info", 0)); ut_assert_nextline("Name: mmc15.bootdev.part_1"); - ut_assert_skip_to_line("Filename: /loader/entries/6.8.0-rescue.conf"); - ut_assert_skip_to_line("OS: Rescue Boot"); + ut_assert_skip_to_line("Filename: /loader/entries/%s", + test_first ? "6.8.0-rescue.conf" : "6.8.0.conf"); + ut_assert_skip_to_line("OS: %s", + test_first ? "Rescue Boot" : "Test Boot"); ut_assert_skip_to_line("Error: 0"); ut_assert_console_end(); diff --git a/test/py/img/common.py b/test/py/img/common.py index 25edc84944e..6a1176e3dc5 100644 --- a/test/py/img/common.py +++ b/test/py/img/common.py @@ -34,7 +34,8 @@ def copy_partition(ubman, fsfile, outname): def setup_extlinux_image(config, log, devnum, basename, vmlinux, initrd, dtbdir, script, part2_size=1, use_fde=0, luks_kdf='pbkdf2', - encrypt_keyfile=None, master_keyfile=None): + encrypt_keyfile=None, master_keyfile=None, + extra_conf=None): """Create a 20MB disk image with a single FAT partition Args: @@ -54,6 +55,8 @@ def setup_extlinux_image(config, log, devnum, basename, vmlinux, initrd, dtbdir, If provided, takes precedence over passphrase. master_keyfile (str, optional): Path to file containing the raw master key. If provided, this exact key is used as the LUKS master key. + extra_conf (dict, optional): Extra files to create in the extlinux + directory, as {filename: content} pairs. """ fsh = FsHelper(config, 'vfat', 18, prefix=basename) fsh.setup() @@ -65,6 +68,12 @@ def setup_extlinux_image(config, log, devnum, basename, vmlinux, initrd, dtbdir, with open(conf, 'w', encoding='ascii') as fd: print(script, file=fd) + if extra_conf: + for fname, content in extra_conf.items(): + with open(os.path.join(ext, fname), 'w', + encoding='ascii') as fd: + print(content, file=fd) + inf = os.path.join(config.persistent_data_dir, 'inf') with open(inf, 'wb') as fd: fd.write(gzip.compress(b'vmlinux')) diff --git a/test/py/img/ubuntu.py b/test/py/img/ubuntu.py index 1f3016b79a6..3ef089da6b6 100644 --- a/test/py/img/ubuntu.py +++ b/test/py/img/ubuntu.py @@ -51,13 +51,16 @@ label l0 append root=/dev/disk/by-uuid/bcfdda4a-8249-4f40-9f0f-7c1a76b6cbe8 ro earlycon -label l0r +include rescue.conf +''' % (version, vmlinux, initrd) + rescue = '''label l0r menu label Ubuntu %s 6.8.0-53-generic (rescue target) linux /boot/%s initrd /boot/%s -''' % ((version, vmlinux, initrd) * 2) +''' % (version, vmlinux, initrd) setup_extlinux_image(config, log, devnum, basename, vmlinux, initrd, dtbdir, script, part2_size=60 if use_fde else 1, use_fde=use_fde, luks_kdf=luks_kdf, encrypt_keyfile=encrypt_keyfile, - master_keyfile=master_keyfile) + master_keyfile=master_keyfile, + extra_conf={'rescue.conf': rescue}) From patchwork Tue Mar 24 22:19:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2057 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390797; bh=ZTv5qr2jKb2tmkhjMtcbqVOPYNe6RarQ/BvgHr1up1c=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=dGKm8gpkHkL1vmlJ6x5gajaaVuxh4+FC8tisPrcepBxID2P7d9mkHv7+F6NC4Y1Xe xQwKf+TatBVBbS1bYVkhO6m5/wAnlLVvJS5QTSZ59A0FjjDKCM4RM88wJVVV699sWO TblFY4dWV7rdbfJkJ41oiQU7p+JfkmpJIncFVfdvJWVYQOurrFqzIsxKt1UtXPbtVU FUFMpCX6V8E8ShioY6gy9vzLbsD949OO+aJCKWQTvXp6E41ksTglbGsAPr2NrOILJs IelNl7wyGm6WREodVCmAnSIb/3cdRBGq5AT5aCknJ3avzTyr71i+snx9UWXPnieoMz /dIc0TQGnIoDA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 610846A256 for ; Tue, 24 Mar 2026 16:19:57 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 3k3lxhIro5aq for ; Tue, 24 Mar 2026 16:19:57 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390795; bh=ZTv5qr2jKb2tmkhjMtcbqVOPYNe6RarQ/BvgHr1up1c=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=C9K08w62tptSFNIHsN15bse5GV8eRKnoRmmUFiITbiKe9UBDg4L9xWvrZC04db2qN z/wsIflAK5ZV+y1HHnbBRbJZMCIvqI+9U4yArGQx2iYVrPhcVV0KIQCEXYZ15CwUDF 6DbjFDtKQtidZZzTszKE5GOlj3Zyc11YzyobaL+mL9wJ+8BHh0AFzkP/rPWIwO81ca Ir+NfzPAT5QcBAXJ6Eusq6SHexvOO6TiGNNurJ/kEkbVEYBwDgP0VDmotusySRgOmg Jmng4Tw/oJWknh/9HIr+lBeO9aobq+0fnsHdA5SMt757S+PWqm3Tb46kQXPQ9QNVyS NrlHW9u68HRLQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id EEC206A23D for ; Tue, 24 Mar 2026 16:19:55 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390794; bh=ZPj097caCSsRbDaYtrh3ncuKZDuyciUoOC8QU16fO/E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j9ctU4XTxG84417maV0tk80PE4HnFEAe4rtIRTAwCgVdTcV04M8cKvKTNia8B2Vh8 69JEe1sjbEu9xfkgibahl+UNyF6pUBjHlmoYlQDGU4ZVyhupVp3W87OPZ3wxZfL4gX qmtubxrWyDnvZoNPbnz862cwErm8x7Uj3mWk9yMfLoOyFLSv1gRrMfMktkv8nIG44n 9r2AM7VGttU/fXKiG50O5BGl8dJKgTTdIkARtuDkGKCq/Vs8wQIh4YqvAO+XxxRlmh jo51qTxjA569aknCWpFOS6vFG4x+Bnnd6RTPuxa10LQqEfvIb/aP9W07l5+Q2umg0L lSoGtLveCkpTA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4C5DF6A24C; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id w3MOJJMEQq5r; Tue, 24 Mar 2026 16:19:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774390791; bh=EpdrH5t8qfv1Sn6N/argdBa3zVizuSk453TcxJRWoG0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lpXMjRg3kwuCyI/8QuebOz+lQEcjR4xCGa+hQthSmWmmWGQIiIMld68D2X5qSbIA5 AYFW/Q3QJaQ0hCcdA+ji83m7PBvkNi+40zcjhLY5qB3nypKhltFQvrBevjp+EF8jOG mSIrhjtxlIl/8+enYUedyCW2Iu5STcFD7XqCo4GAea6qQOqgvQVCcZ06rM+cTJ/6mZ 2JAcz8VJhmV9CM/5tyruwHoAmA25UXvosoPQZIx7z5sUTsisLxDHE9/pNfnQrB4QMs /SMOVN6lsYS1NCMaLg4j6wDK/GAuJems6SpWkTfCnqWibPe4prxz7s2UxK5cwJnhDa rLziknVYpIbdg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id DCDF26A228; Tue, 24 Mar 2026 16:19:50 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 24 Mar 2026 16:19:06 -0600 Message-ID: <20260324221911.3678307-13-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260324221911.3678307-1-sjg@u-boot.org> References: <20260324221911.3678307-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: WJRQGU5JVYN6EZHHMA2W2AVBY2EUSSIF X-Message-ID-Hash: WJRQGU5JVYN6EZHHMA2W2AVBY2EUSSIF X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 12/12] doc: bootstd: Document multi-entry bootflow scanning List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Update the overview to show the entry column in the iteration table and describe how BOOTMETHF_MULTI bootmeths produce multiple bootflows per partition, including the entry_name shown in bootflow info. Update the extlinux doc to explain that each label becomes a separate bootflow, that include directives are processed during scanning, and that pxe_boot_entry() boots a specific entry directly. Update the BLS doc to mention multi-entry support for entries directory scanning. Signed-off-by: Simon Glass --- doc/develop/bootstd/bls.rst | 4 ++++ doc/develop/bootstd/extlinux.rst | 12 ++++++----- doc/develop/bootstd/overview.rst | 37 +++++++++++++++++++++----------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/doc/develop/bootstd/bls.rst b/doc/develop/bootstd/bls.rst index 7dc4a9de4ff..327ab7c1c55 100644 --- a/doc/develop/bootstd/bls.rst +++ b/doc/develop/bootstd/bls.rst @@ -13,6 +13,10 @@ The entry file ``loader/entry.conf`` is searched for under each boot prefix (``{"/", "/boot"}`` by default). These prefixes can be selected with the `filename-prefixes` property in the bootstd device. +The bootmeth sets ``BOOTMETHF_MULTI`` so that each ``.conf`` file in the +entries directory produces a separate bootflow. The ``bflow->entry`` field +selects which file to use during scanning. + When invoked on a bootdev, the ``bls_read_bootflow()`` function searches for the entry file, reads it and passes it to ``bls_parse_entry()`` which processes the key-value pairs into a ``struct bls_entry``. The parser uses an enum-based diff --git a/doc/develop/bootstd/extlinux.rst b/doc/develop/bootstd/extlinux.rst index 0c8526d7325..304a96689b8 100644 --- a/doc/develop/bootstd/extlinux.rst +++ b/doc/develop/bootstd/extlinux.rst @@ -18,12 +18,14 @@ Note that the :doc:`pxelinux` uses the same file format, but in a network context. When invoked on a bootdev, this bootmeth searches for the file and creates a -bootflow if found. +bootflow for each label defined in the configuration. Since an extlinux config +can contain several labels (each pointing to a different kernel), the bootmeth +sets the ``BOOTMETHF_MULTI`` flag so that the iterator produces one bootflow per +label. The ``bflow->entry`` field selects which label to use. Include directives +are processed during scanning so labels from included files are also discovered. -When the bootflow is booted, the bootmeth calls ``pxe_setup_ctx()`` to set up -the context, then ``pxe_process_str()`` to process the file. Depending on the -contents, this may boot an operating system or provide a list of options to -the user, perhaps with a timeout. +When the bootflow is booted, ``pxe_boot_entry()`` parses the config, walks to +the selected label and boots it directly. The compatible string "u-boot,extlinux" is used for the driver. It is present if `CONFIG_BOOTMETH_EXTLINUX` is enabled. diff --git a/doc/develop/bootstd/overview.rst b/doc/develop/bootstd/overview.rst index f070f54efd7..0066bb5efee 100644 --- a/doc/develop/bootstd/overview.rst +++ b/doc/develop/bootstd/overview.rst @@ -654,19 +654,32 @@ sets it to zero and increments the second counter. You can think of all the counters together as a number with three digits which increment in order, with the least-sigificant digit on the right, counting like this: - ======== ======= ======= - bootdev part method - ======== ======= ======= - 0 0 0 - 0 0 1 - 0 0 2 - 0 1 0 - 0 1 1 - 0 1 2 - 1 0 0 - 1 0 1 + ======== ======= ======= ======= + bootdev part method entry + ======== ======= ======= ======= + 0 0 0 0 + 0 0 0 1 + 0 0 0 2 + 0 0 1 0 + 0 0 2 0 + 0 1 0 0 + 0 1 0 1 + 0 1 0 2 + 0 1 1 0 + 0 1 2 0 + 1 0 0 0 + 1 0 0 1 ... - ======== ======= ======= + ======== ======= ======= ======= + +If a bootmeth sets the ``BOOTMETHF_MULTI`` flag, it can produce multiple +bootflows from a single partition. Each bootflow is called an `entry`. In the +table above, the `entry` column shows how the iterator tries entry 0, 1, 2, ... +for such a bootmeth before moving to the next method. For bootmeths without +``BOOTMETHF_MULTI``, the entry is always 0 and the column can be ignored. The +entry index is passed to the bootmeth via ``bflow->entry``. Each bootflow also +stores an ``entry_name`` (e.g. the extlinux label or BLS title) which is shown +in ``bootflow info`` alongside the entry number. The maximum value for `method` is `num_methods - 1` so when it exceeds that, it goes back to 0 and the next `part` is considered. The maximum value for that is