diff --git a/AK/Format.cpp b/AK/Format.cpp index 36b2809e821..8e691a5e36f 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -817,6 +817,14 @@ void vdbgln(StringView fmtstr, TypeErasedFormatParams& params) const auto string = builder.string_view(); +#ifdef __serenity__ +# ifdef KERNEL + if (!Kernel::Processor::is_initialized()) { + kernelearlyputstr(string.characters_without_null_termination(), string.length()); + return; + } +# endif +#endif dbgputstr(string.characters_without_null_termination(), string.length()); } diff --git a/Kernel/kprintf.cpp b/Kernel/kprintf.cpp index 9a85feeab96..a4107e557f1 100644 --- a/Kernel/kprintf.cpp +++ b/Kernel/kprintf.cpp @@ -188,3 +188,14 @@ extern "C" void kernelcriticalputstr(const char* characters, size_t length) for (size_t i = 0; i < length; ++i) critical_console_out(characters[i]); } + +extern "C" void kernelearlyputstr(const char* characters, size_t length) +{ + if (!characters) + return; + // NOTE: We do not lock the log lock here, as this function is called before this or any other processor was initialized, meaning: + // A) The $gs base was not setup yet, so we cannot enter into critical sections, and as a result we cannot use SpinLocks + // B) No other processors may try to print at the same time anyway + for (size_t i = 0; i < length; ++i) + internal_dbgputch(characters[i]); +} diff --git a/Kernel/kstdio.h b/Kernel/kstdio.h index eb882fb8f4c..33890e89b77 100644 --- a/Kernel/kstdio.h +++ b/Kernel/kstdio.h @@ -14,6 +14,7 @@ void dbgputch(char); void dbgputstr(const char*, size_t); void kernelputstr(const char*, size_t); void kernelcriticalputstr(const char*, size_t); +void kernelearlyputstr(const char*, size_t); int snprintf(char* buf, size_t, const char* fmt, ...) __attribute__((format(printf, 3, 4))); void set_serial_debug(bool on_or_off); int get_serial_debug();