From f72d1684e521ba60da5fce8a71ae90494b960164 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 19 Nov 2024 21:35:31 -0500 Subject: [PATCH] kernel/debug: Initialize the frame buffer console much earlier, if possible. Previously it was not initialized until "post-VM", but there are a number of ways VM initialization can go wrong that it would be nice to know about without needing a serial port. On arches which map the whole physical memory into the kernel address space (x86_64, at least), we can get the bluescreen facility initialized using KERNEL_PMAP_BASE. On other architectures, we just fail to init then, and do the usual setup later on. A slight bit of extra code cleanup in blue_screen_init_early: we now just call module->info.std_ops() rather than a frame-buffer-console specific method. --- headers/private/kernel/frame_buffer_console.h | 1 + src/system/kernel/debug/blue_screen.cpp | 32 +++++++++++++------ src/system/kernel/debug/blue_screen.h | 3 +- src/system/kernel/debug/debug.cpp | 7 ++-- .../kernel/debug/frame_buffer_console.cpp | 21 +++++++++++- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/headers/private/kernel/frame_buffer_console.h b/headers/private/kernel/frame_buffer_console.h index a43a1b62ad..dd7197d775 100644 --- a/headers/private/kernel/frame_buffer_console.h +++ b/headers/private/kernel/frame_buffer_console.h @@ -34,6 +34,7 @@ bool frame_buffer_console_available(void); status_t frame_buffer_update(addr_t baseAddress, int32 width, int32 height, int32 depth, int32 bytesPerRow); status_t frame_buffer_console_init(struct kernel_args* args); +status_t frame_buffer_console_init_post_vm(struct kernel_args* args); status_t frame_buffer_console_init_post_modules(struct kernel_args* args); status_t _user_frame_buffer_update(addr_t baseAddress, int32 width, diff --git a/src/system/kernel/debug/blue_screen.cpp b/src/system/kernel/debug/blue_screen.cpp index 3cfa6f8be1..ec90b54407 100644 --- a/src/system/kernel/debug/blue_screen.cpp +++ b/src/system/kernel/debug/blue_screen.cpp @@ -10,7 +10,6 @@ #include "blue_screen.h" #include -#include #include #include #include @@ -63,7 +62,7 @@ struct screen_info { int32 args[MAX_ARGS]; } sScreen; -console_module_info *sModule; +console_module_info *sModule = NULL; static inline void @@ -594,16 +593,31 @@ set_paging(int argc, char **argv) status_t -blue_screen_init(void) +blue_screen_init_early() { - extern console_module_info gFrameBufferConsoleModule; - // we can't use get_module() here, since it's too early in the boot process - - if (!frame_buffer_console_available()) - return B_ERROR; - + extern console_module_info gFrameBufferConsoleModule; sModule = &gFrameBufferConsoleModule; + + if (sModule->info.std_ops(B_MODULE_INIT) != B_OK) { + sModule = NULL; + return B_ERROR; + } + + sScreen.paging = sScreen.paging_timeout = false; + return B_OK; +} + + +status_t +blue_screen_init() +{ + if (sModule == NULL) { + // Early initialization must have previously failed, or never run. + if (blue_screen_init_early() != B_OK) + return B_ERROR; + } + sScreen.paging = !get_safemode_boolean( "disable_onscreen_paging", false); sScreen.paging_timeout = false; diff --git a/src/system/kernel/debug/blue_screen.h b/src/system/kernel/debug/blue_screen.h index 9331c7bdf6..0388bf6b99 100644 --- a/src/system/kernel/debug/blue_screen.h +++ b/src/system/kernel/debug/blue_screen.h @@ -13,7 +13,8 @@ extern "C" { #endif -status_t blue_screen_init(void); +status_t blue_screen_init_early(); +status_t blue_screen_init(); status_t blue_screen_enter(bool debugOutput); bool blue_screen_paging_enabled(void); diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index 75e0978799..6dc9c7ade3 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -1689,6 +1689,9 @@ debug_init(kernel_args* args) debug_paranoia_init(); arch_debug_console_init(args); + + if (frame_buffer_console_init(args) == B_OK && blue_screen_init_early() == B_OK) + sBlueScreenOutput = true; } @@ -1715,7 +1718,7 @@ debug_init_post_vm(kernel_args* args) debug_heap_init(); debug_variables_init(); - frame_buffer_console_init(args); + frame_buffer_console_init_post_vm(args); tracing_init(); } @@ -1735,7 +1738,7 @@ debug_init_post_settings(struct kernel_args* args) sDebugScreenEnabled = get_safemode_boolean("debug_screen", false); if ((sBlueScreenOutput || sDebugScreenEnabled) - && blue_screen_init() != B_OK) + && blue_screen_init() != B_OK) sBlueScreenOutput = sDebugScreenEnabled = false; if (sDebugScreenEnabled) diff --git a/src/system/kernel/debug/frame_buffer_console.cpp b/src/system/kernel/debug/frame_buffer_console.cpp index c7b324bdcd..015d8c6c91 100644 --- a/src/system/kernel/debug/frame_buffer_console.cpp +++ b/src/system/kernel/debug/frame_buffer_console.cpp @@ -455,8 +455,27 @@ frame_buffer_console_init(kernel_args* args) if (!args->frame_buffer.enabled) return B_OK; +#if KERNEL_PMAP_BASE + const addr_t frameBuffer = (KERNEL_PMAP_BASE + + args->frame_buffer.physical_buffer.start); + frame_buffer_update((addr_t)frameBuffer, args->frame_buffer.width, + args->frame_buffer.height, args->frame_buffer.depth, + args->frame_buffer.bytes_per_row); + return B_OK; +#else + return B_NO_INIT; +#endif +} + + +status_t +frame_buffer_console_init_post_vm(kernel_args* args) +{ + if (!args->frame_buffer.enabled) + return B_OK; + void* frameBuffer; - sConsole.area = map_physical_memory("vesa frame buffer", + sConsole.area = map_physical_memory("frame buffer", args->frame_buffer.physical_buffer.start, args->frame_buffer.physical_buffer.size, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA,