emulation: Support the bootcmd more generally

The code for obtaining a bootcmd from the host when running until QEMU
is currently x86-specific. In fact it can be supported on other
architecture.

Move it into a common place and update the documentation.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
Simon Glass
2025-11-14 11:28:38 -07:00
parent 76aa68ed86
commit c22bf794bf
6 changed files with 71 additions and 44 deletions

View File

@@ -153,31 +153,3 @@ int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
return irq;
}
#endif
#if CONFIG_IS_ENABLED(EVENT)
static int qemu_get_bootcmd(void *ctx, struct event *event)
{
struct event_bootcmd *bc = &event->data.bootcmd;
enum fw_cfg_selector select;
struct udevice *qfw_dev;
ulong size;
if (qfw_get_dev(&qfw_dev))
return 0;
if (qfw_locate_file(qfw_dev, "opt/u-boot/bootcmd", &select, &size))
return 0;
if (!size)
return 0;
/* Check if the command fits in the provided buffer with terminator */
if (size >= bc->size)
return -ENOSPC;
qfw_read_entry(qfw_dev, select, size, bc->bootcmd);
bc->bootcmd[size] = '\0';
return 0;
}
EVENT_SPY_FULL(EVT_BOOTCMD, qemu_get_bootcmd);
#endif

View File

@@ -2,3 +2,6 @@
obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += qemu_mtdparts.o
obj-$(CONFIG_SET_DFU_ALT_INFO) += qemu_dfu.o
ifdef CONFIG_QFW
obj-$(CONFIG_$(PHASE_)EVENT) += bootcmd.o
endif

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2025 Canonical Ltd
* Written by Simon Glass <simon.glass@canonical.com>
*/
#include <errno.h>
#include <event.h>
#include <qfw.h>
#if CONFIG_IS_ENABLED(EVENT)
static int qemu_get_bootcmd(void *ctx, struct event *event)
{
struct event_bootcmd *bc = &event->data.bootcmd;
enum fw_cfg_selector select;
struct udevice *qfw_dev;
ulong size;
if (qfw_get_dev(&qfw_dev))
return 0;
if (qfw_locate_file(qfw_dev, "opt/u-boot/bootcmd", &select, &size))
return 0;
if (!size)
return 0;
/* Check if the command fits in the provided buffer with terminator */
if (size >= bc->size)
return -ENOSPC;
qfw_read_entry(qfw_dev, select, size, bc->bootcmd);
bc->bootcmd[size] = '\0';
return 0;
}
EVENT_SPY_FULL(EVT_BOOTCMD, qemu_get_bootcmd);
#endif

View File

@@ -0,0 +1,28 @@
.. SPDX-License-Identifier: GPL-2.0+
Common features
===============
It is possible to specify the boot command directly using the fw_cfg interface.
This allows QEMU to control the boot command, which can be useful for automated
testing or scripting. To use this feature, create a file containing the boot
command and pass it to QEMU using the fw_cfg option.
Here is an x86 example::
$ echo "qfw load; zboot 01000000 - 04000000 1b1ab50" > bootcmd.txt
$ qemu-system-x86_64 -nographic -bios path/to/u-boot.rom \
-fw_cfg name=opt/u-boot/bootcmd,file=bootcmd.txt
U-Boot will read the boot command from the firmware configuration and execute it
automatically during the boot process. This bypasses the normal distro boot
sequence.
Note that the boot command is limited in length and should not exceed the boot
command buffer size. If the command is too long, U-Boot will fail to read it and
fall back to the default boot behavior.
The :doc:`script` and build-efi scripts provide a `-c` option for this feature,
although it uses a string rather than a file.
Note that ``CONFIG_QFW`` must be enabled for this feature to work.

View File

@@ -8,6 +8,7 @@ Emulation
acpi
blkdev
common
script
qemu-arm
qemu-mips

View File

@@ -116,22 +116,8 @@ supports 32-bit.
Specifying a boot command
--------------------------
It is possible to specify the boot command directly using the fw_cfg interface.
This allows QEMU to control the boot command, which can be useful for automated
testing or scripting. To use this feature, create a file containing the boot
command and pass it to QEMU using the fw_cfg option::
$ echo "qfw load; zboot 01000000 - 04000000 1b1ab50" > bootcmd.txt
$ qemu-system-x86_64 -nographic -bios path/to/u-boot.rom \
-fw_cfg name=opt/u-boot/bootcmd,file=bootcmd.txt
U-Boot will read the boot command from the firmware configuration and execute it
automatically during the boot process. This bypasses the normal distro boot
sequence.
Note that the boot command is limited in length and should not exceed the boot
command buffer size. If the command is too long, U-Boot will fail to read it and
fall back to the default boot behavior.
See :doc:`common` for details on how to provide a boot command to U-Boot on
startup.
Booting distros
---------------