[Concept,5/7] scripts: build-efi: Write uboot.env file for bootcmd support

Message ID 20251029061657.1456910-6-sjg@u-boot.org
State New
Headers
Series efi: Minor improvements to QEMU and build scripts |

Commit Message

Simon Glass Oct. 29, 2025, 6:16 a.m. UTC
  From: Simon Glass <sjg@chromium.org>

When running U-Boot as an EFI application under EDK2/OVMF, U-Boot doesn't
have direct access to QEMU's fw_cfg interface. To support the --bootcmd
option, write a uboot.env file to the EFI partition containing the boot
command.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 scripts/build-efi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
  

Patch

diff --git a/scripts/build-efi b/scripts/build-efi
index 95a8f456097..6c3b7a274f3 100755
--- a/scripts/build-efi
+++ b/scripts/build-efi
@@ -13,6 +13,13 @@  OVMF-pure-efi.x64.fd at
 https://drive.google.com/file/d/1c39YI9QtpByGQ4V0UNNQtGqttEzS-eFV/view?usp=sharing
 
 Use ~/.build-efi to configure the various paths used by this script.
+
+When --bootcmd is specified, a uboot.env file is created on the EFI partition
+containing the boot command. U-Boot needs to be configured to import this file
+on startup, for example by adding to CONFIG_PREBOOT or the default bootcmd:
+
+  load ${devtype} ${devnum}:${distro_bootpart} ${loadaddr} uboot.env; \
+  env import -t ${loadaddr} ${filesize}
 """
 
 from argparse import ArgumentParser
@@ -20,6 +27,7 @@  import os
 from pathlib import Path
 import shutil
 import sys
+import tempfile
 
 import build_helper
 
@@ -169,6 +177,32 @@  class BuildEfi:
         tools.write_file(f'{dst}/startup.nsh', f'fs0:{fname}', binary=False)
         shutil.copy(f'{self.build_dir}/{fname}', dst)
 
+        # Write U-Boot environment file if bootcmd is specified
+        if self.args.bootcmd:
+            # Check if mkenvimage is available (local build or system-wide)
+            mkenvimage = 'tools/mkenvimage'
+            if not os.path.exists(mkenvimage):
+                mkenvimage = 'mkenvimage'
+                if not shutil.which(mkenvimage):
+                    tout.error('Please install u-boot-tools package:')
+                    tout.error('  sudo apt install u-boot-tools')
+                    raise FileNotFoundError('mkenvimage not found')
+
+            # Create text environment file
+            env_content = f'bootcmd={self.args.bootcmd}\n'
+            with tempfile.NamedTemporaryFile(mode='w', delete=False,
+                                             suffix='.txt') as outf:
+                outf.write(env_content)
+                env_fname = outf.name
+
+            try:
+                # Convert to binary format with CRC using mkenvimage
+                command.run(mkenvimage, '-s', '0x1000',
+                           '-o', f'{dst}/uboot.env', env_fname)
+                print(f'Created uboot.env with bootcmd: {self.args.bootcmd}')
+            finally:
+                os.unlink(env_fname)
+
     def do_build(self, build):
         """Build U-Boot for the selected board"""
         extra = ['-a', '~CONSOLE_PAGER'] if self.args.no_pager else []