mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH RFC] bootm: support printing bootm parameters determined at runtime to file
Date: Wed, 10 Jan 2024 15:39:58 +0100	[thread overview]
Message-ID: <20240110143958.3773360-1-a.fatoum@pengutronix.de> (raw)

The barebox bootm command is often not called directly, but via
bootloader spec or FIT image boot handlers. For debugging, it can be
useful to reuse those boot handlers, but replace single artifacts, e.g.
using the barebox device tree instead of the bootloader-spec provided
device tree.

To make this easier, have boot -v -d (verbose + dry run) write a boot
script that reproduces the cancelled boot to /env/boot/cancelled.

The user can then edit the file and boot it manually.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 commands/bootm.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
 common/bootm.c   | 10 +++++-
 include/bootm.h  |  9 +++++
 3 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/commands/bootm.c b/commands/bootm.c
index 95d267135cdb..520f041b6bac 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -8,6 +8,7 @@
 #include <driver.h>
 #include <command.h>
 #include <image.h>
+#include <boot.h>
 #include <malloc.h>
 #include <environment.h>
 #include <asm/byteorder.h>
@@ -36,6 +37,90 @@
 #define BOOTM_OPTS BOOTM_OPTS_COMMON
 #endif
 
+int bootm_print_cmd(const char *file, const struct bootm_data *data)
+{
+	int fd = CONSOLE_STDOUT;
+	const char *bootargs;
+	const char *verify = "";
+
+	if (!IS_ENABLED(CONFIG_GLOBALVAR))
+		return -ENOSYS;
+
+	if (file) {
+		fd = creat(file, 0755);
+		if (fd < 0)
+			return fd;
+	}
+
+	dprintf(fd, "#!/bin/sh\n\n");
+
+	if (data->appendroot)
+		dprintf(fd, "global.bootm.appendroot=%u\n", data->appendroot);
+	if (data->root_dev)
+		dprintf(fd, "global.bootm.root_dev='%s'\n", data->root_dev);
+	if (data->provide_machine_id)
+		dprintf(fd, "global.bootm.machine_id=%u\n", data->provide_machine_id);
+
+	switch (data->verify) {
+	case BOOTM_VERIFY_NONE:
+		verify = "none";
+		break;
+	case BOOTM_VERIFY_HASH:
+		verify = "hash";
+		break;
+	case BOOTM_VERIFY_AVAILABLE:
+		verify = "available";
+		break;
+	case BOOTM_VERIFY_SIGNATURE:
+		verify = "signature";
+		break;
+	}
+
+	dprintf(fd, "global.bootm.verify=%s\n", verify);
+
+	dprintf(fd, "\n");
+
+	if (data->os_address != UIMAGE_SOME_ADDRESS)
+		dprintf(fd, "global.bootm.image.loadaddr=0x%08lx\n", data->os_address);
+	if (data->os_file)
+		dprintf(fd, "global.bootm.image='%s'\n", data->os_file);
+	if (data->oftree_file)
+		dprintf(fd, "global.bootm.oftree='%s'\n", data->oftree_file);
+#ifdef CONFIG_BOOTM_INITRD
+	if (data->initrd_file)
+		dprintf(fd, "global.bootm.initrd='%s'\n", data->initrd_file);
+
+	if (data->initrd_address != UIMAGE_INVALID_ADDRESS)
+		dprintf(fd, "global.bootm.initrd.loadaddr=0x%08lx\n", data->initrd_address);
+#endif
+	if (data->tee_file)
+		dprintf(fd, "global.bootm.tee_file='%s'\n", data->tee_file);
+
+	dprintf(fd, "\n");
+
+	bootargs = linux_bootargs_get();
+	if (bootargs)
+		dprintf(fd, "global linux.bootargs.dyn.concatenated='%s'\n", bootargs);
+
+	if (data->force || data->os_entry != UIMAGE_SOME_ADDRESS) {
+		/* We have no global variables for these two parameters yet, so
+		 * we just print a comment to alert the user to this fact
+		 */
+
+		dprintf(fd, "\n# bootm ");
+		if (data->force)
+				dprintf(fd, "-f ");
+		if (data->os_entry != UIMAGE_SOME_ADDRESS)
+				dprintf(fd, "-e %08lx ", data->os_entry);
+		dputc(fd, '\n');
+	}
+
+	if (file)
+		close(fd);
+
+	return 0;
+}
+
 static int do_bootm(int argc, char *argv[])
 {
 	int opt;
diff --git a/common/bootm.c b/common/bootm.c
index 29ea13e28cb8..3ecd788e7b16 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -825,8 +825,16 @@ int bootm_boot(struct bootm_data *bootm_data)
 	}
 
 	ret = handler->bootm(data);
-	if (data->dryrun)
+	if (data->dryrun) {
 		pr_info("Dryrun. Aborted\n");
+		if (bootm_verbose(data)) {
+			const char *file = "/env/boot/cancelled";
+			if (!bootm_print_cmd(file, bootm_data))
+				pr_info("Boot script written to %s\n", file);
+			else
+				pr_warn("Boot script write to %s failed: %m\n", file);
+		}
+	}
 
 err_out:
 	if (data->os_res)
diff --git a/include/bootm.h b/include/bootm.h
index ee2b574521db..53d2905ca992 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -41,6 +41,15 @@ struct bootm_data {
 
 int bootm_boot(struct bootm_data *data);
 
+#ifdef CONFIG_CMD_BOOTM
+int bootm_print_cmd(const char *file, const struct bootm_data *data);
+#else
+static inline int bootm_print_cmd(const char *file, const struct bootm_data *data)
+{
+	return -ENOSYS;
+}
+#endif
+
 struct image_data {
 	/* simplest case. barebox has already loaded the os here */
 	struct resource *os_res;
-- 
2.39.2




             reply	other threads:[~2024-01-10 14:41 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-10 14:39 Ahmad Fatoum [this message]
2024-01-10 15:18 ` Sascha Hauer
2024-01-10 15:26   ` Ahmad Fatoum
2024-01-11  7:10     ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240110143958.3773360-1-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox