[haiku-commits] r35816 - in haiku/trunk: headers/private/kernel/boot src/system/boot/loader src/system/boot/platform/bios_ia32 src/system/kernel/debug

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 11 Mar 2010 18:46:36 +0100 (CET)

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


Other related posts:

  • » [haiku-commits] r35816 - in haiku/trunk: headers/private/kernel/boot src/system/boot/loader src/system/boot/platform/bios_ia32 src/system/kernel/debug - ingo_weinhold