[HELP needed] bootstd EFI bootmeth over the network

Simon Glass sjg at chromium.org
Sun Mar 22 21:06:44 CET 2026


Hi Ryan,

On Sun, 22 Mar 2026 at 10:09, Ryan Persée <ryan.persee at gmail.com> wrote:
>
> Hello!
>
> I'm a bit stuck on this. Does anyone have any idea what I might be doing
> wrong? Any suggestions on how to make it work would be really appreciated!
>
> Thanks.

This is most likely a bug in the network path of the EFI bootmeth. The
qemu_arm64 target has CONFIG_OF_HAS_PRIOR_STAGE enabled (since QEMU
provides the device tree), and when fdtfile is not set,
efi_get_distro_fdt_name() returns -EALREADY to indicate the
prior-stage FDT should be used. The block-device EFI path handles this
correctly, but the network path treats it as a fatal error.

I suspect the -22 (-EINVAL) you saw initially is because fdt_addr_r is
checked before we even determine whether a FDT download is needed.

As a workaround, setting the fdtfile env var to any value should get
past this (the TFTP download of the FDT will fail but that is handled
gracefully). E.g.:

   env set fdtfile dummy.dtb

I'll send a patch to fix this properly.

Regards,
Simon


>
> Le lun. 9 mars 2026, 22:45, Ryan Persée <ryan.persee at gmail.com> a écrit :
>
> > Hello,
> >
> > As the title says, I'm trying to get u-boot to discover and boot an EFI
> > application (iPXE) over the network with DHCP+TFTP.
> > I can get the EFI application to start if I run commands (bootflow scan +
> > bootefi) manually, but after reading the documentation, I expected u-boot
> > to automatically register a bootflow after the scan, and run it
> > automatically.
> >
> > ## Environment
> >
> > - U-Boot version: U-Boot 2026.01 (compiled from sources)
> > - Target: qemu_arm64
> > - EFI-related bootmeths present (from `bootmeth list`):
> >   ```text
> >   => bootmeth list
> >   Order  Seq  Name                Description
> >   -----  ---  ------------------  ------------------
> >       0    0  extlinux            Extlinux boot from a block device
> >       1    1  script              Script boot from a block device
> >    glob    2  efi_mgr             EFI bootmgr flow
> >       3    3  efi                 EFI boot from an .efi file
> >       4    4  qfw                 QEMU boot using firmware interface
> >       5    5  pxe                 PXE boot from a network device
> >    glob    6  vbe_simple          VBE simple
> >   -----  ---  ------------------  ------------------
> >   (7 bootmeths)
> >   ```
> > - To narrow down the issue, I restricted bootmeths to only the EFI loader:
> >   ```text
> >   => bootmeth order efi
> >   => bootmeth list
> >   Order  Seq  Name                Description
> >   -----  ---  ------------------  ------------------
> >       0    3  efi                 EFI boot from an .efi file
> >   -----  ---  ------------------  ------------------
> >   (1 bootmeth)
> >   ```
> >
> > ## Network/TFTP setup
> >
> > - DHCP/TFTP server: `dnsmasq` on the host
> > - For ARM64 EFI clients (DHCP option 93 = 11), dnsmasq returns the
> > bootfile `arm64-efi/snp.efi`:
> >   ```ini
> >   dhcp-match=set:arm64efi,option:client-arch,11
> >   enable-tftp
> >   tftp-root=/var/lib/tftpboot
> >
> >   dhcp-boot=tag:arm64efi,arm64-efi/snp.efi
> >   ```
> > - File on disk:
> >   ```bash
> >   $ file /var/lib/tftpboot/arm64-efi/snp.efi
> >   /var/lib/tftpboot/arm64-efi/snp.efi: PE32+ executable for EFI
> > (application), ARM64, 6 sections
> >   ```
> >
> > So the TFTP payload appears to be a valid ARM64 EFI application.
> >
> > ## Steps to reproduce
> >
> > 1. Start QEMU with `qemu_arm64` and virtio-net pointing to the
> > dnsmasq/TFTP server.
> > 2. Interrupt autoboot to get a U-Boot prompt.
> > 3. Ensure only the `efi` bootmeth is active:
> >    ```bash
> >    bootmeth order efi
> >    bootmeth list
> >    ```
> > 4. Set `fdt_addr_r`:
> >    ```bash
> >    env set fdt_addr_r 0x44000000
> >    ```
> > 5. Run a full bootflow scan with errors shown:
> >    ```bash
> >    bootflow scan -lae
> >    ```
> >
> > (Initially, before setting `fdt_addr_r`, I saw `err=-22` on the network
> > bootflow; after setting `fdt_addr_r` that changed to `err=-114` — see logs
> > below.)
> >
> > ## Observed behavior
> >
> > ### Before setting `fdt_addr_r` (for context)
> >
> > When I first ran `bootflow scan -lae` with only `efi` enabled and **no**
> > `fdt_addr_r` in the environment, I saw:
> >
> > ```text
> > Scanning bootdev 'virtio-net#32.bootdev':
> > BOOTP broadcast 1
> > DHCP client bound to address 172.18.0.243 (2 ms)
> > Using virtio-net#32 device
> > TFTP from server 172.18.0.2; our IP address is 172.18.0.243
> > Filename 'arm64-efi/snp.efi'.
> > Load address: 0x40400000
> > Loading: #####################
> >          11.7 MiB/s
> > done
> > Bytes transferred = 305664 (4aa00 hex)
> >   6  efi          base    ethernet     0  virtio-net#32.bootdev.0
> > arm64-efi/snp.efi
> >      ** No media/partition found, err=-22
> > ...
> > (7 bootflows, 0 valid)
> > ```
> >
> > So:
> > - DHCP and TFTP succeed.
> > - `bootfile` is `arm64-efi/snp.efi`.
> > - A bootflow entry is created but stays in `base` state and has `err=-22`.
> > - No bootflows are considered valid.
> >
> > ### After setting `fdt_addr_r`
> >
> > After:
> >
> > ```bash
> > env set fdt_addr_r 0x44000000
> > bootflow scan -lae
> > ```
> >
> > I now get:
> >
> > ```text
> > Scanning for bootflows in all bootdevs
> > Seq  Method       State   Uclass    Part  Name
> >  Filename
> > ---  -----------  ------  --------  ----  ------------------------
> >  ----------------
> > Scanning bootdev 'fw-cfg at 9020000.bootdev':
> >   0  efi          base    qfw          0  <NULL>
> >      ** No media/partition found, err=-524
> > Scanning bootdev 'usb_mass_storage.lun0.bootdev':
> >   1  efi          media   usb_mass_    0  usb_mass_storage.lun0.boo
> >      ** No partition found, err=-2
> >   2  efi          media   usb_mass_    1  usb_mass_storage.lun0.boo
> >      ** No partition found, err=-2
> >   3  efi          media   usb_mass_    2  usb_mass_storage.lun0.boo
> >      ** No partition found, err=-2
> >   4  efi          media   usb_mass_    3  usb_mass_storage.lun0.boo
> >      ** No partition found, err=-2
> > Scanning bootdev 'virtio-blk#35.bootdev':
> >   5  efi          media   virtio       0  virtio-blk#35.bootdev.who
> >      ** No partition found, err=-93
> > Scanning bootdev 'virtio-net#32.bootdev':
> > BOOTP broadcast 1
> > DHCP client bound to address 172.18.0.243 (2 ms)
> > Using virtio-net#32 device
> > TFTP from server 172.18.0.2; our IP address is 172.18.0.243
> > Filename 'arm64-efi/snp.efi'.
> > Load address: 0x40400000
> > Loading: #####################
> >          4.9 MiB/s
> > done
> > Bytes transferred = 305664 (4aa00 hex)
> >   6  efi          base    ethernet     0  virtio-net#32.bootdev.0
> > arm64-efi/snp.efi
> >      ** No media/partition found, err=-114
> > No more bootdevs
> > ---  -----------  ------  --------  ----  ------------------------
> >  ----------------
> > (7 bootflows, 0 valid)
> > ```
> >
> > So with `fdt_addr_r` set:
> >
> > - DHCP and TFTP still succeed; the same EFI binary is downloaded.
> > - The bootflow for `virtio-net#32.bootdev.0` stays in `base` state, now
> > with `err=-114`.
> > - There are still `(0 bootflows, 0 valid)`.
> > - No attempt to actually execute the downloaded EFI application is visible
> > on the console.
> >
> > Separately, `file(1)` on the TFTP payload shows:
> >
> > ```text
> > /var/lib/tftpboot/arm64-efi/snp.efi: PE32+ executable for EFI
> > (application), ARM64, 6 sections
> > ```
> >
> > ## Expected behavior
> >
> > Given that:
> >
> > - The EFI bootmeth (`efi`) is present and enabled.
> > - The network bootdev (`virtio-net#32.bootdev`) successfully completes
> > DHCP and downloads the bootfile.
> > - The bootfile is a PE32+ ARM64 EFI application on disk.
> >
> > I expected:
> >
> > - A bootflow for `virtio-net#32` to reach a “ready” or equivalent state
> > (i.e. no error), and
> > - `bootflow scan -b` to attempt to execute the downloaded EFI application
> > via the EFI loader.
> >
> > Instead, the bootflow remains in `base` state with `err=-22` (before
> > setting `fdt_addr_r`) or `err=-114` (after setting `fdt_addr_r`), and is
> > not considered valid, so it never gets booted.
> >
> > ## Notes
> >
> > - This is all on QEMU (`qemu_arm64`), but my end goal is to use the EFI
> > bootmeth to automatically boot into iPXE on real ARM64 hardware using the
> > same network flow.
> > - Running `bootefi` manually after DHCP+TFTP fetched the file does work:
> > ```text
> > => bootefi 0x40400000
> > Booting /arm64-efi\snp.efi
> > iPXE initialising devices...
> >
> >
> >
> > iPXE 1.0.0+ -- Open Source Network Boot Firmware -- https://ipxe.org
> > Features: DNS FTP HTTP HTTPS iSCSI NFS TFTP VLAN AoE EFI Menu
> >
> > net0: 52:54:00:12:34:56 using SNP on SNP-0xbe690010 (Ethernet) [open]
> >   [Link:up, TX:0 TXE:0 RX:0 RXE:0]
> > Configuring (net0 52:54:00:12:34:56)...... ok
> > net0: 172.18.0.243/255.255.0.0 gw 172.18.0.1
> > net0: fe80::5054:ff:fe12:3456/64
> > Next server: 172.18.0.2
> > ...
> > ```
> >
> > Can you please help me on this? And/or explain what I'm doing wrong?
> >
> > Kind regards.
> >


More information about the U-Boot mailing list