mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[FREELDR] Add KD support
Some limitations: - only debug output is supported - NOT tested with WinDBG
This commit is contained in:
parent
db271c2228
commit
5fee9d2e41
7 changed files with 248 additions and 14 deletions
|
@ -33,7 +33,8 @@ list(APPEND FREELDR_BOOTLIB_SOURCE
|
|||
lib/cache/blocklist.c
|
||||
lib/cache/cache.c
|
||||
lib/comm/rs232.c
|
||||
## add KD support
|
||||
../../../drivers/base/kdnet/kdnet.c
|
||||
lib/kdstub.c
|
||||
lib/fs/btrfs.c
|
||||
lib/fs/ext2.c
|
||||
lib/fs/fat.c
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
|
||||
BOOLEAN Rs232PortInitialize(ULONG ComPort, ULONG BaudRate);
|
||||
BOOLEAN Rs232PortGetByte(PUCHAR ByteReceived);
|
||||
// BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived);
|
||||
BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived);
|
||||
VOID Rs232PortPutByte(UCHAR ByteToSend);
|
||||
BOOLEAN Rs232PortInUse(PUCHAR Base);
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include <disk.h>
|
||||
#include <fs.h>
|
||||
#include <inifile.h>
|
||||
#include <kd.h>
|
||||
#include <keycodes.h>
|
||||
#include <linux.h>
|
||||
#include <custom.h>
|
||||
|
|
15
boot/freeldr/freeldr/include/kd.h
Normal file
15
boot/freeldr/freeldr/include/kd.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* PROJECT: FreeLoader
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Kernel debugger header file for the FreeLoader
|
||||
* COPYRIGHT: Copyright 2001-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Copyright 2022 Hervé Poussineau <hpoussin@reactos.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windbgkd.h>
|
||||
#include <kddll.h>
|
||||
#include <kdnetextensibility.h>
|
||||
|
||||
VOID DebugPrintChar(UCHAR Character);
|
|
@ -121,13 +121,11 @@ BOOLEAN Rs232PortGetByte(PUCHAR ByteReceived)
|
|||
return (CpGetByte(&Rs232ComPortInfo, ByteReceived, TRUE, FALSE) == CP_GET_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived)
|
||||
{
|
||||
if (Rs232ComPort == 0) return FALSE;
|
||||
return (CpGetByte(&Rs232ComPortInfo, ByteReceived, FALSE, FALSE) == CP_GET_SUCCESS);
|
||||
}
|
||||
*/
|
||||
|
||||
VOID Rs232PortPutByte(UCHAR ByteToSend)
|
||||
{
|
||||
|
|
|
@ -194,6 +194,13 @@ Done:
|
|||
if (!Rs232PortInitialize(ComPort, BaudRate))
|
||||
DebugPort &= ~RS232;
|
||||
}
|
||||
|
||||
{
|
||||
LOADER_PARAMETER_BLOCK LoaderBlock = {0};
|
||||
LoaderBlock.LoadOptions = (PCHAR)CmdLineGetDebugString();
|
||||
KdDebuggerInitialize0(&LoaderBlock);
|
||||
KdDebuggerInitialize1(&LoaderBlock);
|
||||
}
|
||||
}
|
||||
|
||||
VOID DebugPrintChar(UCHAR Character)
|
||||
|
@ -218,12 +225,32 @@ VOID DebugPrintChar(UCHAR Character)
|
|||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
DbgPrintString(
|
||||
_In_ PCHAR Buffer,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
DBGKD_DEBUG_IO DebugIo = {0};
|
||||
STRING MessageHeader;
|
||||
STRING MessageData;
|
||||
|
||||
/* Prepare packet to send to debugger */
|
||||
DebugIo.ApiNumber = DbgKdPrintStringApi;
|
||||
DebugIo.u.PrintString.LengthOfString = Length;
|
||||
MessageHeader.Buffer = (PCHAR)&DebugIo;
|
||||
MessageHeader.Length = sizeof(DebugIo);
|
||||
MessageData.Buffer = Buffer;
|
||||
MessageData.Length = Length;
|
||||
|
||||
/* Send packet to debugger */
|
||||
KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &MessageHeader, &MessageData, NULL);
|
||||
}
|
||||
|
||||
ULONG
|
||||
DbgPrint(const char *Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int Length;
|
||||
char* ptr;
|
||||
CHAR Buffer[512];
|
||||
|
||||
va_start(ap, Format);
|
||||
|
@ -240,9 +267,7 @@ DbgPrint(const char *Format, ...)
|
|||
Length = sizeof(Buffer);
|
||||
}
|
||||
|
||||
ptr = Buffer;
|
||||
while (Length--)
|
||||
DebugPrintChar(*ptr++);
|
||||
DbgPrintString(Buffer, Length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -252,7 +277,7 @@ DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, .
|
|||
{
|
||||
va_list ap;
|
||||
char Buffer[2096];
|
||||
char *ptr = Buffer;
|
||||
int Length;
|
||||
|
||||
/* Mask out unwanted debug messages */
|
||||
if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS))
|
||||
|
@ -285,13 +310,10 @@ DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, .
|
|||
}
|
||||
|
||||
va_start(ap, Format);
|
||||
vsprintf(Buffer, Format, ap);
|
||||
Length = vsprintf(Buffer, Format, ap);
|
||||
va_end(ap);
|
||||
|
||||
while (*ptr)
|
||||
{
|
||||
DebugPrintChar(*ptr++);
|
||||
}
|
||||
DbgPrintString(Buffer, Length);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
197
boot/freeldr/freeldr/lib/kdstub.c
Normal file
197
boot/freeldr/freeldr/lib/kdstub.c
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* PROJECT: FreeLoader
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: I/O functions for the freeldr debugger
|
||||
* COPYRIGHT: Copyright 2022 Hervé Poussineau <hpoussin@reactos.org>
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
static UCHAR KdTxMessageBuffer[4096];
|
||||
static UCHAR KdRxMessageBuffer[4096];
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
KdpGetRxPacketWinKD(
|
||||
_In_ PVOID Adapter,
|
||||
_Out_ PULONG Handle,
|
||||
_Out_ PVOID *Packet,
|
||||
_Out_ PULONG Length)
|
||||
{
|
||||
ULONG DataLength = 0;
|
||||
ULONG Retries;
|
||||
|
||||
do
|
||||
{
|
||||
for (Retries = 100; Retries > 0; Retries--)
|
||||
{
|
||||
if (Rs232PortPollByte(&KdRxMessageBuffer[DataLength]))
|
||||
{
|
||||
DataLength++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (Retries > 0);
|
||||
|
||||
if (DataLength == 0)
|
||||
return STATUS_IO_TIMEOUT;
|
||||
|
||||
*Handle = 1;
|
||||
*Packet = KdRxMessageBuffer;
|
||||
*Length = DataLength;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
KdpGetRxPacketDirectOutput(
|
||||
_In_ PVOID Adapter,
|
||||
_Out_ PULONG Handle,
|
||||
_Out_ PVOID *Packet,
|
||||
_Out_ PULONG Length)
|
||||
{
|
||||
*(PULONG)(KdRxMessageBuffer + 0) = PACKET_LEADER;
|
||||
*(PUSHORT)(KdRxMessageBuffer + 4) = PACKET_TYPE_KD_ACKNOWLEDGE;
|
||||
*(PUSHORT)(KdRxMessageBuffer + 6) = 0; // ByteCount
|
||||
*(PULONG)(KdRxMessageBuffer + 8) = INITIAL_PACKET_ID; // PacketId
|
||||
*(PULONG)(KdRxMessageBuffer + 12) = 0; // CheckSum
|
||||
*(KdRxMessageBuffer + 16) = PACKET_TRAILING_BYTE;
|
||||
|
||||
*Handle = 1;
|
||||
*Packet = KdRxMessageBuffer;
|
||||
*Length = 17;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
KdpReleaseRxPacket(
|
||||
_In_ PVOID Adapter,
|
||||
_In_ ULONG Handle)
|
||||
{
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
KdpGetTxPacket(
|
||||
_In_ PVOID Adapter,
|
||||
_Out_ PULONG Handle)
|
||||
{
|
||||
*Handle = 0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
KdpSendTxPacketWinKD(
|
||||
_In_ PVOID Adapter,
|
||||
_In_ ULONG Handle,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
PUCHAR ByteBuffer = KdTxMessageBuffer;
|
||||
|
||||
while (Length-- > 0)
|
||||
{
|
||||
Rs232PortPutByte(*ByteBuffer++);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
NTAPI
|
||||
KdpSendTxPacketDirectOutput(
|
||||
_In_ PVOID Adapter,
|
||||
_In_ ULONG Handle,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
PKD_PACKET Packet = (PKD_PACKET)KdTxMessageBuffer;
|
||||
PDBGKD_DEBUG_IO DebugIo;
|
||||
PCHAR Buffer;
|
||||
ULONG BufferLength, i;
|
||||
|
||||
if (Packet->PacketType != PACKET_TYPE_KD_DEBUG_IO)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
DebugIo = (PDBGKD_DEBUG_IO)(Packet + 1);
|
||||
if (DebugIo->ApiNumber != DbgKdPrintStringApi)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
BufferLength = Packet->ByteCount - sizeof(DBGKD_DEBUG_IO);
|
||||
Buffer = (PCHAR)(DebugIo + 1);
|
||||
for (i = 0; i < BufferLength; i++)
|
||||
DebugPrintChar(Buffer[i]);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static PVOID
|
||||
NTAPI
|
||||
KdpGetPacketAddress(
|
||||
_In_ PVOID Adapter,
|
||||
_In_ ULONG Handle)
|
||||
{
|
||||
if (Handle == 0)
|
||||
return KdTxMessageBuffer;
|
||||
else if (Handle == 1)
|
||||
return KdRxMessageBuffer;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ULONG
|
||||
NTAPI
|
||||
KdpGetPacketLength(
|
||||
_In_ PVOID Adapter,
|
||||
_In_ ULONG Handle)
|
||||
{
|
||||
if (Handle == 0)
|
||||
return sizeof(KdTxMessageBuffer);
|
||||
else if (Handle == 1)
|
||||
return sizeof(KdRxMessageBuffer);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KDNET_EXTENSIBILITY_EXPORTS KdWinKDExports = {
|
||||
KDNET_EXT_EXPORTS,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
KdpGetRxPacketWinKD,
|
||||
KdpReleaseRxPacket,
|
||||
KdpGetTxPacket,
|
||||
KdpSendTxPacketWinKD,
|
||||
KdpGetPacketAddress,
|
||||
KdpGetPacketLength,
|
||||
};
|
||||
|
||||
static KDNET_EXTENSIBILITY_EXPORTS KdDirectOutputExports = {
|
||||
KDNET_EXT_EXPORTS,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
KdpGetRxPacketDirectOutput,
|
||||
KdpReleaseRxPacket,
|
||||
KdpGetTxPacket,
|
||||
KdpSendTxPacketDirectOutput,
|
||||
KdpGetPacketAddress,
|
||||
KdpGetPacketLength,
|
||||
};
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdInitializeLibrary(
|
||||
_In_ PKDNET_EXTENSIBILITY_IMPORTS ImportTable,
|
||||
_In_opt_ PCHAR LoaderOptions,
|
||||
_Inout_ PDEBUG_DEVICE_DESCRIPTOR Device)
|
||||
{
|
||||
#ifdef _WINKD_
|
||||
if (1)
|
||||
#else
|
||||
if (0)
|
||||
#endif
|
||||
ImportTable->Exports = &KdWinKDExports;
|
||||
else
|
||||
ImportTable->Exports = &KdDirectOutputExports;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
Loading…
Reference in a new issue