[PATCH RFT 6/9] efi: add global.efi.bootargs for bootm'd EFI applications

Ahmad Fatoum a.fatoum at pengutronix.de
Thu Sep 10 03:19:37 PDT 2026


Helo Fabian,

On 9/10/26 12:16 PM, Fabian Pflug wrote:
> On Wed, 2026-08-26 at 14:17 +0200, Ahmad Fatoum wrote:
>> +	options = efi_bootargs_get(filetype_is_linux_efi_image(data->kernel_type));
> 
> At this point you are in bootm and want to boot an image. There should be another way to tell bootm to include the
> kernel command line arguments, because UKI's are MS-Dos executeables, even though they do contain the kernel to execute
> and bootm will just silently drop all kernel command line parameters here.
> 
> Making bootm.appendroot completly useless, which is an advantage of using barebox on x86.
> 
> Just indescrimently adding them would also not be good, as windows would also be the same filetype. But maybe add a
> magic variable to tell efi: "I'm sure, that this will be a kernel. Trust me bro!"

What does the UKI EFI stub do with extra command-line arguments?
Are they prepended? Appended? Do they replace the built-in command-line?
Does enabling secure boot change the behavior?

I don't have verified answers to these questions. If you can research
them, I can consider adapting the behavior here.

Cheers,
Ahmad

