Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här avsnittet beskriver hur KDNET-transporten kan utökas till att köras på valfri maskinvara med hjälp av en separat utökningsmodul för maskinvarudrivrutiner. Utökningsmoduler för KDNET-transport utvecklas av nätverkskortleverantörer för att lägga till stöd för kernelfelsökning till specifika nätverkskort.
Översikt över KDNET
KDNET är en kernel-felsökningstransport som möjliggör kernelfelsökning av fönster över ett nätverk. Ursprungligen användes den för att stödja kernel-felsökning med Ethernet-nätverkskort. Den är utformad så att maskinvarustödlagret är inbyggt i en separat modul från skiktet för bearbetning av nätverkspaket och kernelgränssnitt. Det här stödskiktet för maskinvarudrivrutiner kallas för en KDNET-utökningsmodul.
KDNET är den enda transport som kan utökas för att köras på maskinvara med hjälp av en separat dll för utökningsbarhetsmodulen för maskinvarudrivrutiner. Det är målet att stödja all felsökning av Windows via KDNET- och KDNET-utökningsmoduler. Alla andra DLL:er för kerneltransport (kdcom.dll, kd1394.dll, kdusb.dllosv.) kommer så småningom att bli inaktuella och borttagna från Windows.
Det finns två typer av gränssnitt som KDNET använder för att kommunicera med KDNET-utökningsmoduler. Det ena är ett paketbaserat gränssnitt som används för nätverkskort, USB och trådlös maskinvara, och det andra är ett bytebaserat gränssnitt som används för att stödja KDNET via seriell maskinvara.
KDNET-utökningsmoduler måste följa mycket stränga krav för att fungera korrekt. Eftersom de används för kernel-felsökning anropas och körs de när systemet avhåller ytterligare körning av kod. I allmänhet är alla processorer i systemet låsta i en IPI förutom processorn som kommunicerar med felsökningsprogrammet som körs på värddatorn via kernel-felsökningstransporten. Processorn körs vanligtvis med avbrott helt inaktiverade och snurrar i princip på felsökningstransportmaskinvaran i väntan på att kommandon ska komma från felsökningsprogrammet.
Import och export
KDNET-utökningsmoduler har exakt en explicit export – KdInitializeLibrary. De har inte heller någon explicit import. KDNET-utökningsmoduler skickas en pekare till en struktur med en lista över de rutiner som de tillåts anropa av KDNET när de anropar KdInitializeLibrary. Inga andra rutiner kan anropas. Punkt. KDNET-utökningsmoduler som har importer är felaktigt utformade och stöds inte.
Om du dumpar importerna och exporterna för en KDNET-extensibilitetsmodul med hjälp av länkarna /dump /exports och /dump /imports, ser du att de bara har en export (KdInitializeLibrary) och inga importer. KDNET-utökningsmoduler rapporterar sina ytterligare exporter till KDNET genom att fylla i funktionspekare i en exportfunktionsstruktur som KDNET skickar en pekare till när KdInitializeLibrary anropas. KDNET använder sedan funktionspekarna i den strukturen för att anropa till utökningsmodulen och utföra dataöverföringar med hjälp av den maskinvara som stöds av modulen. KDNET avgör om modulen är en paketbaserad eller bytebaserad modul genom att titta på vilka specifika funktioner modulen fyller i exportfunktionstabellen i strukturen. Vissa av dessa funktioner är till för paketbaserad maskinvara och andra för seriebaserad maskinvara. Vissa av funktionerna i tabellen används av både serie- och paketbaserad maskinvara (KdInitializeController, KdShutdownController, KdGetHardwareContextSize).
Koddesign
KDNET-utökningsmoduler ska skrivas som enkel trådad kod. De bör inte utföra någon synkronisering. Alla kernel-felsökningstransporter är beroende av Windows-kerneln för att utföra rätt synkronisering när felsökaren anges. Kerneln har ett felsökningslås som det tar när den kommer in i kernelfelsökaren och låser även de andra processorerna i systemet i en IPI när felsökningsprogrammet anges. Dessa processorer släpps endast när kernelfelsökaren som körs på värden meddelar måldatorn att tillåta fortsatt körning. Eftersom kerneln utför den här synkroniseringen får KDNET-utökningsmodulerna absolut inte använda några spinlocks, mutexes, grindar eller någon annan Windows-synkroniseringsmekanism i koden. De bör skrivas för att programmera sin respektive hårdvara direkt för att skicka och ta emot paket och/eller byte.
Kod för KDNET-utökningsmoduler bör göras så helt enkelt som möjligt. Detta hjälper till att säkerställa att det är så felfritt som möjligt, eftersom felsökning av KDNET-utökningsmodulkod live på en dator för närvarande inte är möjlig utan att använda en maskinvarufelsökare. Du kan inte använda kernelfelsökaren för att felsöka transportkoden för kernelfelsökning. Om du försöker göra det startas datorn om på grund av en blåst kernelstack (som vanligtvis slutar med ett dubbelt fel och en omstart) eller ett dödläge, eller så kommer transporten att återaktiveras, vilket i de flesta fall gör att transporten inte fungerar korrekt.
Namngivningskonventioner för KDNET-utökningsmoduler
Din kernel-felsökningstransportmodul måste följa en av två namngivningskonventioner för KDNET-utökningsmoduler. Om din modul är till för att stödja PCI-baserad maskinvara måste den namnges kd_YY_XXXX.dll där XXXX är PCI-leverantörs-ID för din maskinvara i hex och YY är PCI-klassen för din maskinvara. Det finns flera KDNET-utökningsmoduler som levereras med Windows och som stöder PCI-baserad hårdvara. Intelskd_02_8086.dll, Broadcomskd_02_14e4.dlloch Realtekskd_02_10ec.dll. Du kan leta upp registrerade PCI-leverantörs-ID:n på https://www.pcisig.com/membership/member-companies Alla PCI-baserade KDNET-utökningsmoduler använder leverantörs-VID för den maskinvara som de stöder i hex som de sista 4 tecknen i namnet på modulen. Klasskoden för de flesta in box-modulerna är 02, eftersom de är nätverksenheter och därför har en PCI-klass med 0x02 i deras PCI-konfigurationsutrymme. Winload.exe skapar namnet på PCI-baserade KDNET-utökningsmoduler genom att läsa PCI-enhetsklassen och PCI VID för den valda felsökningsenheten från dess PCI-konfigurationsutrymme och försöker läsa in en modul med dessa identifierare i namnet. Om enheten har en PCI-klasskod som inte är nätverksklassen 0x02 måste du använda rätt PCI-klasskod i hexadecimalt för enheten, i namnet på din KDNET-utökningsmodul. Annars kommer din modul inte att laddas in korrekt av winload. Den _02_
i vart och ett av dessa namn är PCI-klasskoden för nätverksenheter i hex. Den här koden hittas också och läss från PCI-konfigurationsutrymmet för felsökningsenheten.
Om du har en enhet som har en DBG2-tabellpost och inte är en PCI-baserad enhet är namngivningskonventionen för modulen annorlunda. Namngivningskonventionen för DBG2-tabellens felsökningsenheter är kd_XXXX_YYYY.dll, där XXXX är hexadecimalt DBG2-tabellens PortType, och YYYY är hexadecimalt DBG2-tabellens PortSubtype från posten i DBG2-tabellen. Kd_8003_5143.dll är en inkorgs-DLL för att stödja ett nät (0x8003) PortType med en undertyp av 0x5143. I det här fallet är 5143 Qualcomm PCI VID, eftersom detta är för att stödja KDNET på Qualcomm USB-styrenheter, och för Net DBG 2-tabellposter definieras PortSubtype som PCI VID för leverantören av maskinvaran. Observera att du har stöd för serie-, USB- och andra DBG2-tabellenheter med hjälp av den här namngivningskonventionen. Följande är de PortType-värden som stöds i hex: 8000 för serieenheter, 8001 för 1394-enheter, 8002 för USB-enheter, 8003 för NET-enheter. Observera att undertyperna för serie- och USB-enheter måste reserveras med Microsoft. Microsoft har en lista över de allokerade serie- och USB-undertyperna. Skicka e-post till kdnet@microsoft.com för att reservera en serie- eller USB-undertyp, om de befintliga typerna som stöds inte fungerar med maskinvaran.
KDNET-importer för utökningsbarhet
Följande är en lista över rutiner som du kan anropa från en KDNET-utökningsmodul. Observera att alla dessa rutiner skickas till rutinen KdInitializeLibrary, och headerfilen kdnetextensibility.h mappar om vanliga anrop till dessa rutiner för att skickas genom importtabellen. Koden måste anropa dessa via importtabellen så att modulen inte har några importer. Du får inte anropa några andra rutiner som exporteras av kerneln, HAL eller någon annan kernelmodul. Du kan bara kalla dessa rutiner. Den här uppsättningen rutiner har visat sig vara tillräcklig för att utveckla alla KDNET-utökningsmoduler i rutan och bör räcka för normala scenarier. Om du behöver ytterligare rutiner som exporteras av kerneln, men inte finns med i den här listan, skickar du e-post till kdnet@microsoft.com förklarar ditt scenario och vilka ytterligare rutiner du behöver och varför. Observera att den här listan endast kommer att läggas till i större Windows-versionscykler om alls. Observera att de flesta av dessa rutiner motsvarar direkt windows kernel-API:er som stöds av antingen kerneln eller HAL. En eller två är endast anpassade KDNET-rutiner.
Det är viktigt att du inkluderar kdnetextensibility.h korrekt i rubrikerna så att rätt ommappning av rutiner via importtabellen kan ske. Om detta inte görs kommer modulen att ha importer och stöds inte.
Läsa-och-skriva-minnesrutiner
Följande rutiner bör användas för att läsa och skriva till minnesmappat enhetsminne. Dessa har samma anropskonvention och mappas till motsvarande kernelrutiner: READ_REGISTER_UCHAR, READ_REGISTER_USHORT, READ_REGISTER_ULONG, WRITE_REGISTER_UCHAR, WRITE_REGISTER_USHORT, WRITE_REGISTER_ULONG och på 64-bitarsplattformar endast READ_REGISTER_ULONG64 och WRITE_REGISTER_ULONG64. All åtkomst till enhetens minne bör göras genom dessa rutiner eftersom de säkerställer att läsningar och skrivningar inte sorteras om av processorn. Observera att msdn.microsoft.com dokumenterar Windows CE Compact 2013-rutiner som motsvarar anropskonventionen till dessa rutiner. Tyvärr verkar det som om NT-rutinerna inte är dokumenterade, men anropskonventionen är densamma.
Läs I/O-portrutiner
Följande rutiner ska användas för att läsa och skriva till enhetens I/O-portar. Dessa har samma anropskonvention och mappas till motsvarande kernelrutiner: READ_PORT_UCHAR, READ_PORT_USHORT, READ_PORT_ULONG, WRITE_PORT_UCHAR, WRITE_PORT_USHORT och WRITE_PORT_ULONG. All åtkomst till enhetens I/O-port ska utföras genom dessa rutiner. Observera att msdn.microsoft.com dokumenterar Windows CE Compact 2013-rutiner som motsvarar anropskonventionen till dessa rutiner.
Ytterligare rutiner
Följande ytterligare rutiner kan anropas och bör anropas normalt med de angivna parametrarna. Observera att genom att korrekt inkludera headerfilen kdnetextensibility.h kommer funktionsanropen att mappas om via KDNET:s tabell för utökningsbarhetsimport, vilket innebär att det inte finns några explicita importer i din modul, som krävs för KDNET-utökningsmoduler.
PHYSICAL_ADDRESS
KdGetPhysicalAddress (
__in PVOID Va
);
VOID
KeStallExecutionProcessor (
__in ULONG Microseconds
);
ULONG
KdGetPciDataByOffset (
__in ULONG BusNumber,
__in ULONG SlotNumber,
__out_bcount(Length) PVOID Buffer,
__in ULONG Offset,
__in ULONG Length
);
ULONG
KdSetPciDataByOffset (
__in ULONG BusNumber,
__in ULONG SlotNumber,
__in_bcount(Length) PVOID Buffer,
__in ULONG Offset,
__in ULONG Length
);
VOID
KdSetDebuggerNotPresent (
__in BOOLEAN NotPresent
);
VOID
PoSetHiberRange (
_In_opt_ PVOID MemoryMap,
_In_ ULONG Flags,
_In_ PVOID Address,
_In_ ULONG_PTR Length,
_In_ ULONG Tag
);
VOID
KeBugCheckEx (
__in ULONG BugCheckCode,
__in ULONG_PTR BugCheckParameter1,
__in ULONG_PTR BugCheckParameter2,
__in ULONG_PTR BugCheckParameter3,
__in ULONG_PTR BugCheckParameter4
);
PVOID
KdMapPhysicalMemory64 (
_In_ PHYSICAL_ADDRESS PhysicalAddress,
_In_ ULONG NumberPages,
_In_ BOOLEAN FlushCurrentTLB
);
VOID
KdUnmapVirtualAddress (
_In_ PVOID VirtualAddress,
_In_ ULONG NumberPages,
_In_ BOOLEAN FlushCurrentTLB
);
ULONG64
KdReadCycleCounter (
__out_opt PULONG64 Frequency
);
Observera att poSetHiberRange-funktionen endast ska anropas från rutinen KdSetHibernateRange. Dessutom bör de flesta KDNET-utökningsmoduler inte behöva anropa KeBugCheckEx, KdMapPhysicalMemory64 och KdUnmapVirtualAddress. Å andra sidan måste i stort sett alla KDNET-utökningsmoduler anropa KdGetPhysicalAddress för att hämta fysiska minnesadresser som krävs för att programmera DMA-motorer för enheter, och många måste anropa KeStallExecutionProcessor, KdGetPciDataByOffset och KdSetPciDataByOffset. De två sista rutinerna gäller för åtkomst till pci-konfigurationsutrymme för enheter.
Utökningsbarhetsexporter för KDNET
Följande är en kort beskrivning av var och en av KDNET-utökningsrutinerna. Du måste implementera alla rutiner som krävs för en paketbaserad KDNET-extensiblitetsmodul eller en seriebaserad KDNET-utökningsmodul. Följande är paketexporten för KDNET-extensiblitetsmodulen.
KdInitializeLibrary
/*++
Routine Description:
This routine validates that the ImportTable is a supported version. Makes
a copy of the ImportTable in its own global memory, and writes pointers to
functions that it exports into the Exports pointer also located in that
table.
This routine also writes the size in bytes of the Memory it needs into
the Length field of the Memory structure contained in the debug device
descriptor passed to this routine.
When kernel debugging is enabled, this routine will be called twice during
boot. The first time by winload to determine how much memory to allocate
for KDNET and its extensibility module, and the second time by KDNET when
the kernel first initializes the kernel debugging subsystem.
Arguments:
ImportTable - Supplies a pointer to the KDNET_EXTENSIBILITY_IMPORT
structure.
LoaderOptions - Supplies a pointer to the LoaderOptions passed to the
kernel. This allows settings to be passed to the KDNET extensibility
module using the loadoptions BCD setting.
Device - Supplies a pointer to the debug device descriptor.
Return Value:
STATUS_INVALID_PARAMETER if the version of the import or export table is
incorrect.
STATUS_SUCCESS if initialization succeeds.
--*/
NTSTATUS
KdInitializeLibrary (
__in PKDNET_EXTENSIBILITY_IMPORTS ImportTable,
__in_opt PCHAR LoaderOptions,
__inout PDEBUG_DEVICE_DESCRIPTOR Device
)
{
NTSTATUS Status;
PKDNET_EXTENSIBILITY_EXPORTS Exports;
__security_init_cookie();
Status = STATUS_SUCCESS;
KdNetExtensibilityImports = ImportTable;
if ((KdNetExtensibilityImports == NULL) ||
(KdNetExtensibilityImports->FunctionCount != KDNET_EXT_IMPORTS)) {
Status = STATUS_INVALID_PARAMETER;
goto KdInitializeLibraryEnd;
}
Exports = KdNetExtensibilityImports->Exports;
if ((Exports == NULL) || (Exports->FunctionCount != KDNET_EXT_EXPORTS)) {
Status = STATUS_INVALID_PARAMETER;
goto KdInitializeLibraryEnd;
}
//
// Return the function pointers this KDNET extensibility module exports.
//
Exports->KdInitializeController = KdInitializeController;
Exports->KdShutdownController = KdShutdownController;
Exports->KdSetHibernateRange = KdSetHibernateRange;
Exports->KdGetRxPacket = KdGetRxPacket;
Exports->KdReleaseRxPacket = KdReleaseRxPacket;
Exports->KdGetTxPacket = KdGetTxPacket;
Exports->KdSendTxPacket = KdSendTxPacket;
Exports->KdGetPacketAddress = KdGetPacketAddress;
Exports->KdGetPacketLength = KdGetPacketLength;
Exports->KdGetHardwareContextSize = KdGetHardwareContextSize;
//
// Return the hardware context size required to support this device.
//
Status = ContosoInitializeLibrary(LoaderOptions, Device);
KdInitializeLibraryEnd:
return Status;
}
Den här rutinen anropas för att skicka import- och exportrutinerna mellan KDNET och den här utökningsmodulen för KDNET. Den här rutinen bör verifiera att versionen av både import- och exporttabellerna förväntas och stöds, och misslyckas annars. Den bör göra en kopia av importtabellen i sitt eget globala minne. Den bör skriva de rutiner som den exporterar till strukturen som pekas på av fältet Exporter i importtabellen. Det måste också ange fältet Längd i minnesstrukturen som ingår i felsökningsenhetens beskrivningspekare som skickas till den här rutinen, med det antal byte minne som krävs för att stödja maskinvaruenheten.
Verifiera importexportantal
Koden måste kontrollera att Imports FunctionCount matchar det som är tillgängligt i operativsystemet, till exempel – (KdNetExtensibilityImports->FunctionCount != KDNET_EXT_IMPORTS)
och returnera STATUS_INVALID_PARAMETER
om antalet inte matchar.
Genom att kontrollera antalet säkerställs kompatibiliteten mellan den Windows OS KDNET-version som körs (t.ex. boot manager/OS-inläsare/hypervisor/Säker kernel/NT OS, som alla länkar till KDNET-biblioteket) och den WDK-version som används för att skapa den aktuella KDNET-utökningsmodulen. WDK och OS-versionen måste synkroniseras. Annars misslyckas kontrollen ovan om import-/exporträknarens värde ändras. Om KDNET-utökningsgränssnittet till exempel har lagt till en ny funktion matchar antalet inte längre. Se till att de matchar genom att alltid använda WDK-versionen som matchar operativsystemet som är värd för KDNET-versionen.
Anpassa nödvändigt minne
Observera att enheten fylls i med den maskinvara som valts för felsökningsprogrammet. Den här rutinen bör anpassa mängden minne som krävs baserat på enheten om det behövs. Till exempel kan utökningsmoduler som stöder både 1Gig- och 10Gig-maskinvara öka den minnesstorlek som de begär för 10Gig-enheter. De kan avgöra vilken enhet som används genom att undersöka deviceID-fältet i felsökningsenhetens beskrivning.
KdInitializeLibrary är den enda exporten
Observera att den här rutinen anropas både av winload och av KDNET under KdInitSystem-anropet. Observera att detta är den ENDA rutin som exporteras av KDNET-utökningsmoduler. Det är den enda rutinen som placeras i en .def-fil. KDNET-utökningsmoduler har exakt en explicit export – den här rutinen – och ingen import.
KdSetHibernateRange
VOID
KdSetHibernateRange (
VOID
)
/*++
Routine Description:
This routine is called to mark the code in the KDNET extensiblity module
so that it can be properly handled during hibernate and resume from
hibernate.
Arguments:
None.
Return Value:
None.
--*/
Den här rutinen anropas av systemet före viloläge så att den korrekt kan registrera koden som används av KDNET-utökningsmodulen med systemet. Detta gör att systemet kan hantera minnet korrekt under viloläge och återuppta från viloläge. (Minnet sparas senare och hämtas tidigare eftersom det kommer att anropas redan mycket tidigt under återupptagningen.)
KdInitializeController
NTSTATUS
KdInitializeController(
__in PVOID Adapter
)
/*++
Routine Description:
This function initializes the Network controller. The controller is setup
to send and recieve packets at the fastest rate supported by the hardware
link. Packet send and receive will be functional on successful exit of
this routine. The controller will be initialized with Interrupts masked
since all debug devices must operate without interrupt support.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Return Value:
STATUS_SUCCESS on successful initialization. Appropriate failure code if
initialization fails.
--*/
Den här rutinen anropas för att initiera maskinvaran. Det anropas när systemet initieras och när systemet vaknar från ett lågeffektstillstånd som det kallade KdShutdownController för. Den här rutinen måste se till att maskinvaran har slutfört initieringen helt och att den är redo att skicka paket innan den returneras. Den här rutinen bör vänta tills PHY aktiveras och att länken upprättas. Observera att om det inte finns någon kabel ansluten bör den här rutinen inte stanna på obestämd tid. Den här rutinen anger länkhastigheten och duplex i den delade KDNET-datastrukturen som delas mellan KDNET och den här utökningsmodulen. Den skriver också mac-adressen som används av maskinvaran till den plats som targetmacaddress pekar på i den delade KDNET-datastrukturen.
KdShutdownController
VOID
KdShutdownController (
__in PVOID Adapter
)
/*++
Routine Description:
This function shuts down the Network controller. No further packets can
be sent or received until the controller is reinitialized.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Return Value:
None.
--*/
Det är avgörande att denna rutin väntar tills alla överföringspaket som fortfarande väntar faktiskt skickas ut i nätverket. Den här rutinen måste vänta tills alla överföringspaket har DMA:ats från huvudminnet och är ute på kabeln INNAN den stänger av sändningen i hårdvaran. När alla väntande överföringspaket har skickats bör den här rutinen stänga av maskinvaran helt. Den här rutinen anropas när systemet stängs av och även när systemet bestämmer sig för att strömhantera felsökningstransporten till ett lågeffektstillstånd. Detta kan anropas när systemet går i vänteläge, viloläge, viloläge och anslutet vänteläge, förutom när systemet stängs av.
KdGetHardwareContextSize
ULONG
KdGetHardwareContextSize (
__in PDEBUG_DEVICE_DESCRIPTOR Device
)
/*++
Routine Description:
This function returns the required size of the hardware context in bytes.
Arguments:
Device - Supplies a pointer to the debug device descriptor.
Return Value:
None.
--*/
Den här rutinen bör returnera det antal byte som krävs för allt minne som behövs för att stödja maskinvaran. Detta inkluderar din kontextstruktur och alla paketbuffertar för mottagning och överföring, samt eventuella maskinvarupaketbeskrivningar och andra strukturer. Storleken på ALLT minne som du behöver måste rapporteras här. Inklusive extra minne som krävs för justeringsbegränsningar som maskinvaran kan ha för paket, paketbeskrivningar eller andra strukturer.
Observera att den här rutinen ska anropas av din KdInitializeLibrary-rutin när den anger fältet Minneslängd i felsökningsenhetens beskrivning.
KdGetRxPacket
NTSTATUS
KdGetRxPacket (
__in PVOID Adapter,
__out PULONG Handle,
__out PVOID *Packet,
__out PULONG Length
)
/*++
Routine Description:
This function returns the next available received packet to the caller.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Handle - Supplies a pointer to the handle for this packet. This handle
will be used to release the resources associated with this packet back
to the hardware.
Packet - Supplies a pointer that will be written with the address of the
start of the packet.
Length - Supplies a pointer that will be written with the length of the
received packet.
Return Value:
STATUS_SUCCESS when a packet has been received.
STATUS_IO_TIMEOUT otherwise.
--*/
Den här rutinen hämtar nästa tillgängliga paket som har tagits emot, men som ännu inte har bearbetats. Den returnerar ett handtag för paketet. Handtaget används för att hämta paketets adress genom att anropa KdGetPacketAddress, samt längden genom att anropa KdGetPacketLength. Paketet och handtaget måste vara tillgängliga och giltiga tills paketet släpps genom att anropa KdReleaseRxPacket. Den här rutinen returnerar också paketadressen och längden direkt till anroparen.
Om inget paket är tillgängligt för närvarande måste den här rutinen returneras omedelbart med STATUS_IO_TIMEOUT. Den här rutinen får inte vänta tills ett paket tas emot. Observera att de 2 översta bitarna i Handle är reserverade. TRANSMIT_HANDLE och TRANSMIT_ASYNC måste båda vara tydliga.
KdReleaseRxPacket
VOID
KdReleaseRxPacket (
__in PVOID Adapter,
ULONG Handle
)
/*++
Routine Description:
This function reclaims the hardware resources used for the packet
associated with the passed Handle. It reprograms the hardware to use those
resources to receive another packet.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Handle - Supplies the handle of the packet whose resources should be
reclaimed to receive another packet.
Return Value:
None.
--*/
Den här rutinen släpper de resurser som är associerade med paketreferensen tillbaka till maskinvaran så att de kan användas för att ta emot ett annat paket. Varje lyckat anrop till KdGetRxPacket följs av ett nytt anrop till KdReleaseRxPacket, där handtaget som returnerades från KdGetRxPacket används. Observera att det INTE är garanterat att KdReleaseRxPacket anropas omedelbart efter att KdGetRxPacket har lyckats. Det är möjligt att ett annat KdGetRxPacket-anrop görs först. Men varje lyckat KdGetRxPacket-anrop får sina resurser frisläppta med ett KdReleaseRxPacket-anrop.
Den här rutinen bör programmera maskinvaran korrekt så att de frisläppta resurserna kan användas för att ta emot ett annat paket.
KdGetTxPacket
NTSTATUS
KdGetTxPacket (
__in PVOID Adapter,
__out PULONG Handle
)
/*++
Routine Description:
This function acquires the hardware resources needed to send a packet and
returns a handle to those resources.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Handle - Supplies a pointer to the handle for the packet for which hardware
resources have been reserved.
Return Value:
STATUS_SUCCESS when hardware resources have been successfully reserved.
STATUS_IO_TIMEOUT if the hardware resources could not be reserved.
STATUS_INVALID_PARAMETER if an invalid Handle pointer or Adapter is passed.
--*/
Den här rutinen hämtar nästa lediga överföringsresurser och returnerar en referens till dem. Det här handtaget används för att anropa KdGetPacketAddress och KdGetPacketLength. Paketadressen som returneras av KdGetPacketAddress används för att skriva innehållet i paketet direkt. Paketadressen måste vara början av paketet och längden ska vara det maximala antalet byte som kan skrivas till paketet. Observera att om det inte finns några tillgängliga maskinvaruresurser, eftersom de alla har förvärvats och ännu inte har överförts, bör den här rutinen omedelbart returnera STATUS_IO_TIMEOUT.
TRANSMIT_HANDLE måste anges i det returnerade handtaget. Observera att de två översta bitarna i Handle är reserverade för flaggorna TRANSMIT_ASYNC och TRANSMIT_HANDLE.
KdSendTxPacket
NTSTATUS
KdSendTxPacket (
__in PVOID Adapter,
ULONG Handle,
ULONG Length
)
/*++
Routine Description:
This function sends the packet associated with the passed Handle out to the
network. It does not return until the packet has been sent.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Handle - Supplies the handle of the packet to send.
Length - Supplies the length of the packet to send.
Return Value:
STATUS_SUCCESS when a packet has been successfully sent.
STATUS_IO_TIMEOUT if the packet could not be sent within 100ms.
STATUS_INVALID_PARAMETER if an invalid Handle or Adapter is passed.
--*/
Den här rutinen skickar paketet som är associerat med det skickade handtaget ut på nätverket. Observera att Handle kan ha ytterligare en bituppsättning, som anger om sändningen är en asynkron överföring eller inte. Om flaggan TRANSMIT_ASYNC anges i handtaget bör den här rutinen programmera maskinvaran för att skicka paketet och bör sedan omedelbart returnera utan att vänta på att maskinvaran ska slutföra sändningen. Det innebär att eventuella fel som inträffar under sändningen går förlorade. Det är OK, och avsiktligt, eftersom paket kan gå förlorade på tråden ändå. Om flaggan TRANSMIT_ASYNC inte har angetts i referensen måste den här rutinen vänta tills paketet har skickats ut på tråden och returnera eventuella fel som inträffar under överföring. Observera att när dumpfiler skickas till felsökarvärden, eller när Windows-nätverkspaket skickas från KDNIC via KDNET, ställs TRANSMIT_ASYNC in. När alla andra felsökningspaket skickas kommer TRANSMIT_ASYNC att vara återställd.
Om en uppsättning paket skickas med TRANSMIT_ASYNC set TRUE, följt av ett paket som inte har TRANSMIT_ASYNC inställt, måste maskinvaran vänta tills paketet utan flagguppsättningen faktiskt skickas, även om det innebär att det måste vänta tills de tidigare asynkrona paketen också skickas.
KdGetPacketAddress
PVOID
KdGetPacketAddress (
__in PVOID Adapter,
ULONG Handle
)
/*++
Routine Description:
This function returns a pointer to the first byte of a packet associated
with the passed handle.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Handle - Supplies a handle to the packet for which to return the
starting address.
Return Value:
Pointer to the first byte of the packet.
--*/
Den här rutinen returnerar en pekare till den första byten av paketet som är associerat med det överlämnade Handlet. Observera att referensen har TRANSMIT_HANDLE-biten sätts för överföringspaket och att TRANSMIT_HANDLE-biten är av för att ta emot paket. Den returnerade pekaren ska vara en virtuell Windows-adress som kan läsas eller skrivas av processorn. Den här adressen bör ingå i det minnesblock som är reserverat för KDNET-utökningsmodulen som skickas i felsökningsenhetens beskrivningsminnesstruktur. (Observera att KDNET-utökningsmodulen ALDRIG ska använda mer än den minnesstorlek som begärdes i KdInitializeLibrary vid åtkomst till det minnet. Allt extra minne i slutet av blocket är reserverat för användning av KDNET och får inte röras av KDNET-utökningsmodulen.)
KdGetPacketLength
ULONG
KdGetPacketLength (
__in PVOID Adapter,
ULONG Handle
)
/*++
Routine Description:
This function returns the length of the packet associated with the passed
handle.
Arguments:
Adapter - Supplies a pointer to the debug adapter object.
Handle - Supplies a handle to the packet for which to return the
length.
Return Value:
The length of the packet.
--*/
Den här rutinen returnerar antalet byte av paketet som är associerat med det överförda Handle. Observera att handtaget har TRANSMIT_HANDLE-biten satt för överföringspaket, och att TRANSMIT_HANDLE-biten inte är satt för mottagningspaket. För överföringspaket bör den här längden vara det maximala antalet byte som kan skrivas till paketet. För mottagningspaket bör den här längden vara det faktiska antalet byte i det mottagna paketet.
Felsöka KDNET-utökningsmoduler
För att felsöka en KDNET-utökningsmodul måste du köra följande bcdedit-kommandon från en upphöjd kommandotolk på måldatorn.
Först och viktigast av allt måste du köra följande två kommandon för att se till att Winload tillåter upprepade startfel utan att gå en särskild felsökväg som bryter sig in i felsökningsprogrammet och förhindrar normal start. Om du kör dessa kommandon kan du starta om datorn upprepade gånger med nya bitar och felsöka de nya bitarna utan problem.
Bcdedit -set {current} BootStatusPolicy IgnoreAllFailures
Bcdedit -set {current} RecoveryEnabled No
Förutsatt att du använder seriell felsökning på com1 på måldatorn för att felsöka utökningsmodulen gör du följande.
bcdedit -dbgsettings serial debugport:1 baudrate:115200
Detta anger standardtransporten för felsökning till seriell på com1 på 115200 baud. De här inställningarna används även för startfelsökning.
bcdedit -debug on
Detta möjliggör kernel-felsökning.
bcdedit -bootdebug on
Detta möjliggör startfelsökning på winload.exe, som du använder för att felsöka i den tidiga kärninitieringen, inklusive din KDNET-förlängningsmodul.
bcdedit -set kerneldebugtype net
Den här inställningen tvingar typen av kernel-felsökning till "net", oavsett de angivna standardinställningarna för felsökningstransport. Detta gör att winload.exe läser in kdnet.dll som kernel-felsökningstransport.
bcdedit -set kernelbusparams b.d.f
Där b är bussnumret, d är enhetsnumret och f är funktionsnumret – allt i decimal – för maskinvaran som du skriver modulen KDNET extensiblity för. Dessa siffror beror på vilken PCI-plats som maskinvaran finns i. Du hittar dessa genom att hitta platssträngen på sidan enhetsegenskaper på nätverksenheten i Enhetshanteraren för Windows. Öppna Windows-enhetshanteraren, dubbelklicka på nätverksenheter, leta reda på din enhet, dubbelklicka på den och i fönstret som öppnas ska det finnas ett Plats: fält som innehåller bussen, enheten och funktionen för maskinvaran på PCI-bussen. Om du har en busschaufför som gör att informationen maskeras måste du fastställa platsen från dina förare eller på något annat sätt.
Detta tvingar kernel busparams till b.d.f – vilket tvingar den specifika enheten att väljas som kernel-felsökningsenhet.
bcdedit -set kernelhostip N
Där N bestäms av följande formel. Om värdfelsökardatorn har en IPv4-adress för w.x.y.z, så N = (w0x01000000) + (x0x00010000) + (y0x00000100) + (z0x00000001). N måste anges på kommandoraden i decimal, inte hex. I praktiken tar du varje byte av IPv4-adressen och sammanfogar den (i hex) för att skapa ett 32-bitars tal i hex, och sedan konverterar du det till decimal.
bcdedit -set kernelport N
Där N är 50000 eller någon annan port som inte blockeras i ditt interna nätverk.
Detta tvingar KDNET att använda port N som nätverksfelsöksport.
bcdedit -set kernelkey 1.2.3.4
Detta tvingar KDNET-felsökningsnyckeln till 1.2.3.4. 1.2.3.4 är inte en säker eller unik nyckel på nätverket. För att hålla måldatorerna säkra måste paket som skickas mellan värd- och måldatorerna krypteras. Vi rekommenderar starkt att du använder en automatiskt genererad krypteringsnyckel. Mer information finns i Konfigurera KDNET-nätverkskärnfelsökning automatiskt.
bcdedit -set kerneldhcp on
Detta tvingar KDNET-kernelns dhcp-inställning till på.
Kör felsökningsprogrammet på felsökarens värddator med följande kommandorad förutsatt att du använder com1 som seriell felsökningsport på värddatorn:
windbg -d -k com:port=com1,baud=115200
Det kör felsökningsprogrammet och gör att det bryts när windbg-startfelsökaren först kommunicerar med värddatorn.
Starta sedan om måldatorn genom att köra
shutdown -r -t 0
När felsökningsprogrammet går in i windbg, kontrollera att symbolerna laddas in för winload. (kan behöva ange .sympath och göra en .reload). Kör sedan x winload!*deb*tra*
. En av symbolerna i listan är något som liknar BdDebugTransitions.
Kör sedan ed winload!BdDebugTransitions 1
, men se till att använda rätt symbolnamn.
Kör sedan bu winload!blbdstop
för att ange en brytpunkt.
Slå sedan g
för att börja.
Du bör avbryta vid winload!BlBdStop.
Kör sedan följande kommandon.
bu nt!KdInitSystem
bu kdnet!KdInitialize
bu kdstub!KdInitializeLibrary
Observera att du troligen kommer att använda kdstub när du ställer in brytpunkter i KDNET-utökningsmodulen, om det inte fungerar använder du
bu kd_YY_XXXX!KdInitializeLibrary
Där YY är din PCI-klass och XXXX är din PCI VID. (dvs. Använd namnet på din KDNET-utökningsmodul.)
Vanligtvis i felsökningsprogrammet måste du använda kdstub i stället för att använda det faktiska namnet på utökningsmodulen.
Kör sedan bl
för att visa brytpunkterna. Kontrollera att brytpunkterna är på plats (alla bör ha ett e bredvid sig).
Tryck sedan på g
. Du borde nå nt!KdInitSystem-brytpunkt.
Tryck på g
igen, och du bör nå kdnet!KdInitialize
Tryck på g
igen så bör du nå en brytpunkt i din egen modul vid KdInitializeLibrary.
Sedan kan du ange en brytpunkt för din InitializeController-rutin samt alla andra rutiner och gå igenom koden.
När du har klivit igenom KdInitializeLibrary anger du g, och om du har angett en brytpunkt för din InitializeController-rutin kommer den att träffas näst.
När det är klart kontrollerar du att du har brytpunkter inställda på dina rutiner för KdGetTxPacket, KdSendTxPacket, KdGetRxPacket, KdReleaseRxPacket och träffar g igen, och dessa rutiner körs som en del av nätverksinitiering som utförs av KDNET under starten.
Du kan behöva lägga till tillfällig kod i dina KdInitializeLibrary- eller KdInitializeController-rutiner för att se till att alla dina rutiner anropas så att du kan gå igenom all kod. (KdShutdownController anropas till exempel inte under starten när saker fungerar normalt, så du måste uttryckligen anropa den från tillfällig kod så att du kan gå igenom den och se till att den är korrekt.)
När du har gått igenom all din kod och är säker på att det är korrekt, starta sedan om målet, men ställ INTE in winload! BdDebugTransitions flagga till true (lämna den som standard till noll).
Kör sedan även ytterligare en instans av kernelfelsökaren på värdfelsökardatorn.
Windbg -d -k net:port=50000,key=1.2.3.4
Låt måldatorn starta och den bör ansluta till den andra instansen av kernelfelsökaren via nätverket.
Kör sedan kommandon i kernelfelsökaren och se till att det fungerar och låt sedan målet fortsätta starta och se till att du senare kan bryta in och köra kommandon.
Anmärkning
Om du ställer in flaggan för felsökningsövergångar i winload garanterar du att Windows INTE STARTAR. Om du försöker låta Windows avsluta starten efter att du har angett flaggan kraschar eller låser sig Windows helt enkelt. Om du vill att Windows ska starta upp korrekt kan du inte ställa in debuggövergångsflaggan. Genom att ange flaggan kan du felsöka koden och kontrollera att den är korrekt genom att gå igenom den i felsökningsprogrammet, men i slutändan måste du inte ange flaggan så att du kan kontrollera att felsökningen fungerar när du startar normalt. Det innebär att du inte kan gå igenom koden när du startar systemet normalt, och när Windows körs normalt, med felsökning aktiverat på maskinvaran, kan KDNET-utökningsmodulen inte felsökas. Alla försök att felsöka den med kernelfelsökaren gör att datorn kraschar. (Du kan inte ange brytpunkter i kod som körs i kärnavägar för felsökning, eftersom det orsakar oändlig återinmatning, en kraschad stack och en tvingad omstart.)
Flera fysiska funktioner – 2PF
Utöver utökningsbarheten för KDNET stöder KDNET kernel-felsökning med flera fysiska funktioner (PFs) på de nätverkskort som stöds genom att partitionera PCI-konfigurationsutrymmet. Nätverkskortleverantörer uppmuntras att aktivera stöd för den här funktionen. Mer information finns i Debugger 2PF KDNET Miniport Network Driver Support.
Se även
Konfigurera KDNET-nätverkskärnfelsökning automatiskt
Konfigurera KDNET-nätverkskärnfelsökning manuellt
Felsökningsprogram 2PF KDNET Miniport Network Driver Support