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/blocklist.c
|
||||||
lib/cache/cache.c
|
lib/cache/cache.c
|
||||||
lib/comm/rs232.c
|
lib/comm/rs232.c
|
||||||
## add KD support
|
../../../drivers/base/kdnet/kdnet.c
|
||||||
|
lib/kdstub.c
|
||||||
lib/fs/btrfs.c
|
lib/fs/btrfs.c
|
||||||
lib/fs/ext2.c
|
lib/fs/ext2.c
|
||||||
lib/fs/fat.c
|
lib/fs/fat.c
|
||||||
|
|
|
@ -23,6 +23,6 @@
|
||||||
|
|
||||||
BOOLEAN Rs232PortInitialize(ULONG ComPort, ULONG BaudRate);
|
BOOLEAN Rs232PortInitialize(ULONG ComPort, ULONG BaudRate);
|
||||||
BOOLEAN Rs232PortGetByte(PUCHAR ByteReceived);
|
BOOLEAN Rs232PortGetByte(PUCHAR ByteReceived);
|
||||||
// BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived);
|
BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived);
|
||||||
VOID Rs232PortPutByte(UCHAR ByteToSend);
|
VOID Rs232PortPutByte(UCHAR ByteToSend);
|
||||||
BOOLEAN Rs232PortInUse(PUCHAR Base);
|
BOOLEAN Rs232PortInUse(PUCHAR Base);
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include <disk.h>
|
#include <disk.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <inifile.h>
|
#include <inifile.h>
|
||||||
|
#include <kd.h>
|
||||||
#include <keycodes.h>
|
#include <keycodes.h>
|
||||||
#include <linux.h>
|
#include <linux.h>
|
||||||
#include <custom.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);
|
return (CpGetByte(&Rs232ComPortInfo, ByteReceived, TRUE, FALSE) == CP_GET_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived)
|
BOOLEAN Rs232PortPollByte(PUCHAR ByteReceived)
|
||||||
{
|
{
|
||||||
if (Rs232ComPort == 0) return FALSE;
|
if (Rs232ComPort == 0) return FALSE;
|
||||||
return (CpGetByte(&Rs232ComPortInfo, ByteReceived, FALSE, FALSE) == CP_GET_SUCCESS);
|
return (CpGetByte(&Rs232ComPortInfo, ByteReceived, FALSE, FALSE) == CP_GET_SUCCESS);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
VOID Rs232PortPutByte(UCHAR ByteToSend)
|
VOID Rs232PortPutByte(UCHAR ByteToSend)
|
||||||
{
|
{
|
||||||
|
|
|
@ -194,6 +194,13 @@ Done:
|
||||||
if (!Rs232PortInitialize(ComPort, BaudRate))
|
if (!Rs232PortInitialize(ComPort, BaudRate))
|
||||||
DebugPort &= ~RS232;
|
DebugPort &= ~RS232;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
LOADER_PARAMETER_BLOCK LoaderBlock = {0};
|
||||||
|
LoaderBlock.LoadOptions = (PCHAR)CmdLineGetDebugString();
|
||||||
|
KdDebuggerInitialize0(&LoaderBlock);
|
||||||
|
KdDebuggerInitialize1(&LoaderBlock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID DebugPrintChar(UCHAR Character)
|
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
|
ULONG
|
||||||
DbgPrint(const char *Format, ...)
|
DbgPrint(const char *Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int Length;
|
int Length;
|
||||||
char* ptr;
|
|
||||||
CHAR Buffer[512];
|
CHAR Buffer[512];
|
||||||
|
|
||||||
va_start(ap, Format);
|
va_start(ap, Format);
|
||||||
|
@ -240,9 +267,7 @@ DbgPrint(const char *Format, ...)
|
||||||
Length = sizeof(Buffer);
|
Length = sizeof(Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = Buffer;
|
DbgPrintString(Buffer, Length);
|
||||||
while (Length--)
|
|
||||||
DebugPrintChar(*ptr++);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +277,7 @@ DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, .
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char Buffer[2096];
|
char Buffer[2096];
|
||||||
char *ptr = Buffer;
|
int Length;
|
||||||
|
|
||||||
/* Mask out unwanted debug messages */
|
/* Mask out unwanted debug messages */
|
||||||
if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS))
|
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);
|
va_start(ap, Format);
|
||||||
vsprintf(Buffer, Format, ap);
|
Length = vsprintf(Buffer, Format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
while (*ptr)
|
DbgPrintString(Buffer, Length);
|
||||||
{
|
|
||||||
DebugPrintChar(*ptr++);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
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