Skip to content

Select U-Boot proper boot peripheral based on boot mode - #16

Open
pamolloy wants to merge 2 commits into
adi-u-boot-2025.10.yfrom
staging/philip/boot-mode-select-boot-peripheral
Open

Select U-Boot proper boot peripheral based on boot mode#16
pamolloy wants to merge 2 commits into
adi-u-boot-2025.10.yfrom
staging/philip/boot-mode-select-boot-peripheral

Conversation

@pamolloy

@pamolloy pamolloy commented Sep 2, 2025

Copy link
Copy Markdown
Collaborator

A silicon issue means that booting from eMMC requires programming the OTP. Additionally booting from SPI flash is much faster than eMMC. However future DSP processors will fix these issues so we should be able to support both without requiring to reconfigure and rebuild U-Boot for each case.

Note this does not handle the case where the boot loaders are loaded from SPI flash and then the runtime OS is loaded from the SD card. This is done because the boot ROM can not load the first stage boot loader from a SD card.

@pamolloy pamolloy added this to ADSP Sep 2, 2025
Comment thread board/adi/common-sc598-som/sc598-som.c Outdated
@pamolloy pamolloy self-assigned this Sep 4, 2025
Comment thread board/adi/common-sc598-som/sc598-som.c Outdated
@pamolloy

pamolloy commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

@ozan956 this patch was in Buildroot or br2_external, but I don't see it now. We had some issues with it? There was the off by one issue that I commented about above, but perhaps something else?

@ozan956

ozan956 commented Jun 25, 2026

Copy link
Copy Markdown
Member

@ozan956 this patch was in Buildroot or br2_external, but I don't see it now. We had some issues with it? There was the off by one issue that I commented about above, but perhaps something else?

Yes, that was the only issue as far as I remember.

We removed it because of that (and since it wasn’t critical anyway) .

I will update both branches, test the behavior again, and then mark this PR as ready.

@pamolloy
pamolloy force-pushed the staging/philip/boot-mode-select-boot-peripheral branch from 0142020 to 0aff3d7 Compare July 14, 2026 07:51
@pamolloy
pamolloy changed the base branch from adi-u-boot-2025.07.y to adi-u-boot-2025.10.y July 14, 2026 07:51
@pamolloy
pamolloy force-pushed the staging/philip/boot-mode-select-boot-peripheral branch from 0aff3d7 to 5952476 Compare July 14, 2026 07:53
@gastmaier
gastmaier force-pushed the adi-u-boot-2025.10.y branch from b87c75a to ea29368 Compare July 14, 2026 13:01
@ozan956
ozan956 force-pushed the staging/philip/boot-mode-select-boot-peripheral branch 3 times, most recently from 7d6b4ef to ecd6078 Compare July 18, 2026 14:04
@ozan956

ozan956 commented Jul 18, 2026

Copy link
Copy Markdown
Member

I looked into this,

The current mapping is left unchanged. Supports spi and emmc boot.

The selection is performed in board_late_init rather than board_init. In the U-Boot initialization sequence, board_init runs before the final environment is loaded by initr_env. A bootcmd set there could therefore be overwritten. board_late_init runs after environment relocation, so the selected command remains active for autoboot.

This is the behavior I encountered in docs for Zynq boot-mode implementation, which reads the boot mode and updates the runtime boot variable from board_late_init, see https://docs.u-boot.org/en/latest/board/xilinx/zynq.html#bootmode

One assumption that needs confirmation is the use of emmcboot. The U-Boot default environment currently defines mmcboot in include/env/adi/adi_boot.env, but does not define emmcboot. I used emmcboot because the Buildroot flow provides an eMMC-specific boot command and this is the command expected by that flow. This means the current implementation assumes emmcboot is supplied by the Buildroot-generated environment. If U-Boot must also work independently of Buildroot, we should either add an emmcboot definition to the U-Boot board environment, or use the existing mmcboot command instead.

The boot mode being red from switch currently overrides bootcmd after the environment is loaded. This is intentional for mode selection, but it also means a stored bootcmd would not override the boot pins. I think this is OK since we are not using modifyable environments and not storing bootcmd as default.

I also fixed the bounds checks in sc5xx_get_boot_mode.

@ozan956
ozan956 marked this pull request as ready for review July 18, 2026 14:20
@ozan956 ozan956 moved this to In Development in ADSP Jul 18, 2026
pamolloy and others added 2 commits July 19, 2026 11:58
Select the default boot command from the SC5xx boot mode switch after
environment relocation. Use spiboot for SPI Master and emmcboot for
EMMC boot mode.

Signed-off-by: Philip Molloy <philip.molloy@analog.com>
Signed-off-by: Ozan Durgut <ozan.durgut@analog.com>
local_mode is unsigned, so checking it against zero is unnecessary.
Use a strict upper bound to prevent an out-of-range array access.

Fixes: 48a0b0b ("arch: arm: Add Analog Devices SC5xx machine type")
Signed-off-by: Ozan Durgut <ozan.durgut@analog.com>
@ozan956
ozan956 force-pushed the staging/philip/boot-mode-select-boot-peripheral branch 2 times, most recently from 0a14610 to 85f69ff Compare July 19, 2026 10:04
@CalebEthridgeADI

Copy link
Copy Markdown

