replace ad hoc driver loading with a proper driver manager, new DDK, new PnP manager with device matching, asynchronous startup, resource ownership and removal, add shared PCI capability helpers, replace typed, rigid services with a proper service manager, implement proper system shutdown and restart, shutting down unloads drivers and shuts down services, add simple power button, remove heavyweight boot self-tests and SMP stress runs, add monotonic timestamps to kernel debug output, fruitless USB and PS/2 fixes, make test builds opt in.

This commit is contained in:
maksw committed 2026-10-26 10:08:03 +01:00
1 parent c0ad63c27f
commit d36f19509c
160 files changed
+6563 -7366

No files matched your search

+8 -135
View File
@@ -11,72 +11,7 @@
#include <kernel/ke_debug.h>
#include <kernel/ob_object.h>
#include <kernel/ke_sched.h>
#define MAX_DRIVER_OBJECTS 64
#define MAX_PDO_OBJECTS 128
// Implements the sv Or Unnamed operation.
static SYS_STRING_VIEW IoSvOrUnnamed(SYS_STRING_VIEW name) {
return SysSvIsEmpty(name) ? SYS_SV_LITERAL("<unnamed>") : name;
}
// Implements the bus Type Name operation.
static const char* IoBusTypeName(IO_BUS_TYPE busType) {
switch (busType) {
case IoBusPci: return "pci";
case IoBusUsb: return "usb";
default: return "unknown";
}
}
// Driver object registry / PDO AddDevice binding.
static DRIVER_OBJECT* gDriverObjects[MAX_DRIVER_OBJECTS];
static uint32_t gDriverObjectCount;
static DEVICE_OBJECT* gPhysicalDevices[MAX_PDO_OBJECTS];
static uint32_t gPhysicalDeviceCount;
// Implements the driver Matches Pdo operation.
static bool IoDriverMatchesPdo(const DRIVER_OBJECT* driver, const DEVICE_OBJECT* pdo) {
if (!driver || !driver->IdTable || !pdo || pdo->Type != DeviceObjectPhysical)
return false;
for (size_t d = 0; d < driver->IdTable->Count; d++) {
const IO_DEVICE_ID* want = &driver->IdTable->Ids[d];
if (want->BusType != IoBusUnknown && want->BusType != pdo->u.Pdo.BusType)
continue;
for (uint8_t p = 0; p < pdo->u.Pdo.IdCount; p++) {
if (SysSvEqual(want->Id, pdo->u.Pdo.Ids[p].Id))
return true;
}
}
return false;
}
// Implements the try Add Device For Driver operation.
static bool IoTryAddDeviceForDriver(DRIVER_OBJECT* driver, DEVICE_OBJECT* pdo) {
if (!driver || !pdo || !driver->DriverAddDevice)
return false;
if (!IoDriverMatchesPdo(driver, pdo))
return false;
KSTATUS st = driver->DriverAddDevice(driver, pdo);
if (KSUCCESS(st)) {
DbgPrint("io: AddDevice driver=%v pdo=%v bus=%s\n",
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), IoBusTypeName(pdo->u.Pdo.BusType));
KSTATUS start = IoSendPnpIrpSync(pdo, IRP_MN_START_DEVICE);
if (!KSUCCESS(start) && start != NTLSTATUS_NOT_SUPPORTED) {
DbgPrint("io: START_DEVICE failed driver=%v pdo=%v st=0x%x\n",
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), start);
}
return true;
} else {
DbgPrint("io: AddDevice failed driver=%v pdo=%v st=0x%x\n",
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), st);
return true;
}
}
#include <kernel/io_pnp.h>
__declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver,
SYS_STRING_VIEW name) {
@@ -86,42 +21,12 @@ __declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver,
driver->Name = name;
}
// Registers driver Object.
__declspec(dllexport) KSTATUS IoRegisterDriverObject(DRIVER_OBJECT* driver) {
if (!driver) return NTLSTATUS_INVALID_PARAMETER;
if (!SysSvIsUtf8Text(driver->Name)) return NTLSTATUS_INVALID_PARAMETER;
if (gDriverObjectCount >= MAX_DRIVER_OBJECTS)
return NTLSTATUS_NO_MEMORY;
if (driver->Header.Type != ObjectTypeDriver ||
driver->Header.LifetimeState != ObjectAlive) {
ObInitializeObjectHeader(&driver->Header, ObjectTypeDriver);
}
gDriverObjects[gDriverObjectCount++] = driver;
DbgPrint("io: registered driver object %v\n", IoSvOrUnnamed(driver->Name));
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++)
(void)IoTryAddDeviceForDriver(driver, gPhysicalDevices[i]);
return NTLSTATUS_SUCCESS;
}
// Device object lifetime.
static void IoDeviceDestroy(OBJECT* object) {
DEVICE_OBJECT* dev = (DEVICE_OBJECT*)object;
IoDmaDetachDevice(dev);
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
if (gPhysicalDevices[i] == dev) {
gPhysicalDevices[i] = gPhysicalDevices[gPhysicalDeviceCount - 1u];
gPhysicalDevices[gPhysicalDeviceCount - 1u] = (DEVICE_OBJECT*)0;
gPhysicalDeviceCount--;
break;
}
}
if (dev->LowerDevice)
IoDetachDevice(dev);
@@ -232,27 +137,11 @@ __declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo) {
if (!pdo || pdo->Type != DeviceObjectPhysical)
return NTLSTATUS_INVALID_PARAMETER;
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
if (gPhysicalDevices[i] == pdo)
return NTLSTATUS_ALREADY_EXISTS;
}
KSTATUS status = IoPnpPhysicalDeviceArrived(pdo);
if (!KSUCCESS(status)) return status;
if (gPhysicalDeviceCount >= MAX_PDO_OBJECTS)
return NTLSTATUS_NO_MEMORY;
IoPnpPhysicalDevicePublished(pdo);
gPhysicalDevices[gPhysicalDeviceCount++] = pdo;
bool anyMatched = false;
for (uint32_t i = 0; i < gDriverObjectCount; i++) {
if (IoTryAddDeviceForDriver(gDriverObjects[i], pdo))
anyMatched = true;
}
if (!anyMatched && pdo->u.Pdo.BusType == IoBusUsb) {
SYS_STRING_VIEW id = pdo->u.Pdo.IdCount ? pdo->u.Pdo.Ids[0].Id : SYS_SV_LITERAL("<no-id>");
DbgPrint("io: no function driver for pdo=%v id=%v bus=%s\n",
IoSvOrUnnamed(pdo->Name), id, IoBusTypeName(pdo->u.Pdo.BusType));
}
return NTLSTATUS_SUCCESS;
}
@@ -280,24 +169,6 @@ __declspec(dllexport) void IoDereferenceDeviceObject(DEVICE_OBJECT* device) {
if (device) ObDereferenceObject(&device->Header);
}
// Releases physical Device Registry Entry.
static void IoRemovePhysicalDeviceRegistryEntry(DEVICE_OBJECT* device) {
if (!device || device->Type != DeviceObjectPhysical)
return;
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
if (gPhysicalDevices[i] == device) {
for (uint32_t j = i + 1; j < gPhysicalDeviceCount; j++)
gPhysicalDevices[j - 1] = gPhysicalDevices[j];
gPhysicalDeviceCount--;
if (gPhysicalDeviceCount < MAX_PDO_OBJECTS)
gPhysicalDevices[gPhysicalDeviceCount] = (DEVICE_OBJECT*)0;
return;
}
}
}
// Implements the unlink Device From Parent operation.
static void IoUnlinkDeviceFromParent(DEVICE_OBJECT* device) {
if (!device || !device->Parent)
return;
@@ -333,9 +204,11 @@ __declspec(dllexport) void IoDeleteDevice(DEVICE_OBJECT* device) {
device->PnpState = DevicePnpDeleted;
KeReleaseSpinlock(&device->Lock, flags);
IoDmaDetachDevice(device);
if (device->Type == DeviceObjectPhysical)
IoPnpPhysicalDeviceRemoved(device);
else
IoDmaDetachDevice(device);
IoUnlinkDeviceFromParent(device);
IoRemovePhysicalDeviceRegistryEntry(device);
IoDereferenceDeviceObject(device);
}