Author: bonefish Date: 2010-03-11 18:46:36 +0100 (Thu, 11 Mar 2010) New Revision: 35816 Changeset: http://dev.haiku-os.org/changeset/35816/haiku Added: haiku/trunk/src/system/boot/loader/vm.cpp haiku/trunk/src/system/boot/platform/bios_ia32/debug.cpp haiku/trunk/src/system/boot/platform/bios_ia32/debug.h Removed: haiku/trunk/src/system/boot/platform/bios_ia32/debug.c Modified: haiku/trunk/headers/private/kernel/boot/kernel_args.h haiku/trunk/src/system/boot/loader/Jamfile haiku/trunk/src/system/boot/loader/menu.cpp haiku/trunk/src/system/boot/platform/bios_ia32/Jamfile haiku/trunk/src/system/boot/platform/bios_ia32/serial.cpp haiku/trunk/src/system/boot/platform/bios_ia32/serial.h haiku/trunk/src/system/boot/platform/bios_ia32/start.c haiku/trunk/src/system/kernel/debug/debug.cpp Log: kernel: * The kernel syslog ring buffer is no longer emptied by the syslog sender thread. Instead we only drop the oldest data from the buffer when we're writing to it and there's not enough free space in it. Advantages: We drop old data rather than the most recent data when the buffer is full. The "syslog" KDL command has more data available now. So the odds are that kernel syslog messages not written to disk yet are at least still in the kernel buffer. * Changed dprintf_no_syslog() semantics: Now it writes to the syslog, but doesn't notify the syslog sender thread. boot loader: * Added the ring_buffer implementation and a dummy user_memcpy(). * bios_x86: Moved the syslog stuff from serial.{cpp,h} to debug.{cpp.h}. * Moved the debug options from the "Select safe mode options" menu to a new "Select debug options" menu. * Added option "Enable debug syslog" to the new menu (ATM available on x86 only). It allocates a 1 MB in-memory buffer for the syslog for this session in such a way that it can be accessed by the boot loader after a reset. * Added item "Display syslog from previous session" to the new menu, doing what its name suggests. Modified: haiku/trunk/headers/private/kernel/boot/kernel_args.h =================================================================== --- haiku/trunk/headers/private/kernel/boot/kernel_args.h 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/headers/private/kernel/boot/kernel_args.h 2010-03-11 17:46:36 UTC (rev 35816) @@ -78,6 +78,7 @@ void *debug_output; uint32 debug_size; + bool keep_debug_output_buffer; platform_kernel_args platform_args; arch_kernel_args arch_args; Modified: haiku/trunk/src/system/boot/loader/Jamfile =================================================================== --- haiku/trunk/src/system/boot/loader/Jamfile 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/boot/loader/Jamfile 2010-03-11 17:46:36 UTC (rev 35816) @@ -50,17 +50,19 @@ } KernelStaticLibrary boot_loader : + elf.cpp + heap.cpp + kernel_args.cpp + load_driver_settings.cpp + loader.cpp main.cpp - vfs.cpp + menu.cpp + pager.cpp + partitions.cpp RootFileSystem.cpp - partitions.cpp - heap.cpp stdio.cpp - elf.cpp - menu.cpp - loader.cpp - kernel_args.cpp - load_driver_settings.cpp + vfs.cpp + vm.cpp # libroot driver_settings.c @@ -69,6 +71,7 @@ kernel_cpp.cpp KMessage.cpp list.cpp + ring_buffer.cpp safemode_settings.cpp : -fno-pic @@ -89,7 +92,7 @@ ; # Tell Jam where to find the utility sources -SEARCH on [ FGristFiles kernel_cpp.cpp list.cpp ] +SEARCH on [ FGristFiles kernel_cpp.cpp list.cpp ring_buffer.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel util ] ; SEARCH on [ FGristFiles KMessage.cpp ] Modified: haiku/trunk/src/system/boot/loader/menu.cpp =================================================================== --- haiku/trunk/src/system/boot/loader/menu.cpp 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/boot/loader/menu.cpp 2010-03-11 17:46:36 UTC (rev 35816) @@ -5,23 +5,26 @@ #include "menu.h" -#include "loader.h" -#include "RootFileSystem.h" -#include "load_driver_settings.h" +#include <string.h> + #include <algorithm> #include <OS.h> -#include <util/kernel_cpp.h> #include <boot/menu.h> #include <boot/stage2.h> #include <boot/vfs.h> #include <boot/platform.h> #include <boot/stdio.h> #include <safemode.h> +#include <util/kernel_cpp.h> +#include <util/ring_buffer.h> -#include <string.h> +#include "load_driver_settings.h" +#include "loader.h" +#include "pager.h" +#include "RootFileSystem.h" #define TRACE_MENU @@ -375,6 +378,48 @@ } +static bool +debug_menu_display_syslog(Menu *menu, MenuItem *item) +{ + ring_buffer* buffer = (ring_buffer*)gKernelArgs.debug_output; + if (buffer == NULL) + return true; + + struct TextSource : PagerTextSource { + TextSource(ring_buffer* buffer) + : + fBuffer(buffer) + { + } + + virtual size_t BytesAvailable() const + { + return ring_buffer_readable(fBuffer); + } + + virtual size_t Read(size_t offset, void* buffer, size_t size) const + { + return ring_buffer_peek(fBuffer, offset, buffer, size); + } + + private: + ring_buffer* fBuffer; + }; + + pager(TextSource(buffer)); + + return true; +} + + +static bool +debug_menu_toggle_debug_syslog(Menu *menu, MenuItem *item) +{ + gKernelArgs.keep_debug_output_buffer = item->IsMarked(); + return true; +} + + static Menu * add_boot_volume_menu(Directory *bootVolume) { @@ -459,34 +504,66 @@ platform_add_menus(safeMenu); + safeMenu->AddSeparatorItem(); + safeMenu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); + + return safeMenu; +} + + +static Menu * +add_debug_menu() +{ + Menu *menu = new(nothrow) Menu(SAFE_MODE_MENU, "Debug Options"); + MenuItem *item; + #if DEBUG_SPINLOCK_LATENCIES item = new(std::nothrow) MenuItem("Disable latency checks"); if (item != NULL) { item->SetType(MENU_ITEM_MARKABLE); item->SetData(B_SAFEMODE_DISABLE_LATENCY_CHECK); item->SetHelpText("Disables latency check panics."); - safeMenu->AddItem(item); + menu->AddItem(item); } #endif - safeMenu->AddItem(item + menu->AddItem(item = new(nothrow) MenuItem("Enable serial debug output")); item->SetData("serial_debug_output"); item->SetType(MENU_ITEM_MARKABLE); item->SetHelpText("Turns on forwarding the syslog output to the serial " "interface."); - safeMenu->AddItem(item + menu->AddItem(item = new(nothrow) MenuItem("Enable on screen debug output")); item->SetData("debug_screen"); item->SetType(MENU_ITEM_MARKABLE); item->SetHelpText("Displays debug output on screen while the system " "is booting, instead of the normal boot logo."); - safeMenu->AddSeparatorItem(); - safeMenu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); + menu->AddItem(item = new(nothrow) MenuItem("Enable debug syslog")); + item->SetType(MENU_ITEM_MARKABLE); + item->SetMarked(gKernelArgs.keep_debug_output_buffer); + item->SetTarget(&debug_menu_toggle_debug_syslog); + item->SetHelpText("Enables a special in-memory syslog buffer for this " + "session that the boot loader will be able to access after rebooting."); - return safeMenu; + ring_buffer* syslogBuffer = (ring_buffer*)gKernelArgs.debug_output; + if (syslogBuffer != NULL && ring_buffer_readable(syslogBuffer) > 0) { + menu->AddSeparatorItem(); + + menu->AddItem(item + = new(nothrow) MenuItem("Display syslog from previous session")); + item->SetTarget(&debug_menu_display_syslog); + item->SetType(MENU_ITEM_NO_CHOICE); + item->SetHelpText( + "Displays the syslog from the previous Haiku session."); + } + + menu->AddSeparatorItem(); + menu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); + + return menu; } @@ -527,6 +604,7 @@ { Menu *menu = new(nothrow) Menu(MAIN_MENU); Menu *safeModeMenu = NULL; + Menu *debugMenu = NULL; MenuItem *item; TRACE(("user_menu: enter\n")); @@ -539,6 +617,10 @@ menu->AddItem(item = new(nothrow) MenuItem("Select safe mode options", safeModeMenu = add_safe_mode_menu())); + // add debug menu + menu->AddItem(item = new(nothrow) MenuItem("Select debug options", + debugMenu = add_debug_menu())); + // Add platform dependent menus platform_add_menus(menu); @@ -561,6 +643,7 @@ *_bootVolume = (Directory *)item->Data(); apply_safe_mode_options(safeModeMenu); + apply_safe_mode_options(debugMenu); delete menu; TRACE(("user_menu: leave\n")); Added: haiku/trunk/src/system/boot/loader/vm.cpp =================================================================== --- haiku/trunk/src/system/boot/loader/vm.cpp (rev 0) +++ haiku/trunk/src/system/boot/loader/vm.cpp 2010-03-11 17:46:36 UTC (rev 35816) @@ -0,0 +1,17 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include <KernelExport.h> + +#include <string.h> + + +status_t +user_memcpy(void* to, const void* from, size_t size) +{ + memcpy(to, from, size); + return B_OK; +} Modified: haiku/trunk/src/system/boot/platform/bios_ia32/Jamfile =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/Jamfile 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/boot/platform/bios_ia32/Jamfile 2010-03-11 17:46:36 UTC (rev 35816) @@ -17,7 +17,7 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; -local genericPlatformSources = +local genericPlatformSources = text_menu.cpp video_blit.cpp video_splash.cpp @@ -27,7 +27,7 @@ KernelMergeObject boot_platform_bios_ia32.o : shell.S start.c - debug.c + debug.cpp bios.S console.cpp serial.cpp @@ -44,7 +44,7 @@ video.cpp apm.cpp hpet.cpp - + $(genericPlatformSources) # VESA/DDC EDID Copied: haiku/trunk/src/system/boot/platform/bios_ia32/debug.cpp (from rev 35799, haiku/trunk/src/system/boot/platform/bios_ia32/debug.c) =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/debug.cpp (rev 0) +++ haiku/trunk/src/system/boot/platform/bios_ia32/debug.cpp 2010-03-11 17:46:36 UTC (rev 35816) @@ -0,0 +1,134 @@ +/* + * Copyright 2004-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "debug.h" + +#include <stdarg.h> +#include <string.h> + +#include <boot/platform.h> +#include <boot/stage2.h> +#include <boot/stdio.h> +#include <kernel.h> +#include <util/ring_buffer.h> + +#include "keyboard.h" +#include "mmu.h" +#include "serial.h" + + +static const char* const kDebugSyslogSignature = "Haiku syslog"; + +static char sBuffer[16384]; +static uint32 sBufferPosition; + +static ring_buffer* sDebugSyslogBuffer = NULL; + + +/*! This works only after console_init() was called. +*/ +void +panic(const char *format, ...) +{ + va_list list; + + platform_switch_to_text_mode(); + + puts("*** PANIC ***"); + + va_start(list, format); + vprintf(format, list); + va_end(list); + + puts("\nPress key to reboot."); + + clear_key_buffer(); + wait_for_key(); + platform_exit(); +} + + +void +dprintf(const char *format, ...) +{ + char buffer[512]; + va_list list; + int length; + + va_start(list, format); + length = vsnprintf(buffer, sizeof(buffer), format, list); + va_end(list); + + if (length >= (int)sizeof(buffer)) + length = sizeof(buffer) - 1; + + if (sBufferPosition + length < sizeof(sBuffer)) { + memcpy(sBuffer + sBufferPosition, buffer, length); + sBufferPosition += length; + } + + serial_puts(buffer, length); + + if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) + fprintf(stderr, "%s", buffer); +} + + +// #pragma mark - + + +void +debug_init_post_mmu(void) +{ + // allocate 1 MB memory at 16 MB + addr_t base = 16 * 1024 * 1024; + size_t size = 1024 * 1024; + if (!mmu_allocate_physical(base, size)) + return; + + void* buffer = (void*)mmu_map_physical_memory(base, size, + kDefaultPageFlags); + if (buffer == NULL) + return; + + // check whether there's a previous syslog we can recover + size_t signatureLength = strlen(kDebugSyslogSignature); + bool recover = memcmp(buffer, kDebugSyslogSignature, signatureLength) == 0; + + // clear the signature + memset(buffer, 0, signatureLength); + + size -= signatureLength; + buffer = (uint8*)buffer + ROUNDUP(signatureLength, sizeof(void*)); + + sDebugSyslogBuffer = create_ring_buffer_etc(buffer, size, + recover ? RING_BUFFER_INIT_FROM_BUFFER : 0); + + gKernelArgs.debug_output = sDebugSyslogBuffer; + gKernelArgs.debug_size = sDebugSyslogBuffer->size; +} + + +void +debug_cleanup(void) +{ + if (gKernelArgs.keep_debug_output_buffer && sDebugSyslogBuffer != NULL) { + // copy the output gathered so far into the ring buffer + ring_buffer_clear(sDebugSyslogBuffer); + ring_buffer_write(sDebugSyslogBuffer, (uint8*)sBuffer, sBufferPosition); + + // set the buffer signature, so we'll accept it as valid after reboot + size_t signatureLength = strlen(kDebugSyslogSignature); + memcpy((void*)ROUNDDOWN((addr_t)sDebugSyslogBuffer, B_PAGE_SIZE), + kDebugSyslogSignature, signatureLength); + } else { + gKernelArgs.debug_output = kernel_args_malloc(sBufferPosition); + if (gKernelArgs.debug_output != NULL) { + memcpy(gKernelArgs.debug_output, sBuffer, sBufferPosition); + gKernelArgs.debug_size = sBufferPosition; + } + } +} Added: haiku/trunk/src/system/boot/platform/bios_ia32/debug.h =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/debug.h (rev 0) +++ haiku/trunk/src/system/boot/platform/bios_ia32/debug.h 2010-03-11 17:46:36 UTC (rev 35816) @@ -0,0 +1,24 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ +#ifndef DEBUG_H +#define DEBUG_H + + +#include <SupportDefs.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +void debug_init_post_mmu(void); +void debug_cleanup(void); + +#ifdef __cplusplus +} +#endif + + +#endif // DEBUG_H Modified: haiku/trunk/src/system/boot/platform/bios_ia32/serial.cpp =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/serial.cpp 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/boot/platform/bios_ia32/serial.cpp 2010-03-11 17:46:36 UTC (rev 35816) @@ -34,10 +34,6 @@ static int32 sSerialEnabled = 0; static uint16 sSerialBasePort = 0x3f8; -static char sBuffer[16384]; -static uint32 sBufferPosition; - - static void serial_putc(char c) { @@ -55,11 +51,6 @@ if (sSerialEnabled <= 0) return; - if (sBufferPosition + size < sizeof(sBuffer)) { - memcpy(sBuffer + sBufferPosition, string, size); - sBufferPosition += size; - } - while (size-- != 0) { char c = string[0]; @@ -93,20 +84,6 @@ extern "C" void -serial_cleanup(void) -{ - if (sSerialEnabled <= 0) - return; - - gKernelArgs.debug_output = kernel_args_malloc(sBufferPosition); - if (gKernelArgs.debug_output != NULL) { - memcpy(gKernelArgs.debug_output, sBuffer, sBufferPosition); - gKernelArgs.debug_size = sBufferPosition; - } -} - - -extern "C" void serial_init(void) { // copy the base ports of the optional 4 serial ports to the kernel args @@ -133,4 +110,3 @@ serial_enable(); #endif } - Modified: haiku/trunk/src/system/boot/platform/bios_ia32/serial.h =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/serial.h 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/boot/platform/bios_ia32/serial.h 2010-03-11 17:46:36 UTC (rev 35816) @@ -14,6 +14,7 @@ #endif extern void serial_init(void); +extern void serial_init_post_mmu(void); extern void serial_cleanup(void); extern void serial_puts(const char *string, size_t size); Modified: haiku/trunk/src/system/boot/platform/bios_ia32/start.c =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/start.c 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/boot/platform/bios_ia32/start.c 2010-03-11 17:46:36 UTC (rev 35816) @@ -4,24 +4,26 @@ */ -#include "serial.h" -#include "console.h" -#include "apm.h" -#include "cpu.h" -#include "mmu.h" -#include "smp.h" -#include "acpi.h" -#include "keyboard.h" -#include "bios.h" -#include "multiboot.h" +#include <string.h> #include <KernelExport.h> + +#include <arch/cpu.h> #include <boot/platform.h> #include <boot/heap.h> #include <boot/stage2.h> -#include <arch/cpu.h> -#include <string.h> +#include "acpi.h" +#include "apm.h" +#include "bios.h" +#include "console.h" +#include "cpu.h" +#include "debug.h" +#include "keyboard.h" +#include "mmu.h" +#include "multiboot.h" +#include "serial.h" +#include "smp.h" #define HEAP_SIZE (128 * 1024) @@ -79,7 +81,7 @@ = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; smp_init_other_cpus(); - serial_cleanup(); + debug_cleanup(); mmu_init_for_kernel(); smp_boot_other_cpus(); @@ -128,6 +130,7 @@ console_init(); cpu_init(); mmu_init(); + debug_init_post_mmu(); parse_multiboot_commandline(&args); // reading the keyboard doesn't seem to work in graphics mode Modified: haiku/trunk/src/system/kernel/debug/debug.cpp =================================================================== --- haiku/trunk/src/system/kernel/debug/debug.cpp 2010-03-11 17:42:00 UTC (rev 35815) +++ haiku/trunk/src/system/kernel/debug/debug.cpp 2010-03-11 17:46:36 UTC (rev 35816) @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx * Copyright 2002-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. * @@ -91,6 +91,7 @@ static sem_id sSyslogNotify = -1; static struct syslog_message* sSyslogMessage; static struct ring_buffer* sSyslogBuffer; +static size_t sSyslogBufferOffset = 0; static bool sSyslogDropped = false; static const char* sCurrentKernelDebuggerMessagePrefix; @@ -106,7 +107,7 @@ DefaultDebugOutputFilter gDefaultDebugOutputFilter; static mutex sOutputLock = MUTEX_INITIALIZER("debug output"); -static void flush_pending_repeats(bool syslogOutput); +static void flush_pending_repeats(bool notifySyslog); static void check_pending_repeats(void* data, int iter); static int64 sMessageRepeatFirstTime = 0; @@ -180,7 +181,7 @@ DefaultDebugOutputFilter::Print(const char* format, va_list args) { vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, format, args); - flush_pending_repeats(sInDebugger == 0); + flush_pending_repeats(false); PrintString(sInterruptOutputBuffer); } @@ -1065,12 +1066,14 @@ cpu_status state = disable_interrupts(); acquire_spinlock(&sSpinlock); - length = ring_buffer_readable(sSyslogBuffer); + length = ring_buffer_readable(sSyslogBuffer) + - sSyslogBufferOffset; if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH) length = SYSLOG_MAX_MESSAGE_LENGTH; - length = ring_buffer_read(sSyslogBuffer, + length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset, (uint8*)sSyslogMessage->message, length); + sSyslogBufferOffset += length; if (sSyslogDropped) { // Add drop marker - since parts had to be dropped, it's // guaranteed that we have enough space in the buffer now. @@ -1111,29 +1114,33 @@ static void -syslog_write(const char* text, int32 length) +syslog_write(const char* text, int32 length, bool notify) { - bool trunc = false; - if (sSyslogBuffer == NULL) return; - if ((int32)ring_buffer_writable(sSyslogBuffer) < length) { - // truncate data - length = ring_buffer_writable(sSyslogBuffer); + if (length > sSyslogBuffer->size) { + text = "<DROP>"; + length = 6; + } - if (length > 8) { - trunc = true; - length -= 8; + int32 writable = ring_buffer_writable(sSyslogBuffer); + if (writable < length) { + // drop old data + size_t toDrop = length - writable; + ring_buffer_flush(sSyslogBuffer, toDrop); + + if (toDrop > sSyslogBufferOffset) { + sSyslogBufferOffset = 0; + sSyslogDropped = true; } else - sSyslogDropped = true; + sSyslogBufferOffset -= toDrop; } ring_buffer_write(sSyslogBuffer, (uint8*)text, length); - if (trunc) - ring_buffer_write(sSyslogBuffer, (uint8*)"<TRUNC>", 7); - release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); + if (notify) + release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); } @@ -1163,7 +1170,7 @@ static status_t -syslog_init(struct kernel_args* args) +syslog_init_post_vm(struct kernel_args* args) { status_t status; int32 length = 0; @@ -1177,7 +1184,7 @@ goto err1; } - { + if (sSyslogBuffer == NULL) { size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE; void* handle = load_driver_settings("kernel"); if (handle != NULL) { @@ -1195,11 +1202,18 @@ } sSyslogBuffer = create_ring_buffer(bufferSize); + + if (sSyslogBuffer == NULL) { + status = B_NO_MEMORY; + goto err2; + } + } else { + // create an area for the debug syslog buffer + void* base = (void*)ROUNDDOWN((addr_t)args->debug_output, B_PAGE_SIZE); + size_t size = ROUNDUP(args->debug_size, B_PAGE_SIZE); + create_area("syslog debug", &base, B_EXACT_ADDRESS, size, + B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); } - if (sSyslogBuffer == NULL) { - status = B_NO_MEMORY; - goto err2; - } // initialize syslog message sSyslogMessage->from = 0; @@ -1209,14 +1223,14 @@ //strcpy(sSyslogMessage->ident, "KERNEL"); if (args->debug_output != NULL) - syslog_write((const char*)args->debug_output, args->debug_size); + syslog_write((const char*)args->debug_output, args->debug_size, false); char revisionBuffer[64]; length = snprintf(revisionBuffer, sizeof(revisionBuffer), "Welcome to syslog debug output!\nHaiku revision: %lu\n", get_haiku_revision()); syslog_write(revisionBuffer, - std::min(length, (ssize_t)sizeof(revisionBuffer) - 1)); + std::min(length, (ssize_t)sizeof(revisionBuffer) - 1), false); add_debugger_command_etc("syslog", &cmd_dump_syslog, "Dumps the syslog buffer.", @@ -1236,6 +1250,19 @@ } +static status_t +syslog_init(struct kernel_args* args) +{ + if (!args->keep_debug_output_buffer) + return B_OK; + + sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size, + RING_BUFFER_INIT_FROM_BUFFER); + + return B_OK; +} + + static void debug_memcpy_trampoline(void* _parameters) { @@ -1273,7 +1300,7 @@ //! Must be called with the sSpinlock held. static void -debug_output(const char* string, int32 length, bool syslogOutput) +debug_output(const char* string, int32 length, bool notifySyslog) { if (length >= OUTPUT_BUFFER_SIZE) length = OUTPUT_BUFFER_SIZE - 1; @@ -1285,12 +1312,12 @@ if (sMessageRepeatFirstTime == 0) sMessageRepeatFirstTime = sMessageRepeatLastTime; } else { - flush_pending_repeats(syslogOutput); + flush_pending_repeats(notifySyslog); if (sSerialDebugEnabled) arch_debug_serial_puts(string); - if (sSyslogOutputEnabled && syslogOutput) - syslog_write(string, length); + if (sSyslogOutputEnabled) + syslog_write(string, length, notifySyslog); if (sBlueScreenEnabled || sDebugScreenEnabled) blue_screen_puts(string); if (sSerialDebugEnabled) { @@ -1308,7 +1335,7 @@ //! Must be called with the sSpinlock held. static void -flush_pending_repeats(bool syslogOutput) +flush_pending_repeats(bool notifySyslog) { if (sMessageRepeatCount <= 0) return; @@ -1321,8 +1348,8 @@ if (sSerialDebugEnabled) arch_debug_serial_puts(temp); - if (sSyslogOutputEnabled && syslogOutput) - syslog_write(temp, length); + if (sSyslogOutputEnabled) + syslog_write(temp, length, notifySyslog); if (sBlueScreenEnabled || sDebugScreenEnabled) blue_screen_puts(temp); if (sSerialDebugEnabled) { @@ -1337,8 +1364,8 @@ if (sSerialDebugEnabled) arch_debug_serial_puts(sLastOutputBuffer); - if (sSyslogOutputEnabled && syslogOutput) - syslog_write(sLastOutputBuffer, length); + if (sSyslogOutputEnabled) + syslog_write(sLastOutputBuffer, length, notifySyslog); if (sBlueScreenEnabled || sDebugScreenEnabled) blue_screen_puts(sLastOutputBuffer); if (sSerialDebugEnabled) { @@ -1374,7 +1401,7 @@ static void -dprintf_args(const char* format, va_list args, bool syslogOutput) +dprintf_args(const char* format, va_list args, bool notifySyslog) { if (are_interrupts_enabled()) { MutexLocker locker(sOutputLock); @@ -1384,7 +1411,7 @@ length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); InterruptsSpinLocker _(sSpinlock); - debug_output(sOutputBuffer, length, syslogOutput); + debug_output(sOutputBuffer, length, notifySyslog); } else { InterruptsSpinLocker _(sSpinlock); @@ -1392,7 +1419,7 @@ format, args); length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); - debug_output(sInterruptOutputBuffer, length, syslogOutput); + debug_output(sInterruptOutputBuffer, length, notifySyslog); } } @@ -1425,7 +1452,7 @@ debug_puts(const char* string, int32 length) { InterruptsSpinLocker _(sSpinlock); - debug_output(string, length, sSyslogOutputEnabled); + debug_output(string, length, true); } @@ -1441,6 +1468,8 @@ { new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter; + syslog_init(args); + debug_paranoia_init(); return arch_debug_console_init(args); } @@ -1484,7 +1513,7 @@ if (sDebugScreenEnabled) blue_screen_enter(true); - syslog_init(args); + syslog_init_post_vm(args); return arch_debug_init(args); } @@ -1785,7 +1814,7 @@ return; va_start(args, format); - dprintf_args(format, args, sSyslogOutputEnabled); + dprintf_args(format, args, true); va_end(args); }