[PATCH] commands: implement new safemode command

Sascha Hauer s.hauer at pengutronix.de
Thu Dec 4 06:41:49 PST 2025


On Wed, Dec 03, 2025 at 01:09:52PM +0100, Ahmad Fatoum wrote:
> barebox has extensive support for manipulating the device tree it passes
> to Linux, which can be useful during bringup.
> 
> Let's collect some of this functionality into a safemode command in an
> attempt to gather that knowledge at one place.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
>  commands/Kconfig       |   7 +++
>  commands/Makefile      |   1 +
>  commands/safemode.c    | 109 +++++++++++++++++++++++++++++++++++++++++
>  drivers/mci/mci-core.c |   6 +--
>  include/mci.h          |   5 ++
>  5 files changed, 123 insertions(+), 5 deletions(-)
>  create mode 100644 commands/safemode.c
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 6bfc1499afdb..af3b65f35547 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -226,6 +226,13 @@ config CMD_MEMINFO
>  	  system bytes     =     282616
>  	  in use bytes     =     274752
>  
> +config CMD_SAFEMODE
> +	tristate
> +	prompt "safemode"
> +	select CMD_OF_PROPERTY
> +	help
> +	  Apply safe-mode defaults for next kernel boot.
> +
>  config CMD_CHECKLEAK
>  	tristate
>  	prompt "checkleak"
> diff --git a/commands/Makefile b/commands/Makefile
> index e7d65163ad80..657fb426ba3e 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_CMD_MW)		+= mw.o
>  obj-$(CONFIG_CMD_MEMCMP)	+= memcmp.o
>  obj-$(CONFIG_CMD_MEMCPY)	+= memcpy.o
>  obj-$(CONFIG_CMD_MEMSET)	+= memset.o
> +obj-$(CONFIG_CMD_SAFEMODE)	+= safemode.o
>  obj-$(CONFIG_CMD_EDIT)		+= edit.o
>  obj-$(CONFIG_CMD_ETHLOG)	+= ethlog.o
>  obj-$(CONFIG_CMD_EXEC)		+= exec.o
> diff --git a/commands/safemode.c b/commands/safemode.c
> new file mode 100644
> index 000000000000..9016869bc56e
> --- /dev/null
> +++ b/commands/safemode.c
> @@ -0,0 +1,109 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <command.h>
> +#include <getopt.h>
> +#include <mci.h>
> +#include <xfuncs.h>
> +#include <stdio.h>
> +#include <environment.h>
> +
> +#define	SAFEMODE_MMC		BIT(0)
> +#define	SAFEMODE_CONSOLE	BIT(1)
> +#define	SAFEMODE_BOOT		BIT(2)
> +
> +#define run_command_fmt(args...) ({	\
> +	char *__buf = xasprintf(args);	\
> +	if (verbose)			\
> +		printf("%s\n", __buf);	\
> +	int __ret = run_command(__buf);	\
> +	free(__buf);			\
> +	__ret;				\
> +})
> +
> +static void safemode_mmc(int verbose)
> +{
> +	struct mci *mci;
> +
> +	for_each_mci(mci) {
> +		const char *dev = dev_name(&mci->dev);
> +
> +		run_command_fmt("%s.broken_cd=1", dev);
> +		run_command_fmt("of_property -fs %s max-frequency '<52000000>'", dev);
> +		run_command_fmt("of_property -fs %s pinctrl-names default", dev);

This only works when there is an alias for the SD card and barebox uses
it for the device name and the kernel device tree has the same alias.
We usually overcome this by using of_get_reproducible_name() /
of_find_node_by_reproducible_name(). Not sure how to integrate this here
though.

> +	}
> +}
> +
> +static void safemode_console(int verbose)
> +{
> +	run_command_fmt("global.bootm.earlycon=1");
> +}
> +
> +static void safemode_boot(int verbose)
> +{
> +	if (IS_ENABLED(CONFIG_WATCHDOG))
> +		run_command_fmt("global.boot.watchdog_timeout=0");
> +
> +	if (IS_ENABLED(CONFIG_BOOTCHOOSER) &&
> +	    getenv_nonempty("global.bootchooser.targets"))
> +		run_command_fmt("bootchooser -a default -p defaut");

s/defaut/default/

> +
> +	if (IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL))
> +		run_command_fmt("global.linux.efi.handover=1");
> +}
> +
> +static int do_safemode(int argc, char *argv[])
> +{
> +	unsigned safemode = 0;
> +	int opt, verbose = 0;
> +
> +	while((opt = getopt(argc, argv, "mcbv")) > 0) {
> +		switch(opt) {
> +		case 'm':
> +			safemode |= SAFEMODE_MMC;
> +			break;
> +		case 'c':
> +			safemode |= SAFEMODE_CONSOLE;
> +			break;
> +		case 'b':
> +			safemode |= SAFEMODE_BOOT;
> +			break;
> +		case 'v':
> +			verbose++;
> +			break;
> +		default:
> +			return COMMAND_ERROR_USAGE;
> +		}
> +	}
> +
> +	if (argc != optind)
> +		return COMMAND_ERROR_USAGE;
> +
> +	if (!safemode)
> +		safemode = ~0;

With this "safemode" without arguments shows nothing but still does
something. Better print a message here.

> +
> +	if (safemode & SAFEMODE_MMC)
> +		safemode_mmc(verbose);
> +	if (safemode & SAFEMODE_CONSOLE)
> +		safemode_console(verbose);
> +	if (safemode & SAFEMODE_BOOT)
> +		safemode_boot(verbose);
> +
> +	return 0;
> +}
> +
> +BAREBOX_CMD_HELP_START(safemode)
> +BAREBOX_CMD_HELP_TEXT("Apply safe-mode defaults for next kernel boot.")
> +BAREBOX_CMD_HELP_TEXT("")
> +BAREBOX_CMD_HELP_TEXT("Options:")
> +BAREBOX_CMD_HELP_OPT ("-m",  "safe mmc settings")
> +BAREBOX_CMD_HELP_OPT ("-c",  "safe console settings")
> +BAREBOX_CMD_HELP_OPT ("-b",  "safe boot defaults")

-v is missing here.

Sascha

-- 
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