[RFC PATCH 2/2] common: console: Add support of passing the saved console log to the OS

Bence Cs csokas.bence at prolan.hu
Thu Dec 28 00:30:12 CET 2023


CONFIG_CONSOLE_RECORD_SAVE option allows for the recorded console log to
be saved to a memory location, along with some metadata. This memory
address is then passed to the booted OS via command line.

Signed-off-by: Bence Cs <csokas.bence at prolan.hu>
---

Notes:
    Some improvements to consider:
    * pass CONFIG_CONSOLE_RECORD_SAVE_BASE via FDT
    * or possibly add it to U-Boot env, so scripts can choose the passing method
    * find a better place to call console_record_save(), ideally as late as possible
    
    Link: https://lists.denx.de/pipermail/u-boot/2023-December/541138.html

 boot/bootm.c      | 27 +++++++++++++++++++++++++--
 common/Kconfig    | 13 +++++++++++++
 common/console.c  | 13 +++++++++++++
 include/console.h | 19 +++++++++++++++++++
 4 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/boot/bootm.c b/boot/bootm.c
index 7a050ed41a..7f67f6a58e 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -10,6 +10,7 @@
 #include <bootstage.h>
 #include <cli.h>
 #include <command.h>
+#include <console.h>
 #include <cpu_func.h>
 #include <env.h>
 #include <errno.h>
@@ -857,6 +858,16 @@ static int process_subst(char *buf, int maxlen)
 	return ret;
 }
 
+static int append_bootlog_base(char *buf, int maxlen)
+{
+	int size = strlen(buf);
+
+	if (size + 1 + strlen(" bootlog.base=0x" + 8 > maxlen)
+		return -ENOSPC;
+
+	sprintf(buf + size, " bootlog.base=0x%08X", CONFIG_CONSOLE_RECORD_SAVE_BASE);
+}
+
 int bootm_process_cmdline(char *buf, int maxlen, int flags)
 {
 	int ret;
@@ -875,6 +886,11 @@ int bootm_process_cmdline(char *buf, int maxlen, int flags)
 		if (ret)
 			return log_msg_ret("subst", ret);
 	}
+	if (IS_ENABLED(CONFIG_CONSOLE_RECORD_SAVE)) {
+		ret = append_bootlog_base(buf, maxlen);
+		if (ret)
+			return log_msg_ret("bootlogbase", ret);
+	}
 
 	return 0;
 }
@@ -882,7 +898,7 @@ int bootm_process_cmdline(char *buf, int maxlen, int flags)
 int bootm_process_cmdline_env(int flags)
 {
 	const int maxlen = MAX_CMDLINE_SIZE;
-	bool do_silent;
+	bool do_silent, do_pass_record;
 	const char *env;
 	char *buf;
 	int ret;
@@ -890,7 +906,8 @@ int bootm_process_cmdline_env(int flags)
 	/* First check if any action is needed */
 	do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
 	    !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT);
-	if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
+	do_pass_record = IS_ENABLED(CONFIG_CONSOLE_RECORD_SAVE);
+	if (!do_silent && !do_pass_record && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
 		return 0;
 
 	env = env_get("bootargs");
@@ -1056,6 +1073,13 @@ int bootm_run_states(struct bootm_info *bmi, int states)
 	}
 #endif
 
+	if (ret)
+		return ret;
+
+#if CONFIG_IS_ENABLED(CONSOLE_RECORD_SAVE)
+	console_record_save();
+#endif /* CONFIG_IS_ENABLED(CONSOLE_RECORD_SAVE) */
+
 	/* From now on, we need the OS boot function */
 	if (ret)
 		return ret;
diff --git a/common/Kconfig b/common/Kconfig
index 0283701f1d..d70fa748c2 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -52,6 +52,19 @@ config CONSOLE_RECORD_IN_SIZE
 	  The buffer is allocated immediately after the malloc() region is
 	  ready.
 
+config CONSOLE_RECORD_SAVE
+	bool "Save a copy of the recording for the OS to read"
+	depends on CONSOLE_RECORD
+	help
+	  This option makes a copy of the recorded console log available at a fixed
+	  RAM location, so that the booted OS can read it
+
+config CONSOLE_RECORD_SAVE_BASE
+	hex "Memory location to save the log to"
+	depends on CONSOLE_RECORD_SAVE
+	help
+	  The base address for the saved copy (will be passed to the booted OS)
+
 config SYS_CBSIZE
 	int "Console input buffer size"
 	default 2048 if ARCH_TEGRA || ARCH_VERSAL || ARCH_ZYNQ || ARCH_ZYNQMP || \
diff --git a/common/console.c b/common/console.c
index 1ffda49c87..77a41d99f7 100644
--- a/common/console.c
+++ b/common/console.c
@@ -860,6 +860,19 @@ int console_in_puts(const char *str)
 
 #endif
 
+#if CONFIG_IS_ENABLED(CONSOLE_RECORD_SAVE)
+void console_record_save(void)
+{
+	struct console_record_log *log = (struct console_record_log *)(CONFIG_CONSOLE_RECORD_SAVE_BASE);
+	char *buf = (char *)(log + 1);
+	// buffer starts at the end of the log struct
+	log->version = 1U;
+	log->uboot_version = U_BOOT_CURRENT_VERSION_CODE;
+	log->len = membuff_get((struct membuff *)&gd->console_out, buf, console_record_avail());
+	log->magic = CONSOLE_RECORD_LOG_MAGIC;
+}
+#endif /* CONFIG_IS_ENABLED(CONSOLE_RECORD_SAVE) */
+
 /* test if ctrl-c was pressed */
 static int ctrlc_disabled = 0;	/* see disable_ctrl() */
 static int ctrlc_was_pressed = 0;
diff --git a/include/console.h b/include/console.h
index e29817e57b..7a1b5ebffd 100644
--- a/include/console.h
+++ b/include/console.h
@@ -133,6 +133,25 @@ static inline int console_in_puts(const char *str)
 
 #endif /* !CONFIG_CONSOLE_RECORD */
 
+#if CONFIG_IS_ENABLED(CONSOLE_RECORD_SAVE)
+struct console_record_log {
+	u32 magic;
+	u32 version;
+	u32 uboot_version;
+	u32 len;
+};
+
+/*
+ * Magic value for struct console_record_log
+ */
+#define CONSOLE_RECORD_LOG_MAGIC 0xB0021062
+
+/*
+ * Saves the recorded console log to CONSOLE_RECORD_SAVE_BASE
+ */
+void console_record_save(void);
+#endif /* CONFIG_IS_ENABLED(CONSOLE_RECORD_SAVE) */
+
 /**
  * console_announce_r() - print a U-Boot console on non-serial consoles
  *
-- 
2.25.1




More information about the U-Boot mailing list