refactor(core): introduce debugging console
What changed, and why it matters
This commit refactors how debug output is handled in Trezor firmware. It replaces direct USB virtual-serial and SWO debug output with a new 'debugging console' abstraction, adds optional read support, and exposes it to less-privileged application code through system calls. The change is described by the vendor as a refactor with no changelog entry. It does not by itself create a known exploit, but it widens the attack surface by making a debug channel readable and writable from user-space firmware, which could matter if the feature is enabled in production or combined with other bugs.
Treat this as a defensive review item, not a confirmed vulnerability. Verify that production release builds do not set `dbg_console` or `USE_DBG_CONSOLE`. If debug builds are used for factory provisioning or field diagnostics, ensure the console is read-only or disabled and that the verifier correctly rejects out-of-bounds buffers. Audit any future commits that add console commands or REPL-like behavior over this channel.
Security signals we found
New debug read path exposed to application firmware via syscall
MicroPython stdio redirected to debug console instead of USB VCP when USE_DBG_CONSOLE is set
Debug console feature is build-time gated but could be enabled in production images
Verifier added for read/write syscalls, indicating privileged/unprivileged boundary crossing
Old direct ITM/SWO output replaced with abstraction that also supports USB VCP input/output
Evidence from the diff
The patch introduces sys/dbg/dbg_console.{c,h} and platform backends for STM32 and Unix. It removes the old dbg_printf/dbg_vprintf helpers and replaces them with dbg_console_read, dbg_console_write, dbg_console_printf, and a dbg_printf alias. On STM32 the backend can route debug output to ITM/SWO, USB VCP, or SystemView depending on build flags. The console is initialized during system_init(). New syscalls SYSCALL_DBG_CONSOLE_READ and SYSCALL_DBG_CONSOLE_WRITE are added with verifier wrappers that probe user memory access before calling the kernel implementation. The firmware’s MicroPython stdio hooks (mp_hal_stdin_rx_chr/mp_hal_stdout_tx_strn) are switched to use the debug console only when USE_DBG_CONSOLE is defined; otherwise they become no-ops. Build scripts gate the feature on a dbg_console feature flag and require USE_USB_IFACE_VCP when VCP mode is selected.
Changed components
core/embed/sys/dbg/dbg_console.ccore/embed/sys/dbg/stm32/dbg_console_backend.ccore/embed/sys/dbg/unix/dbg_console_backend.ccore/embed/sys/syscall/stm32/syscall_dispatch.ccore/embed/sys/syscall/stm32/syscall_stubs.ccore/embed/sys/syscall/stm32/syscall_verifiers.ccore/embed/projects/firmware/mphalport.ccore/embed/projects/unix/main.ccore/embed/sec/optiga/optiga_config.ccore/site_scons/models/stm32f4_common.pycore/site_scons/models/stm32u5_common.pycore/site_scons/models/unix_common.pyInspect captured patch +362 / −98
diff --git a/core/embed/projects/firmware/mphalport.c b/core/embed/projects/firmware/mphalport.c
index e38f2a43..0b138cde 100644
--- a/core/embed/projects/firmware/mphalport.c
+++ b/core/embed/projects/firmware/mphalport.c
@@ -21,22 +21,26 @@
#include "py/mphal.h"
-#include <io/usb_config.h>
#include <sys/systick.h>
+#ifdef USE_DBG_CONSOLE
+#include <sys/dbg_console.h>
+#endif
+
int mp_hal_stdin_rx_chr(void) {
+#ifdef USE_DBG_CONSOLE
uint8_t c = 0;
- int r = syshandle_read(SYSHANDLE_USB_VCP, &c, sizeof(c));
- (void)r;
+ dbg_console_read(&c, sizeof(c));
return c;
+#else
+ return 0;
+#endif
}
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
- // The write timeout defaults to 0, because otherwise when the VCP receive
- // buffer on the host gets full, the timeout will block device operation.
- int r = syshandle_write_blocking(SYSHANDLE_USB_VCP, (const uint8_t *)str, len,
- BLOCK_ON_VCP ? 1000 : 0);
- (void)r;
+#ifdef USE_DBG_CONSOLE
+ dbg_console_write(str, len);
+#endif
}
// Dummy implementation required by ports/stm32/gccollect.c.
diff --git a/core/embed/projects/unix/main.c b/core/embed/projects/unix/main.c
index 58882b46..3e494a65 100644
--- a/core/embed/projects/unix/main.c
+++ b/core/embed/projects/unix/main.c
@@ -39,6 +39,7 @@
#include <io/display.h>
#include <io/usb_config.h>
#include <sec/secret.h>
+#include <sys/dbg_console.h>
#include <sys/system.h>
#include <sys/systimer.h>
#include <util/flash.h>
@@ -84,9 +85,8 @@ long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4);
STATIC void stderr_print_strn(void *env, const char *str, size_t len) {
(void)env;
- ssize_t dummy = write(STDERR_FILENO, str, len);
+ dbg_console_write(str, len);
mp_uos_dupterm_tx_strn(str, len);
- (void)dummy;
}
const mp_print_t mp_stderr_print = {NULL, stderr_print_strn};
diff --git a/core/embed/sec/optiga/optiga_config.c b/core/embed/sec/optiga/optiga_config.c
index b38294d0..b616dc43 100644
--- a/core/embed/sec/optiga/optiga_config.c
+++ b/core/embed/sec/optiga/optiga_config.c
@@ -29,26 +29,33 @@
#include "memzero.h"
-#ifdef USE_OPTIGA_LOGGING
+#ifdef USE_DBG_CONSOLE
+#include <sys/dbg_console.h>
+#endif
+
+#if defined(USE_DBG_CONSOLE) && defined(USE_OPTIGA_LOGGING)
#include <inttypes.h>
#if 1 // color log
#define OPTIGA_LOG_FORMAT \
- "%" PRIu32 " \x1b[35moptiga\x1b[0m \x1b[32mDEBUG\x1b[0m %s: "
+ "%d.%03d \x1b[35moptiga\x1b[0m \x1b[32mDEBUG\x1b[0m %s: "
#else
-#define OPTIGA_LOG_FORMAT "%" PRIu32 " optiga DEBUG %s: "
+#define OPTIGA_LOG_FORMAT "%d.%03d optiga DEBUG %s: "
#endif
static void optiga_log_hex(const char *prefix, const uint8_t *data,
size_t data_size) {
- printf(OPTIGA_LOG_FORMAT, hal_ticks_ms() * 1000, prefix);
+ ticks_t now = hal_ticks_ms();
+ uint32_t sec = now / 1000;
+ uint32_t msec = now % 1000;
+ dbg_console_printf(OPTIGA_LOG_FORMAT, sec, msec, prefix);
for (size_t i = 0; i < data_size; i++) {
- printf("%02x", data[i]);
+ dbg_console_printf("%02x", data[i]);
}
- printf("\n");
+ dbg_console_printf("\n");
}
#endif
void optiga_init_and_configure(void) {
-#ifdef USE_OPTIGA_LOGGING
+#if defined(USE_DBG_CONSOLE) && defined(USE_OPTIGA_LOGGING)
// command log is relatively quiet so we enable it in debug builds
optiga_command_set_log_hex(optiga_log_hex);
// transport log can be spammy, uncomment if you want it:
diff --git a/core/embed/sys/dbg/dbg_console.c b/core/embed/sys/dbg/dbg_console.c
new file mode 100644
index 00000000..9289162b
--- /dev/null
+++ b/core/embed/sys/dbg/dbg_console.c
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <trezor_rtl.h>
+
+#include <rtl/mini_printf.h>
+#include <sys/dbg_console.h>
+
+void dbg_console_vprintf(const char *fmt, va_list args) {
+ char temp[80];
+ mini_vsnprintf(temp, sizeof(temp), fmt, args);
+ dbg_console_write(temp, strnlen(temp, sizeof(temp)));
+}
+
+void dbg_console_printf(const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ dbg_console_vprintf(fmt, args);
+ va_end(args);
+}
diff --git a/core/embed/sys/dbg/inc/sys/dbg_console.h b/core/embed/sys/dbg/inc/sys/dbg_console.h
new file mode 100644
index 00000000..4be29f55
--- /dev/null
+++ b/core/embed/sys/dbg/inc/sys/dbg_console.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <trezor_types.h>
+
+#include <stdarg.h>
+
+#ifdef KERNEL_MODE
+
+/**
+ * @brief Initialize the debugging console.
+ *
+ * Called when system starts up, during `system_init()`.
+ */
+void dbg_console_init(void);
+
+#endif
+
+/**
+ * @brief Read data from the debugging console.
+ *
+ * Not all platforms support reading from the debugging console.
+ *
+ * @param buffer Pointer to the buffer where data will be stored.
+ * @param buffer_size Size of the buffer in bytes.
+ *
+ * @return Number of bytes read, or a negative error code on failure.
+ */
+ssize_t dbg_console_read(void* buffer, size_t buffer_size);
+
+/**
+ * @brief Write data to the debugging console.
+ *
+ * @param data Pointer to the data to write.
+ * @param data_size Size of the data in bytes.
+ */
+void dbg_console_write(const void* data, size_t data_size);
+
+/**
+ * @brief vprintf-like function for debugging.
+ *
+ * @param fmt Format string.
+ * @param args Variable argument list.
+ */
+void dbg_console_vprintf(const char* fmt, va_list args);
+
+/**
+ * @brief printf-like function for debugging.
+ *
+ * @param fmt Format string.
+ * @param ... Variable arguments.
+ */
+void dbg_console_printf(const char* fmt, ...);
+
+/**
+ * @brief Short alias for `dbg_console_printf()`.
+ */
+#define dbg_printf dbg_console_printf
diff --git a/core/embed/sys/dbg/inc/sys/dbg_printf.h b/core/embed/sys/dbg/inc/sys/dbg_printf.h
deleted file mode 100644
index 72a8edd3..00000000
--- a/core/embed/sys/dbg/inc/sys/dbg_printf.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of the Trezor project, https://trezor.io/
- *
- * Copyright (c) SatoshiLabs
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#ifdef KERNEL_MODE
-
-// vprintf-like functions for debugging
-void dbg_vprintf(const char* fmt, va_list args);
-
-// printf-like functions for debugging
-void dbg_printf(const char* fmt, ...);
-
-#endif // KERNEL_MODE
diff --git a/core/embed/sys/dbg/stm32/dbg_console_backend.c b/core/embed/sys/dbg/stm32/dbg_console_backend.c
new file mode 100644
index 00000000..cdcc81ea
--- /dev/null
+++ b/core/embed/sys/dbg/stm32/dbg_console_backend.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef KERNEL_MODE
+
+#include <trezor_rtl.h>
+
+#include <sys/irq.h>
+
+#include <sys/dbg_console.h>
+#include <sys/sysevent.h>
+
+#if defined(USE_DBG_CONSOLE_VCP) && !defined(USE_USB_IFACE_VCP)
+#error "USE_DBG_CONSOLE_VCP requires USE_USB_IFACE_VCP"
+#endif
+
+
+void dbg_console_init(void) {}
+
+ssize_t dbg_console_read(void *buffer, size_t buffer_size) { return 0; }
+
+#ifdef USE_DBG_CONSOLE_SWO
+static void itm_swo_write(const void *data, size_t data_size) {
+ irq_key_t irq_key = irq_lock();
+
+ for (size_t i = 0; i < data_size; i++) {
+ ITM_SendChar(((const char *)data)[i]);
+ }
+
+ irq_unlock(irq_key);
+}
+#endif
+
+#ifdef USE_DBG_CONSOLE_VCP
+static void usb_vcp_write(const void *data, size_t data_size) {
+#ifdef BLOCK_ON_VCP
+ syshandle_write_blocking(SYSHANDLE_USB_VCP, data, data_size, 1000);
+#else
+ syshandle_write(SYSHANDLE_USB_VCP, data, data_size);
+#endif
+}
+#endif
+
+void dbg_console_write(const void *data, size_t data_size) {
+#ifdef USE_DBG_CONSOLE_SWO
+ itm_swo_write(data, data_size);
+#endif
+#ifdef USE_DBG_CONSOLE_VCP
+ usb_vcp_write(data, data_size);
+#endif
+}
+
+#endif // KERNEL_MODE
diff --git a/core/embed/sys/dbg/stm32/dbg_printf.c b/core/embed/sys/dbg/stm32/dbg_printf.c
deleted file mode 100644
index f15b894d..00000000
--- a/core/embed/sys/dbg/stm32/dbg_printf.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file is part of the Trezor project, https://trezor.io/
- *
- * Copyright (c) SatoshiLabs
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifdef KERNEL_MODE
-
-#include <rtl/mini_printf.h>
-#include <stdarg.h>
-#include <sys/irq.h>
-
-void dbg_vprintf(const char* fmt, va_list args) {
- char temp[80];
- mini_vsnprintf(temp, sizeof(temp), fmt, args);
-
- irq_key_t irq_key = irq_lock();
- for (size_t i = 0; i < sizeof(temp); i++) {
- if (temp[i] == '\0') {
- break;
- }
- ITM_SendChar(temp[i]);
- }
- irq_unlock(irq_key);
-}
-
-void dbg_printf(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- dbg_vprintf(fmt, args);
- va_end(args);
-}
-
-#endif // KERNEL_MODE
diff --git a/core/embed/sys/dbg/unix/dbg_console_backend.c b/core/embed/sys/dbg/unix/dbg_console_backend.c
new file mode 100644
index 00000000..85c0e747
--- /dev/null
+++ b/core/embed/sys/dbg/unix/dbg_console_backend.c
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/dbg_console.h>
+
+void dbg_console_init(void) {}
+
+ssize_t dbg_console_read(void *buffer, size_t buffer_size) { return 0; }
+
+void dbg_console_write(const void *data, size_t data_size) {
+ int result = write(STDERR_FILENO, data, data_size);
+ (void)result;
+}
diff --git a/core/embed/sys/syscall/inc/sys/syscall_numbers.h b/core/embed/sys/syscall/inc/sys/syscall_numbers.h
index e3fe19c6..c49c0718 100644
--- a/core/embed/sys/syscall/inc/sys/syscall_numbers.h
+++ b/core/embed/sys/syscall/inc/sys/syscall_numbers.h
@@ -44,6 +44,9 @@ typedef enum {
SYSCALL_SYSHANDLE_READ,
SYSCALL_SYSHANDLE_WRITE,
+ SYSCALL_DBG_CONSOLE_READ,
+ SYSCALL_DBG_CONSOLE_WRITE,
+
SYSCALL_BOOT_IMAGE_CHECK,
SYSCALL_BOOT_IMAGE_REPLACE,
diff --git a/core/embed/sys/syscall/stm32/syscall_dispatch.c b/core/embed/sys/syscall/stm32/syscall_dispatch.c
index 95d42128..388fcc2a 100644
--- a/core/embed/sys/syscall/stm32/syscall_dispatch.c
+++ b/core/embed/sys/syscall/stm32/syscall_dispatch.c
@@ -167,6 +167,20 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[0] = syshandle_write__verified(handle, data, data_size);
} break;
+#ifdef USE_DBG_CONSOLE
+ case SYSCALL_DBG_CONSOLE_READ: {
+ void *buffer = (void *)args[0];
+ size_t buffer_size = (size_t)args[1];
+ args[0] = dbg_console_read__verified(buffer, buffer_size);
+ } break;
+
+ case SYSCALL_DBG_CONSOLE_WRITE: {
+ const void *data = (const void *)args[0];
+ size_t data_size = (size_t)args[1];
+ dbg_console_write__verified(data, data_size);
+ } break;
+#endif
+
case SYSCALL_BOOT_IMAGE_CHECK: {
const boot_image_t *image = (const boot_image_t *)args[0];
args[0] = boot_image_check__verified(image);
diff --git a/core/embed/sys/syscall/stm32/syscall_stubs.c b/core/embed/sys/syscall/stm32/syscall_stubs.c
index 00a78296..ed7b3750 100644
--- a/core/embed/sys/syscall/stm32/syscall_stubs.c
+++ b/core/embed/sys/syscall/stm32/syscall_stubs.c
@@ -95,6 +95,23 @@ ssize_t syshandle_write(syshandle_t handle, const void *data,
SYSCALL_SYSHANDLE_WRITE);
}
+// =============================================================================
+// dbg_console.h
+// =============================================================================
+
+#ifdef USE_DBG_CONSOLE
+
+ssize_t dbg_console_read(void *buffer, size_t buffer_size) {
+ return syscall_invoke2((uint32_t)buffer, buffer_size,
+ SYSCALL_DBG_CONSOLE_READ);
+}
+
+void dbg_console_write(const void *data, size_t data_size) {
+ syscall_invoke2((uint32_t)data, data_size, SYSCALL_DBG_CONSOLE_WRITE);
+}
+
+#endif // USE_DBG_CONSOLE
+
// =============================================================================
// boot_image.h
// =============================================================================
diff --git a/core/embed/sys/syscall/stm32/syscall_verifiers.c b/core/embed/sys/syscall/stm32/syscall_verifiers.c
index 2b4ccfff..bac49396 100644
--- a/core/embed/sys/syscall/stm32/syscall_verifiers.c
+++ b/core/embed/sys/syscall/stm32/syscall_verifiers.c
@@ -90,6 +90,36 @@ access_violation:
// ---------------------------------------------------------------------
+#ifdef USE_DBG_CONSOLE
+
+ssize_t dbg_console_read__verified(void *buffer, size_t buffer_size) {
+ if (!probe_write_access(buffer, buffer_size)) {
+ goto access_violation;
+ }
+
+ return dbg_console_read(buffer, buffer_size);
+
+access_violation:
+ apptask_access_violation();
+ return -1;
+}
+
+void dbg_console_write__verified(const void *data, size_t data_size) {
+ if (!probe_read_access(data, data_size)) {
+ goto access_violation;
+ }
+
+ dbg_console_write(data, data_size);
+ return;
+
+access_violation:
+ apptask_access_violation();
+}
+
+#endif // USE_DBG_CONSOLE
+
+// ---------------------------------------------------------------------
+
bool boot_image_check__verified(const boot_image_t *image) {
if (!probe_read_access(image, sizeof(*image))) {
goto access_violation;
diff --git a/core/embed/sys/syscall/stm32/syscall_verifiers.h b/core/embed/sys/syscall/stm32/syscall_verifiers.h
index a33fd73d..78d54f1a 100644
--- a/core/embed/sys/syscall/stm32/syscall_verifiers.h
+++ b/core/embed/sys/syscall/stm32/syscall_verifiers.h
@@ -45,6 +45,17 @@ void system_exit_error__verified(const char *title, size_t title_len,
void system_exit_fatal__verified(const char *message, size_t message_len,
const char *file, size_t file_len, int line);
+// ---------------------------------------------------------------------
+#ifdef USE_DBG_CONSOLE
+
+#include <sys/dbg_console.h>
+
+ssize_t dbg_console_read__verified(void *buffer, size_t buffer_size);
+
+void dbg_console_write__verified(const void *data, size_t data_size);
+
+#endif
+
// ---------------------------------------------------------------------
#include <sys/bootutils.h>
diff --git a/core/embed/sys/task/stm32/system.c b/core/embed/sys/task/stm32/system.c
index 526400a5..7a27ba57 100644
--- a/core/embed/sys/task/stm32/system.c
+++ b/core/embed/sys/task/stm32/system.c
@@ -33,6 +33,10 @@
#include <sys/systimer.h>
#include <sys/sysutils.h>
+#ifdef USE_DBG_CONSOLE
+#include <sys/dbg_console.h>
+#endif
+
#ifdef USE_SDRAM
#include <sys/sdram.h>
#endif
@@ -67,6 +71,9 @@ void system_init(systask_error_handler_t error_handler) {
#ifdef KERNEL
syscall_ipc_init();
#endif
+#ifdef USE_DBG_CONSOLE
+ dbg_console_init();
+#endif
}
void system_deinit(void) {
diff --git a/core/embed/sys/task/unix/system.c b/core/embed/sys/task/unix/system.c
index 69179310..68643ad0 100644
--- a/core/embed/sys/task/unix/system.c
+++ b/core/embed/sys/task/unix/system.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <sys/bootutils.h>
+#include <sys/dbg_console.h>
#include <sys/system.h>
#include <sys/systick.h>
#include <sys/systimer.h>
@@ -32,6 +33,7 @@ void system_init(systask_error_handler_t error_handler) {
g_error_handler = error_handler;
systick_init();
systimer_init();
+ dbg_console_init();
}
void system_deinit(void) { systick_deinit(); }
diff --git a/core/site_scons/models/stm32f4_common.py b/core/site_scons/models/stm32f4_common.py
index e7cea83a..63e31290 100644
--- a/core/site_scons/models/stm32f4_common.py
+++ b/core/site_scons/models/stm32f4_common.py
@@ -18,7 +18,6 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
"embed/sec/secure_aes/inc",
"embed/sec/time_estimate/inc",
"embed/sys/bsp/stm32f4",
- "embed/sys/dbg/inc",
"embed/sys/irq/inc",
"embed/sys/linker/inc",
"embed/sys/mpu/inc",
@@ -72,7 +71,6 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
"embed/sec/secret/stm32f4/secret_keys.c",
"embed/sec/storage/stm32f4/storage_salt.c",
"embed/sec/time_estimate/stm32/time_estimate.c",
- "embed/sys/dbg/stm32/dbg_printf.c",
"embed/sys/irq/stm32/irq.c",
"embed/sys/linker/linker_utils.c",
"embed/sys/mpu/stm32f4/mpu.c",
@@ -106,6 +104,23 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
"embed/util/unit_properties/stm32/unit_properties.c",
]
+ if "dbg_console" in features_wanted:
+ sources += [
+ "embed/sys/dbg/dbg_console.c",
+ "embed/sys/dbg/stm32/dbg_console_backend.c",
+ ]
+ paths += ["embed/sys/dbg/inc"]
+ defines += [("USE_DBG_CONSOLE", "1")]
+
+ if env.get("DBG_CONSOLE") == "VCP" and "usb" in features_wanted:
+ features_wanted += ["usb_iface_vcp"]
+ defines += ["USE_DBG_CONSOLE_VCP"]
+ elif env.get("DBG_CONSOLE") == "SWO":
+ defines += ["USE_DBG_CONSOLE_SWO"]
+ elif env.get("DBG_CONSOLE") == "SYSTEM_VIEW":
+ features_wanted += ["system_view"]
+ defines += ["USE_DBG_CONSOLE_SYSTEM_VIEW"]
+
if "usb" in features_wanted:
sources += [
"embed/io/usb/stm32/usb_class_hid.c",
diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py
index cb402033..3ca35da5 100644
--- a/core/site_scons/models/stm32u5_common.py
+++ b/core/site_scons/models/stm32u5_common.py
@@ -20,7 +20,6 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
"embed/sec/secure_aes/inc",
"embed/sec/time_estimate/inc",
"embed/sys/bsp/stm32u5",
- "embed/sys/dbg/inc",
"embed/sys/irq/inc",
"embed/sys/linker/inc",
"embed/sys/mpu/inc",
@@ -93,7 +92,6 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
"embed/sec/secure_aes/stm32u5/secure_aes_unpriv.c",
"embed/sec/storage/stm32u5/storage_salt.c",
"embed/sec/time_estimate/stm32/time_estimate.c",
- "embed/sys/dbg/stm32/dbg_printf.c",
"embed/sys/irq/stm32/irq.c",
"embed/sys/linker/linker_utils.c",
"embed/sys/mpu/stm32u5/mpu.c",
@@ -132,6 +130,23 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
"embed/util/unit_properties/stm32/unit_properties.c",
]
+ if "dbg_console" in features_wanted:
+ sources += [
+ "embed/sys/dbg/dbg_console.c",
+ "embed/sys/dbg/stm32/dbg_console_backend.c",
+ ]
+ paths += ["embed/sys/dbg/inc"]
+ defines += [("USE_DBG_CONSOLE", "1")]
+
+ if env.get("DBG_CONSOLE") == "VCP" and "usb" in features_wanted:
+ features_wanted += ["usb_iface_vcp"]
+ defines += ["USE_DBG_CONSOLE_VCP"]
+ elif env.get("DBG_CONSOLE") == "SWO":
+ defines += ["USE_DBG_CONSOLE_SWO"]
+ elif env.get("DBG_CONSOLE") == "SYSTEM_VIEW":
+ features_wanted += ["system_view"]
+ defines += ["USE_DBG_CONSOLE_SYSTEM_VIEW"]
+
if "applet" in features_wanted:
sources += ["embed/sys/task/stm32/applet.c"]
diff --git a/core/site_scons/models/unix_common.py b/core/site_scons/models/unix_common.py
index 7567058f..5190e745 100644
--- a/core/site_scons/models/unix_common.py
+++ b/core/site_scons/models/unix_common.py
@@ -15,6 +15,7 @@ def unix_common_files(env, features_wanted, defines, sources, paths):
"embed/sec/random_delays/inc",
"embed/sec/time_estimate/inc",
"embed/sys/bsp/inc",
+ "embed/sys/dbg/inc",
"embed/sec/rng/inc",
"embed/sec/monoctr/inc",
"embed/sec/secret/inc",
@@ -39,6 +40,8 @@ def unix_common_files(env, features_wanted, defines, sources, paths):
"embed/sec/monoctr/unix/monoctr.c",
"embed/sec/rng/unix/rng.c",
"embed/sec/time_estimate/unix/time_estimate.c",
+ "embed/sys/dbg/dbg_console.c",
+ "embed/sys/dbg/unix/dbg_console_backend.c",
"embed/sys/mpu/unix/mpu.c",
"embed/sys/startup/unix/bootutils.c",
"embed/sys/task/sysevent.c",
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.