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.
This commit is contained in:
Augustin Cavalier 2024-11-19 21:35:31 -05:00
parent 4550b3c025
commit f72d1684e5
5 changed files with 51 additions and 13 deletions

View File

@ -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,

View File

@ -10,7 +10,6 @@
#include "blue_screen.h"
#include <KernelExport.h>
#include <frame_buffer_console.h>
#include <console.h>
#include <debug.h>
#include <arch/debug_console.h>
@ -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;

View File

@ -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);

View File

@ -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();
}

View File

@ -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,