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), }; /**