From patchwork Fri Feb 13 20:24:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1851 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=1771014295; bh=PdDYbV24z49WhVNh8EzMBSCFM4Uf1LLBt540BbbR/n4=; 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=jQL60pczL2yNvq4A06I7Nc6GwOMh1H8abYcd5jRdM9g0uFwtPB17fW6HJH2ZRNVqd P6kvhm4VTIEOsEjj9Tev6BnAorVtpQfpfy5n9aZJPoHJYrI0ZtKj1b7r81UK9mCUQI 03mKcehF757PPbKPbiPbOf8I69UUq4RSMJRgqdGXrvrOpM2gVKeuyygomhkTamAbBB jonJnp+M7t6CyhgG7yd0XV2uK54UeUClLFRolrMCPuV289ahya9CQWICwV5lqt3HfR hdWXN6hpnkoWGxkeV46PfM/lXvzJCGnQJHgvSH3dVmYGPbb33cbwiFbEUIkADOOoJs J8SBdE8Pa2lxQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 726AB69B3A for ; Fri, 13 Feb 2026 13:24:55 -0700 (MST) 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 huxtujtgs6SL for ; Fri, 13 Feb 2026 13:24:55 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014295; bh=PdDYbV24z49WhVNh8EzMBSCFM4Uf1LLBt540BbbR/n4=; 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=jQL60pczL2yNvq4A06I7Nc6GwOMh1H8abYcd5jRdM9g0uFwtPB17fW6HJH2ZRNVqd P6kvhm4VTIEOsEjj9Tev6BnAorVtpQfpfy5n9aZJPoHJYrI0ZtKj1b7r81UK9mCUQI 03mKcehF757PPbKPbiPbOf8I69UUq4RSMJRgqdGXrvrOpM2gVKeuyygomhkTamAbBB jonJnp+M7t6CyhgG7yd0XV2uK54UeUClLFRolrMCPuV289ahya9CQWICwV5lqt3HfR hdWXN6hpnkoWGxkeV46PfM/lXvzJCGnQJHgvSH3dVmYGPbb33cbwiFbEUIkADOOoJs J8SBdE8Pa2lxQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 5FDEF69B2D for ; Fri, 13 Feb 2026 13:24:55 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014293; bh=Bpey8WLf7E8ubiZuAwq0vM4zBWiL/xRDizUZb0LdOzs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ugvlDHzA/PZ6bQ8+ftVGnO431uoLGA1JrWMei0CKXnynYxaZr8kmn3FYtreku3Qv6 BM8Bx6DdnEhRkaF8BVxrCm7E4vdK8gpQcGVFRHpAGf1Y6ybxAoXEUYydZ6K+NkpJzj oaEdPSEFuK8jvbxCozTXf62a4HN893O2Rd2XglpZOBXwpmu8LzBmrzTuIAF4U+kXYB 4iVsKeWJMK+NRjd53+8bHW9u8Hm2AtPdFp0Y+QfqxA657TK9h74ZcbNe+8FiGp0aR8 nBZfDgMKZ32bHEkbO7mOGbFzpOEX2pIUX25vbxbWtk20Sc7RW8mvSvtugUVbXylyBT NPOPQ1iW1yYqg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D0B3569B0E; Fri, 13 Feb 2026 13:24:53 -0700 (MST) 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 oopcGJ9JkgzR; Fri, 13 Feb 2026 13:24:53 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014288; bh=Lcj73yExCDuA3WuwUGXyWOA3FZV9flHJ6xx/ctB+bIw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XIAjLlM1j+zM5Eha84MjO0KMfJgIFyroA4Id/tgoP72q4orphXPwOLi+Z3a/BqYWT +PS0nP/aIneMCkMuTR5EI98PNd82wXg5NueP28w5+VkVNfy7AOgK1Fald3WVBTvE+X Ym7ycPaPC7N99mMroo2ZGL+xL9nSoMJrcVYIeZz9GZw8wVkbLDGmTh3E5ms2fYcYdZ BlW9PQh+Xgw+AfSWo8rxmEbTxWkW9KKvyD+RfKNvpC8nL5tvDc8VIvNQt3eO/FfKlC xRGew+wshworXyg5vB1ePRGL6IisWkeK/Zi3V0xnoC93jQzpGjmBTaF4oho8E/tCn6 eBqDX+iI6bj1w== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id A66AF69B3D; Fri, 13 Feb 2026 13:24:47 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 13 Feb 2026 13:24:09 -0700 Message-ID: <20260213202417.223068-5-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260213202417.223068-1-sjg@u-boot.org> References: <20260213202417.223068-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: LALIOZR3XBMP2ZEPB3QKFIFHKS42HUNB X-Message-ID-Hash: LALIOZR3XBMP2ZEPB3QKFIFHKS42HUNB 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 , "Claude Sonnet 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 4/8] boot: Add BLS Type #1 bootmethod 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 bootmethod for Boot Loader Specification (BLS) Type #1 entries, enabling U-Boot to discover and boot from BLS configuration files. The bootmethod looks for a single BLS entry file at loader/entry.conf on each bootdev partition. When found, it parses the entry using the BLS parser and creates a bootflow that can be booted or displayed in menus. Implementation details: - Searches for loader/entry.conf with standard bootdev prefix support - Parses the BLS entry and registers discovered images (kernel, initrd, FDT) - Converts the BLS entry to a PXE label for boot execution - Reuses the existing PXE infrastructure for file loading and boot - Supports FITs with #config syntax in the linux field - Handles multiple initrd lines (uses the first due to a PXE limitation) - Skips reloading files if already loaded (an optimisation) Current limitations: - Single entry file only (not multiple entries in loader/entries/) - Only first initrd used (PXE infrastructure limitation) - No devicetree-overlay support - No architecture/machine-id filtering - No version-based sorting - No UKI/EFI support (Type #2) The bootmethod integrates with the standard bootflow framework and appears in bootflow menus alongside extlinux and EFI entries. Documentation is provided in doc/usage/bls.rst covering the BLS format, supported features, and current limitations. Co-developed-by: Claude Sonnet 4.5 Signed-off-by: Simon Glass --- boot/Makefile | 2 +- boot/bootflow.c | 1 + boot/bootmeth_bls.c | 438 ++++++++++++++++++++++++++++++++++++++++++++ doc/usage/bls.rst | 128 +++++++++++++ doc/usage/index.rst | 1 + include/bootflow.h | 2 + 6 files changed, 571 insertions(+), 1 deletion(-) create mode 100644 boot/bootmeth_bls.c create mode 100644 doc/usage/bls.rst diff --git a/boot/Makefile b/boot/Makefile index 1e75f7ece79..7cb28e52e50 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_$(PHASE_)BOOTSTD_PROG) += prog_boot.o obj-$(CONFIG_$(PHASE_)BOOTMETH_EXTLINUX) += ext_pxe_common.o bootmeth_extlinux.o obj-$(CONFIG_$(PHASE_)BOOTMETH_EXTLINUX_PXE) += ext_pxe_common.o bootmeth_pxe.o -obj-$(CONFIG_$(PHASE_)BOOTMETH_BLS) += bls_parse.o +obj-$(CONFIG_$(PHASE_)BOOTMETH_BLS) += bls_parse.o bootmeth_bls.o obj-$(CONFIG_$(PHASE_)BOOTMETH_EFI) += bootmeth_efi.o obj-$(CONFIG_$(PHASE_)BOOTMETH_CROS) += bootmeth_cros.o obj-$(CONFIG_$(PHASE_)BOOTMETH_FEL) += bootmeth_fel.o diff --git a/boot/bootflow.c b/boot/bootflow.c index 0c389f78a28..0925c879e3d 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -30,6 +30,7 @@ enum { static const char *const bootflow_img[BFI_COUNT - BFI_FIRST] = { "extlinux_cfg", + "bls_cfg", "logo", "efi", "cmdline", diff --git a/boot/bootmeth_bls.c b/boot/bootmeth_bls.c new file mode 100644 index 00000000000..c9a2afbb6f3 --- /dev/null +++ b/boot/bootmeth_bls.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Bootmethod for Boot Loader Specification (BLS) Type #1 + * + * Copyright 2026 Canonical Ltd + * Written by Simon Glass + * + * This implements support for BLS Type #1 entries as defined in: + * https://uapi-group.org/specifications/specs/boot_loader_specification/ + * + * Supported features: + * - Single BLS entry file at loader/entry.conf + * - Fields: title, version, linux, options, initrd, devicetree + * - Multiple options lines (concatenated with spaces) + * - Multiple initrd lines (only first used, PXE limitation) + * - FITs with #config syntax in linux field + * - Zero-copy parsing (fields point into bootflow buffer) + * + * Current limitations: + * - Single entry file only, not multiple entries in loader/entries/ + * - Only first initrd used (PXE infrastructure supports one) + * - No devicetree-overlay support + * - No architecture/machine-id filtering + * - No version-based sorting + * - No UKI/EFI support (Type #2) + */ + +#define LOG_CATEGORY UCLASS_BOOTSTD + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Single BLS entry file to check */ +#define BLS_ENTRY_FILE "loader/entry.conf" + +/** + * struct bls_info - context information for BLS getfile callback + * + * @dev: Bootmethod device being used to boot + * @bflow: Bootflow being booted + */ +struct bls_info { + struct udevice *dev; + struct bootflow *bflow; +}; + +static int bls_get_state_desc(struct udevice *dev, char *buf, int maxsize) +{ + if (IS_ENABLED(CONFIG_SANDBOX)) { + int len; + + len = snprintf(buf, maxsize, "OK"); + + return len + 1 < maxsize ? 0 : -ENOSPC; + } + + return 0; +} + +static int bls_getfile(struct pxe_context *ctx, const char *file_path, + ulong *addrp, ulong align, enum bootflow_img_t type, + ulong *sizep) +{ + struct bls_info *info = ctx->userdata; + int ret; + + /* Allow up to 1GB */ + *sizep = 1 << 30; + ret = bootmeth_read_file(info->dev, info->bflow, file_path, addrp, + align, type, sizep); + if (ret) + return log_msg_ret("read", ret); + + return 0; +} + +static int bls_check(struct udevice *dev, struct bootflow_iter *iter) +{ + int ret; + + /* This only works on block devices */ + ret = bootflow_iter_check_blk(iter); + if (ret) + return log_msg_ret("blk", ret); + + return 0; +} + +/** + * bls_to_pxe_label() - Convert bootflow to PXE label for boot execution + * + * @bflow: Bootflow containing BLS entry and discovered images + * @labelp: Returns allocated PXE label structure + * Return: 0 on success, -ENOMEM if out of memory + */ +static int bls_to_pxe_label(struct bootflow *bflow, + struct pxe_label **labelp) +{ + struct pxe_label *label; + struct bootflow_img *img; + int ret; + + label = calloc(1, sizeof(*label)); + if (!label) + return log_msg_ret("alloc", -ENOMEM); + + INIT_LIST_HEAD(&label->list); + alist_init_struct(&label->files, struct pxe_file); + + label->menu = strdup(bflow->os_name ?: ""); + label->append = strdup(bflow->cmdline ?: ""); + if (!label->menu || !label->append) { + ret = -ENOMEM; + goto err; + } + + /* Extract kernel, initrd and FDT from the bootflow images */ + alist_for_each(img, &bflow->images) { + char **fieldp; + + if (img->type == (enum bootflow_img_t)IH_TYPE_KERNEL) + fieldp = &label->kernel; + else if (img->type == (enum bootflow_img_t)IH_TYPE_RAMDISK) + fieldp = &label->initrd; + else if (img->type == (enum bootflow_img_t)IH_TYPE_FLATDT) + fieldp = &label->fdt; + else + continue; + + if (!*fieldp) { + *fieldp = strdup(img->fname); + if (!*fieldp) { + ret = -ENOMEM; + goto err; + } + } + } + + *labelp = label; + return 0; + +err: + label_destroy(label); + return ret; +} + +/** + * bls_entry_init() - Parse entry and register images with bootflow + * + * @entry: Entry structure to initialize + * @bflow: Bootflow to populate + * @size: Size of BLS entry file in bflow->buf + * Return: 0 on success, -ve on error + */ +static int bls_entry_init(struct bls_entry *entry, struct bootflow *bflow, + loff_t size) +{ + char **initrd; + int ret; + + /* Parse BLS entry (fields point into bflow->buf) */ + ret = bls_parse_entry(bflow->buf, size, entry); + if (ret) + return log_msg_ret("parse", ret); + + /* Save title as os_name */ + if (entry->title) { + bflow->os_name = strdup(entry->title); + if (!bflow->os_name) + return log_msg_ret("name", -ENOMEM); + } + + /* Transfer cmdline ownership to bflow */ + if (entry->options) { + bflow->cmdline = entry->options; + entry->options = NULL; + } + + /* Register discovered images (not yet loaded, addr=0) */ + if (entry->kernel) { + if (!bootflow_img_add(bflow, entry->kernel, + (enum bootflow_img_t)IH_TYPE_KERNEL, + 0, 0)) + return log_msg_ret("imk", -ENOMEM); + } + + alist_for_each(initrd, &entry->initrds) { + if (!bootflow_img_add(bflow, *initrd, + (enum bootflow_img_t)IH_TYPE_RAMDISK, + 0, 0)) + return log_msg_ret("imi", -ENOMEM); + } + + if (entry->devicetree) { + if (!bootflow_img_add(bflow, entry->devicetree, + (enum bootflow_img_t)IH_TYPE_FLATDT, + 0, 0)) + return log_msg_ret("imf", -ENOMEM); + } + + return 0; +} + +static int bls_read_bootflow(struct udevice *dev, struct bootflow *bflow) +{ + struct bls_entry entry; + struct blk_desc *desc; + const char *const *prefixes; + struct udevice *bootstd; + const char *prefix; + loff_t size; + int ret, i; + + log_debug("BLS: starting part %d\n", bflow->part); + + /* Get bootstd device for prefixes */ + ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd); + if (ret) { + log_debug("no bootstd\n"); + return log_msg_ret("std", ret); + } + + /* Block devices require a partition table */ + if (bflow->blk && !bflow->part) { + log_debug("no partition table\n"); + return -ENOENT; + } + + prefixes = bootstd_get_prefixes(bootstd); + desc = bflow->blk ? dev_get_uclass_plat(bflow->blk) : NULL; + + /* Try each prefix to find the BLS entry file */ + i = 0; + do { + prefix = prefixes ? prefixes[i] : NULL; + log_debug("trying prefix %s\n", prefix); + + ret = bootmeth_try_file(bflow, desc, prefix, BLS_ENTRY_FILE); + } while (ret && prefixes && prefixes[++i]); + + if (ret) { + log_debug("no BLS entry file found\n"); + return log_msg_ret("try", ret); + } + + size = bflow->size; + + /* Read the file */ + ret = bootmeth_alloc_file(bflow, 0x10000, ARCH_DMA_MINALIGN, + BFI_BLS_CFG); + if (ret) + return log_msg_ret("read", ret); + + ret = bls_entry_init(&entry, bflow, size); + bls_entry_uninit(&entry); + + return ret; +} + +/** + * bls_load_files() - Load files using an existing label + * + * @dev: Bootmethod device + * @bflow: Bootflow to load files for + * @pxe_ctx: Returns initialized PXE context (caller must destroy) + * @label: PXE label to use for loading + * Return: 0 on success, -ve on error + */ +static int bls_load_files(struct udevice *dev, struct bootflow *bflow, + struct pxe_context *pxe_ctx, + struct pxe_label *label) +{ + const struct bootflow_img *first_img; + struct bls_info info; + struct pxe_file *file; + 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); + already_loaded = first_img && first_img->addr; + + /* Set up PXE context */ + info.dev = dev; + info.bflow = bflow; + ret = pxe_setup_ctx(pxe_ctx, bls_getfile, &info, true, bflow->fname, + false, false, bflow); + if (ret) + return log_msg_ret("ctx", ret); + + if (!already_loaded) { + /* Load files (kernel, initrd, FDT) */ + ret = pxe_load_files(pxe_ctx, label, NULL); + if (ret) { + pxe_destroy_ctx(pxe_ctx); + return log_msg_ret("load", ret); + } + + /* Update loaded images with their addresses */ + alist_for_each(file, &label->files) { + struct bootflow_img *img; + + /* Find the corresponding image in bootflow */ + alist_for_each(img, &bflow->images) { + if (!strcmp(img->fname, file->path)) { + img->addr = file->addr; + img->size = file->size; + break; + } + } + } + } + + /* Process FDT (apply overlays, etc.) */ + ret = pxe_setup_label(pxe_ctx, label); + if (ret) { + pxe_destroy_ctx(pxe_ctx); + return log_msg_ret("setup", ret); + } + + return 0; +} + +/** + * bls_load_all() - Load all files needed for boot + * + * @dev: Bootmethod device + * @bflow: Bootflow to load files for + * @pxe_ctx: Returns initialized PXE context (caller must destroy) + * @labelp: Returns PXE label (caller must destroy) + * Return: 0 on success, -ve on error + */ +static int bls_load_all(struct udevice *dev, struct bootflow *bflow, + struct pxe_context *pxe_ctx, + struct pxe_label **labelp) +{ + struct pxe_label *label; + int ret; + + /* Convert bootflow to PXE label for boot execution */ + ret = bls_to_pxe_label(bflow, &label); + if (ret) + return log_msg_ret("label", ret); + + ret = bls_load_files(dev, bflow, pxe_ctx, label); + if (ret) { + label_destroy(label); + return ret; + } + + *labelp = label; + + return 0; +} + +static int __maybe_unused bls_read_all(struct udevice *dev, + struct bootflow *bflow) +{ + struct pxe_context pxe_ctx; + struct pxe_label *label; + int ret; + + ret = bls_load_all(dev, bflow, &pxe_ctx, &label); + if (ret) + return ret; + + pxe_destroy_ctx(&pxe_ctx); + label_destroy(label); + + return 0; +} + +static int bls_boot(struct udevice *dev, struct bootflow *bflow) +{ + struct pxe_context pxe_ctx; + struct pxe_label *label; + int ret; + + ret = bls_load_all(dev, bflow, &pxe_ctx, &label); + if (ret) + return ret; + + /* Boot the label */ + pxe_ctx.label = label; + ret = pxe_boot(&pxe_ctx); + + /* Cleanup */ + pxe_destroy_ctx(&pxe_ctx); + label_destroy(label); + + return log_msg_ret("boot", ret); +} + +static int bls_bootmeth_bind(struct udevice *dev) +{ + struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev); + + plat->desc = IS_ENABLED(CONFIG_BOOTSTD_FULL) ? + "Boot Loader Specification (BLS) Type #1" : "bls"; + + return 0; +} + +static struct bootmeth_ops bls_bootmeth_ops = { + .get_state_desc = bls_get_state_desc, + .check = bls_check, + .read_bootflow = bls_read_bootflow, + .read_file = bootmeth_common_read_file, +#if CONFIG_IS_ENABLED(BOOTSTD_FULL) + .read_all = bls_read_all, +#endif + .boot = bls_boot, +}; + +static const struct udevice_id bls_bootmeth_ids[] = { + { .compatible = "u-boot,boot-loader-specification" }, + { } +}; + +/* Put a number before 'bls' to provide a default ordering */ +U_BOOT_DRIVER(bootmeth_2bls) = { + .name = "bootmeth_bls", + .id = UCLASS_BOOTMETH, + .of_match = bls_bootmeth_ids, + .ops = &bls_bootmeth_ops, + .bind = bls_bootmeth_bind, +}; diff --git a/doc/usage/bls.rst b/doc/usage/bls.rst new file mode 100644 index 00000000000..5f5f0efb8a4 --- /dev/null +++ b/doc/usage/bls.rst @@ -0,0 +1,128 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Boot Loader Specification (BLS) Type #1 Support +================================================ + +U-Boot supports Boot Loader Specification (BLS) Type #1 boot entries as defined +in the `Boot Loader Specification`_. + +.. _Boot Loader Specification: https://uapi-group.org/specifications/specs/boot_loader_specification/ + +Overview +-------- + +BLS provides a standardised way to describe boot entries. U-Boot's BLS support +allows it to boot operating systems configured with BLS entries, which is used +by Fedora, RHEL, and other distributions. + +The current implementation supports a single BLS entry file at +``loader/entry.conf``. Future versions may support multiple entries in +``loader/entries/``. + +Configuration +------------- + +Enable BLS support with:: + + CONFIG_BOOTMETH_BLS=y + +This automatically selects ``CONFIG_PXE_UTILS`` for boot execution. + +BLS Entry Format +---------------- + +BLS entries use a simple key-value format, one field per line. Lines starting +with ``#`` are comments. Example:: + + title Fedora Linux 39 + version 6.7.0-1.fc39.x86_64 + options root=/dev/sda3 ro quiet + linux /vmlinuz-6.7.0-1.fc39.x86_64 + initrd /initramfs-6.7.0-1.fc39.x86_64.img + devicetree /dtbs/6.7.0-1.fc39.x86_64/board.dtb + +Supported Fields +---------------- + +**Required (at least one):** + +* ``linux`` - Path to Linux kernel image (Type #1); supports FITs with + ``path#config`` syntax + +**Optional:** + +* ``title`` - Human-readable menu display name +* ``version`` - OS version identifier (parsed but not used for sorting) +* ``options`` - Kernel command line parameters (may appear multiple times; all + occurrences are concatenated) +* ``initrd`` - Initial ramdisk path (may appear multiple times, but only first + is used due to PXE limitation) +* ``devicetree`` - Device tree blob path +* ``devicetree-overlay`` - Device tree overlays (parsed but not yet supported) +* ``architecture`` - Target architecture (parsed but not used for filtering) +* ``machine-id`` - OS identifier (parsed but not used for filtering) +* ``sort-key`` - Primary sorting key (parsed but not used for sorting) + +**Not supported (out of scope for Type #1):** + +* ``efi`` - EFI program path (Type #2/UKI) +* ``uki`` - Unified Kernel Image path +* ``uki-url`` - Remote UKI reference +* ``profile`` - Multi-profile UKI selector + +FIT Support +----------- + +U-Boot's BLS implementation works seamlessly with FITs using the standard +``path#config`` syntax in the ``linux`` field:: + + linux /boot/image.fit#config-1 + +The PXE boot infrastructure handles FIT parsing automatically. + +Multiple Values +--------------- + +Fields that support multiple occurrences: + +* ``options`` - All values are concatenated with spaces +* ``initrd`` - Multiple paths can be specified, but only the first is used + (limitation of PXE boot infrastructure) + +Usage +----- + +BLS boot entries are discovered automatically during standard boot:: + + => bootflow scan + => bootflow list + => bootflow select 0 + => bootflow boot + +The BLS entry at ``loader/entry.conf`` is discovered as a bootflow. + +Implementation Notes +-------------------- + +* Single BLS entry file support (``loader/entry.conf``) +* Boot execution reuses U-Boot's PXE infrastructure for kernel loading +* Unknown fields are ignored for forward compatibility +* The bootmethod is ordered as ``bootmeth_2bls`` (after extlinux) +* Zero-copy parsing: most fields point into bootflow buffer (except ``options`` + which is allocated for concatenation) + +Current Limitations +------------------- + +* Only single entry file, not multiple entries directory scanning +* Only first initrd used (PXE infrastructure limitation) +* No devicetree-overlay support +* No architecture/machine-id filtering +* No version-based or sort-key sorting +* No UKI/Type #2 support + +See Also +-------- + +* doc/develop/bootstd.rst - Standard boot framework +* doc/usage/cmd/bootflow.rst - Bootflow command reference diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 1e0ffacebaf..4e2089389f0 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -6,6 +6,7 @@ Use U-Boot spl_boot blkmap + bls console dfu environment diff --git a/include/bootflow.h b/include/bootflow.h index be94fba80d3..6c6f07db97d 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -135,6 +135,7 @@ struct bootflow { * bootflow_img[] * * @BFI_EXTLINUX_CFG: extlinux configuration-file + * @BFI_BLS_CFG: Boot Loader Specification (BLS) configuration-file * @BFI_LOGO: logo image * @BFI_EFI: EFI PE image * @BFI_CMDLINE: OS command-line string @@ -145,6 +146,7 @@ struct bootflow { enum bootflow_img_t { BFI_FIRST = IH_TYPE_COUNT, BFI_EXTLINUX_CFG = BFI_FIRST, + BFI_BLS_CFG, BFI_LOGO, BFI_EFI, BFI_CMDLINE,