[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