https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bf734e5373ef476083109…
commit bf734e5373ef4760831098b23279e568935c83e1
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sun Jul 10 15:01:01 2022 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Mar 10 23:59:08 2023 +0100
[NTOS:KD] Move handling of Dmesg buffer from screen provider to KDBG provider.
(#5143)
CORE-10749
The dmesg command is now available even if screen output is disabled.
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
---
ntoskrnl/include/internal/kd.h | 11 ++++++
ntoskrnl/kd/kdio.c | 68 ---------------------------------
ntoskrnl/kdbg/kdb_cli.c | 85 ++++++++++++++++++++++++++++++++++++------
3 files changed, 85 insertions(+), 79 deletions(-)
diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h
index 75ffd8be63f..325e0b0ea3c 100644
--- a/ntoskrnl/include/internal/kd.h
+++ b/ntoskrnl/include/internal/kd.h
@@ -53,6 +53,17 @@ VOID
/* INIT ROUTINES *************************************************************/
+KIRQL
+NTAPI
+KdbpAcquireLock(
+ _In_ PKSPIN_LOCK SpinLock);
+
+VOID
+NTAPI
+KdbpReleaseLock(
+ _In_ PKSPIN_LOCK SpinLock,
+ _In_ KIRQL OldIrql);
+
VOID
KdpScreenAcquire(VOID);
diff --git a/ntoskrnl/kd/kdio.c b/ntoskrnl/kd/kdio.c
index 9c8a486fad8..129db8b9b5e 100644
--- a/ntoskrnl/kd/kdio.c
+++ b/ntoskrnl/kd/kdio.c
@@ -37,14 +37,6 @@ CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
static CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
static ULONG KdpScreenLineBufferPos = 0, KdpScreenLineLength = 0;
-const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
-PCHAR KdpDmesgBuffer = NULL;
-volatile ULONG KdpDmesgCurrentPosition = 0;
-volatile ULONG KdpDmesgFreeBytes = 0;
-volatile ULONG KdbDmesgTotalWritten = 0;
-volatile BOOLEAN KdbpIsInDmesgMode = FALSE;
-static KSPIN_LOCK KdpDmesgLogSpinLock;
-
KDP_DEBUG_MODE KdpDebugMode;
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
KD_DISPATCH_TABLE DispatchTable[KdMax];
@@ -440,20 +432,12 @@ KdpScreenRelease(VOID)
}
}
-/*
- * Screen debug logger function KdpScreenPrint() writes text strings into
- * KdpDmesgBuffer, using it as a circular buffer. KdpDmesgBuffer contents could
- * be later (re)viewed using dmesg command of kdbg. KdpScreenPrint() protects
- * KdpDmesgBuffer from simultaneous writes by use of KdpDmesgLogSpinLock.
- */
static VOID
NTAPI
KdpScreenPrint(PCHAR String,
ULONG Length)
{
PCHAR pch = String;
- KIRQL OldIrql;
- ULONG beg, end, num;
while (pch < String + Length && *pch)
{
@@ -497,45 +481,6 @@ KdpScreenPrint(PCHAR String,
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
KdpScreenLineBufferPos = KdpScreenLineLength;
}
-
- /* Dmesg: store the string in the buffer to show it later */
- if (KdbpIsInDmesgMode)
- return;
-
- if (KdpDmesgBuffer == NULL)
- return;
-
- /* Acquire the printing spinlock without waiting at raised IRQL */
- OldIrql = KdbpAcquireLock(&KdpDmesgLogSpinLock);
-
- beg = KdpDmesgCurrentPosition;
- /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
- num = min(Length, KdpDmesgFreeBytes);
- if (num != 0)
- {
- end = (beg + num) % KdpDmesgBufferSize;
- if (end > beg)
- {
- RtlCopyMemory(KdpDmesgBuffer + beg, String, Length);
- }
- else
- {
- RtlCopyMemory(KdpDmesgBuffer + beg, String, KdpDmesgBufferSize - beg);
- RtlCopyMemory(KdpDmesgBuffer, String + (KdpDmesgBufferSize - beg), end);
- }
- KdpDmesgCurrentPosition = end;
-
- /* Counting the total bytes written */
- KdbDmesgTotalWritten += num;
- }
-
- /* Release the spinlock */
- KdbpReleaseLock(&KdpDmesgLogSpinLock, OldIrql);
-
- /* Optional step(?): find out a way to notify about buffer exhaustion,
- * and possibly fall into kbd to use dmesg command: user will read
- * debug strings before they will be wiped over by next writes.
- */
}
VOID
@@ -557,22 +502,9 @@ KdpScreenInit(
}
else if (BootPhase == 1)
{
- /* Allocate a buffer for dmesg log buffer. +1 for terminating null,
- * see kdbp_cli.c:KdbpCmdDmesg()/2
- */
- KdpDmesgBuffer = ExAllocatePoolZero(NonPagedPool,
- KdpDmesgBufferSize + 1,
- TAG_KDBG);
- /* Ignore failure if KdpDmesgBuffer is NULL */
- KdpDmesgFreeBytes = KdpDmesgBufferSize;
- KdbDmesgTotalWritten = 0;
-
/* Take control of the display */
KdpScreenAcquire();
- /* Initialize spinlock */
- KeInitializeSpinLock(&KdpDmesgLogSpinLock);
-
HalDisplayString("\r\n Screen debugging enabled\r\n\r\n");
}
}
diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c
index c12f19554ef..fdd5d694924 100644
--- a/ntoskrnl/kdbg/kdb_cli.c
+++ b/ntoskrnl/kdbg/kdb_cli.c
@@ -155,14 +155,14 @@ static LONG KdbNumberOfColsTerminal = -1;
PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during
initialization */
BOOLEAN KdbpBugCheckRequested = FALSE;
-/* Vars for dmesg */
-/* defined in ../kd/kdio.c, declare here: */
-extern volatile BOOLEAN KdbpIsInDmesgMode;
-extern const ULONG KdpDmesgBufferSize;
-extern PCHAR KdpDmesgBuffer;
-extern volatile ULONG KdpDmesgCurrentPosition;
-extern volatile ULONG KdpDmesgFreeBytes;
-extern volatile ULONG KdbDmesgTotalWritten;
+/* Variables for Dmesg */
+static const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
+static PCHAR KdpDmesgBuffer = NULL;
+static volatile ULONG KdpDmesgCurrentPosition = 0;
+static volatile ULONG KdpDmesgFreeBytes = 0;
+static volatile ULONG KdbDmesgTotalWritten = 0;
+static volatile BOOLEAN KdbpIsInDmesgMode = FALSE;
+static KSPIN_LOCK KdpDmesgLogSpinLock;
STRING KdbPromptString = RTL_CONSTANT_STRING("kdb:> ");
@@ -3882,13 +3882,60 @@ KdbpCliInit(VOID)
}
+/**
+ * @brief Debug logger function.
+ *
+ * This function writes text strings into KdpDmesgBuffer, using it as
+ * a circular buffer. KdpDmesgBuffer contents can be later (re)viewed
+ * using the dmesg command. KdbDebugPrint() protects KdpDmesgBuffer
+ * from simultaneous writes by use of KdpDmesgLogSpinLock.
+ **/
static VOID
NTAPI
KdbDebugPrint(
- PCH Message,
- ULONG Length)
+ _In_ PCHAR String,
+ _In_ ULONG Length)
{
- /* Nothing here */
+ KIRQL OldIrql;
+ ULONG beg, end, num;
+
+ /* Avoid recursive calling if we already are in Dmesg mode */
+ if (KdbpIsInDmesgMode)
+ return;
+
+ if (KdpDmesgBuffer == NULL)
+ return;
+
+ /* Acquire the printing spinlock without waiting at raised IRQL */
+ OldIrql = KdbpAcquireLock(&KdpDmesgLogSpinLock);
+
+ beg = KdpDmesgCurrentPosition;
+ /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
+ num = min(Length, KdpDmesgFreeBytes);
+ if (num != 0)
+ {
+ end = (beg + num) % KdpDmesgBufferSize;
+ if (end > beg)
+ {
+ RtlCopyMemory(KdpDmesgBuffer + beg, String, Length);
+ }
+ else
+ {
+ RtlCopyMemory(KdpDmesgBuffer + beg, String, KdpDmesgBufferSize - beg);
+ RtlCopyMemory(KdpDmesgBuffer, String + (KdpDmesgBufferSize - beg), end);
+ }
+ KdpDmesgCurrentPosition = end;
+
+ /* Counting the total bytes written */
+ KdbDmesgTotalWritten += num;
+ }
+
+ /* Release the spinlock */
+ KdbpReleaseLock(&KdpDmesgLogSpinLock, OldIrql);
+
+ /* Optional step(?): find out a way to notify about buffer exhaustion,
+ * and possibly fall into kbd to use dmesg command: user will read
+ * debug strings before they will be wiped over by next writes. */
}
/**
@@ -3918,6 +3965,22 @@ KdbInitialize(
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
+ else if (BootPhase == 1)
+ {
+ /* Initialize Dmesg support */
+
+ /* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
+ * see kdbp_cli.c:KdbpCmdDmesg()/2 */
+ KdpDmesgBuffer = ExAllocatePoolZero(NonPagedPool,
+ KdpDmesgBufferSize + 1,
+ TAG_KDBG);
+ /* Ignore failure if KdpDmesgBuffer is NULL */
+ KdpDmesgFreeBytes = KdpDmesgBufferSize;
+ KdbDmesgTotalWritten = 0;
+
+ /* Initialize spinlock */
+ KeInitializeSpinLock(&KdpDmesgLogSpinLock);
+ }
if (BootPhase <= 1)
{