If U-Boot must also work independently of Buildroot, we should either add an emmcboot definition to the U-Boot board environment, or use the existing mmcboot command instead.

I think we should use the existing mmcboot command, since it is not guaranteed that the MMC device we are booting off of is an eMMC. Shouldn't Buildroot just be calling the defined bootcmd? What is special about the emmcboot flow it has?

The boot mode being red from switch currently overrides bootcmd after the environment is loaded. This is intentional for mode selection, but it also means a stored bootcmd would not override the boot pins. I think this is OK since we are not using modifyable environments and not storing bootcmd as default.

There is an option to build in support for saving the environment for a debug build currently in Yocto, but I do not think this is a big issue, as using the boot mode defined by the pins would be the expected behavior except in the rare case where the boot mode for U-boot and Linux are different ( i.e. booing U-boot off of SPI and Linux off of eMMC) which isn't supported by these current changes anyway.

@pamolloy

pamolloy commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

The boot mode being red from switch currently overrides bootcmd after the environment is loaded. This is intentional for mode selection, but it also means a stored bootcmd would not override the boot pins. I think this is OK since we are not using modifyable environments and not storing bootcmd as default.

There is an option to build in support for saving the environment for a debug build currently in Yocto, but I do not think this is a big issue, as using the boot mode defined by the pins would be the expected behavior except in the rare case where the boot mode for U-boot and Linux are different ( i.e. booing U-boot off of SPI and Linux off of eMMC) which isn't supported by these current changes anyway.

The reason this PR hasn't been worked on is because the primary boot flow is boot ROM -> U-Boot (SPI flash) -> Linux (eMMC). Typically this would be simply configured in U-Boot, but we want to have a single U-Boot binary for all flows and secure boot requires a static environment. Ideally we'd use something like a jumper to support both SPI flash only and eMMC in boot mode 1. We also have to factor in boot time and eventually removing U-Boot Proper.

SPI flash -> SD card is hopefully just a devicetree change. We could say load Linux from eMMC if it the eMMC is enabled in the devicetree, but this doesn't feel very generic.

@pamolloy

Copy link
Copy Markdown
Collaborator Author

U-Boot: Controlling Linux Boot via the Device Tree

U-Boot provides several device tree mechanisms to specify what to boot and
where to load it from, without storing anything in the U-Boot binary or its
environment.

1. Override bootcmd with the /config node

common/cli.c reads the /config node before autoboot runs. This works even
when environment loading is disabled.

/ {
    config {
        bootcmd = "bootflow scan -lb";
        bootdelay = <1>;
        load-environment = <0>;
    };
};

Useful /config properties (doc/device-tree-bindings/config.txt):

Property Type Effect
bootcmd string Replaces the boot command
bootdelay int Overrides the autoboot delay
bootsecure int Forces secure boot (no shell parsing)
load-environment int Set to 0 to skip loading the environment
kernel-offset int Sets the kernaddr env var (flash byte offset)

2. Control boot device order with the bootstd node

With CONFIG_BOOTSTD enabled, the bootstd node controls which devices are
scanned and in what order, replacing the boot_targets environment variable.

/ {
    bootstd {
        compatible = "u-boot,boot-std";
        filename-prefixes = "/", "/boot/";
        bootdev-order = "mmc1", "mmc0", "usb0";

        extlinux {
            compatible = "u-boot,extlinux";
        };

        efi {
            compatible = "u-boot,distro-efi";
        };
    };
};
  • bootdev-order: list of bootdev labels (uclass + sequence number) to try in
    order. Read by bootstd_get_bootdev_order() in boot/bootstd-uclass.c. The
    boot_targets environment variable overrides this if present, so pair it with
    load-environment = <0> if you want the device tree to take full control.
  • filename-prefixes: directories searched on each device. Defaults to
    {"/", "/boot/"}.
  • Child nodes: only the bootmeth compatible strings listed here are active.
    If none are listed, all available bootmeth drivers are bound automatically.

3. Control SPL boot device order via /chosen

The SPL stage reads u-boot,spl-boot-order from /chosen
(doc/device-tree-bindings/chosen.txt):

/ {
    chosen {
        u-boot,spl-boot-order = "same-as-spl", &emmc, &sdmmc;
    };
};

The special value "same-as-spl" inserts the device SPL was loaded from at
that position in the list. This is used on Rockchip and SoCFPGA platforms.

4. Configure a raw boot device with a bootdev child node

For boot sources that are not filesystems (e.g. raw SPI flash), a bootdev
child node can provide offset and size information directly in the device tree.

/ {
    spi@0 {
        flash@0 {
            compatible = "jedec,spi-nor";
            reg = <0>;

            bootdev {
                compatible = "u-boot,sf-bootdev";
                offset = <0x2000>;
                size   = <0x1000>;
            };
        };
    };
};

Summary

Goal Mechanism Location
Override boot command /config { bootcmd; } U-Boot DTB
Skip env loading /config { load-environment; } U-Boot DTB
Device scan order bootstd { bootdev-order; } U-Boot DTB
Search directories bootstd { filename-prefixes; } U-Boot DTB
Boot methods Child nodes of bootstd U-Boot DTB
SPL device order /chosen { u-boot,spl-boot-order; } U-Boot DTB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Development

Development

Successfully merging this pull request may close these issues.

4 participants