From: Simon Glass <simon.glass@canonical.com> 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> --- arch/x86/cpu/qemu/qemu.c | 28 ------------------------ board/emulation/common/Makefile | 3 +++ board/emulation/common/bootcmd.c | 37 ++++++++++++++++++++++++++++++++ doc/board/emulation/common.rst | 28 ++++++++++++++++++++++++ doc/board/emulation/index.rst | 1 + doc/board/emulation/qemu-x86.rst | 18 ++-------------- 6 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 board/emulation/common/bootcmd.c create mode 100644 doc/board/emulation/common.rst diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 24916d867ee..b393205acb3 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -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 diff --git a/board/emulation/common/Makefile b/board/emulation/common/Makefile index c5b452e7e34..a91e4f16fef 100644 --- a/board/emulation/common/Makefile +++ b/board/emulation/common/Makefile @@ -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 diff --git a/board/emulation/common/bootcmd.c b/board/emulation/common/bootcmd.c new file mode 100644 index 00000000000..6fc7c618c8f --- /dev/null +++ b/board/emulation/common/bootcmd.c @@ -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 diff --git a/doc/board/emulation/common.rst b/doc/board/emulation/common.rst new file mode 100644 index 00000000000..90dde5f442a --- /dev/null +++ b/doc/board/emulation/common.rst @@ -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. diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst index 5a2a00ae225..6eccf7bad8a 100644 --- a/doc/board/emulation/index.rst +++ b/doc/board/emulation/index.rst @@ -8,6 +8,7 @@ Emulation acpi blkdev + common script qemu-arm qemu-mips diff --git a/doc/board/emulation/qemu-x86.rst b/doc/board/emulation/qemu-x86.rst index c2862e631ee..27f0d273f38 100644 --- a/doc/board/emulation/qemu-x86.rst +++ b/doc/board/emulation/qemu-x86.rst @@ -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 --------------- -- 2.43.0