> 
> /Fabian
>> +	if (options) {
>> +		load_option = xstrdup_char_to_wchar(options);
>> +		load_option_size = (strlen(options) + 1) * sizeof(wchar_t);
>>  	}
>>  
>>  	file_path = efi_dp_from_file(AT_FDCWD, data->os_file);
>>  
>>  	pr_info("Loading %pD\n", file_path);
>> +	if (data->verbose && options)
>> +		pr_info("Load options: %s\n", options);
>> +
>> +	free(options);
>>  
>>  	/* Initialize EFI drivers */
>>  	efiret = efi_init_obj_list();
>> @@ -321,6 +322,14 @@ static int efi_loader_bootm(struct image_data *data)
>>  	/* Control is returned to us, disable EFI watchdog */
>>  	efi_set_watchdog(0);
>>  
>> +	/*
>> +	 * A still loaded driver would keep referencing the load options.
>> +	 * efi_set_load_options() tolerates the already deleted handle of an
>> +	 * application.
>> +	 */
>> +	efi_set_load_options(handle, 0, NULL);
>> +	free(load_option);
>> +
>>  	return -efi_errno(efiret);
>>  
>>  out:
>> diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
>> index fe2d27b7ff10..491bafb66898 100644
>> --- a/efi/payload/bootm.c
>> +++ b/efi/payload/bootm.c
>> @@ -22,7 +22,6 @@
>>  #include <string.h>
>>  #include <linux/err.h>
>>  #include <boot.h>
>> -#include <bootargs.h>
>>  #include <bootm.h>
>>  #include <fs.h>
>>  #include <libfile.h>
>> @@ -32,6 +31,7 @@
>>  #include <efi/payload/driver.h>
>>  #include <efi/error.h>
>>  #include <efi/initrd.h>
>> +#include <efi/bootargs.h>
>>  
>>  #include "image.h"
>>  
>> @@ -167,6 +167,7 @@ static int do_bootm_efi_stub(struct image_data *data)
>>  	bool image_freed = false;
>>  	efi_handle_t handle = NULL; /* silence compiler warning */
>>  	enum filetype type;
>> +	char *options;
>>  	int ret;
>>  
>>  	ret = efi_load_os(data, &loaded_image, &handle);
>> @@ -186,9 +187,11 @@ static int do_bootm_efi_stub(struct image_data *data)
>>  	if (data->dryrun)
>>  		goto unload_ramdisk;
>>  
>> -	ret = efi_execute_image(handle, loaded_image, true, type,
>> -				filetype_is_linux_efi_image(type) ?
>> -				linux_bootargs_get() : NULL);
>> +	options = efi_bootargs_get(filetype_is_linux_efi_image(type));
>> +
>> +	ret = efi_execute_image(handle, loaded_image, true, type, options);
>> +
>> +	free(options);
>>  
>>  	/* efi_execute_image takes care to unload the image on error,
>>  	 * so we set image_freed and fall through to freeing ramdisk
>> @@ -215,6 +218,7 @@ static int efi_app_execute(struct image_data *data)
>>  	struct efi_loaded_image *loaded_image;
>>  	efi_handle_t handle;
>>  	enum filetype type;
>> +	char *options;
>>  	int ret;
>>  
>>  	ret = efi_load_image(data->os_file, &loaded_image, &handle);
>> @@ -223,14 +227,19 @@ static int efi_app_execute(struct image_data *data)
>>  
>>  	type = file_detect_type(loaded_image->image_base, PAGE_SIZE);
>>  
>> +	options = efi_bootargs_get(filetype_is_linux_efi_image(type));
>> +
>>  	if (data->dryrun) {
>>  		BS->unload_image(handle);
>> +		free(options);
>>  		return 0;
>>  	}
>>  
>> -	return efi_execute_image(handle, loaded_image, true, type,
>> -				 filetype_is_linux_efi_image(type) ?
>> -				 linux_bootargs_get() : NULL);
>> +	ret = efi_execute_image(handle, loaded_image, true, type, options);
>> +
>> +	free(options);
>> +
>> +	return ret;
>>  }
>>  
>>  static int linux_efi_handover = true;
>> diff --git a/include/efi/bootargs.h b/include/efi/bootargs.h
>> new file mode 100644
>> index 000000000000..dfd17261ff9d
>> --- /dev/null
>> +++ b/include/efi/bootargs.h
>> @@ -0,0 +1,9 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef __EFI_BOOTARGS_H
>> +#define __EFI_BOOTARGS_H
>> +
>> +#include <linux/types.h>
>> +
>> +char *efi_bootargs_get(bool linux_image);
>> +
>> +#endif /* __EFI_BOOTARGS_H */
>> diff --git a/test/py/test_shell.py b/test/py/test_shell.py
>> index 23c2d5dbb0b6..05090ae07be0 100644
>> --- a/test/py/test_shell.py
>> +++ b/test/py/test_shell.py
>> @@ -155,3 +155,29 @@ def test_barebox_test_var_exists(barebox, barebox_config):
>>  
>>      # Clean up
>>      barebox.run_check('rm /tmp/testvars')
>> +
>> +
>> +def test_boot_bootargs_dyn_cleared(barebox, barebox_config):
>> +    skip_disabled(barebox_config, "CONFIG_CMD_BOOT", "CONFIG_CMD_GLOBAL",
>> +                  "CONFIG_CMD_ECHO")
>> +
>> +    barebox.run_check("echo -o /env/boot/dyntest '#!/bin/sh'")
>> +    barebox.run_check("echo -a /env/boot/dyntest "
>> +                      "'global linux.bootargs.dyn.test=linux-dyn'")
>> +    barebox.run_check("echo -a /env/boot/dyntest "
>> +                      "'global efi.bootargs.dyn.test=efi-dyn'")
>> +    barebox.run_check("echo -a /env/boot/dyntest "
>> +                      "'global efi.bootargs.nodyntest=efi-static'")
>> +
>> +    # Run the script, but don't actually boot anything
>> +    barebox.run("boot -d -d dyntest")
>> +
>> +    # .dyn. variables must not leak into subsequent boot entries
>> +    assert barebox.run_check("echo ${global.linux.bootargs.dyn.test}") == [""]
>> +    assert barebox.run_check("echo ${global.efi.bootargs.dyn.test}") == [""]
>> +    # ... but other variables are left alone
>> +    assert barebox.run_check("echo ${global.efi.bootargs.nodyntest}") == \
>> +        ["efi-static"]
>> +
>> +    barebox.run_check("global -r efi.bootargs.nodyntest")
>> +    barebox.run_check("rm /env/boot/dyntest")

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




More information about the barebox mailing list