replace nob with ms' build, move disk creation to build.bat, major comment cleanup, remove old and stupid tests, overhaul interrupt management with per-CPU vector allocation, affinity migration and safe teardown, add proper IOAPIC routing and PCI MSI/MSI-X/INTx support, migrate drivers to the new interrupt API, integrate ACPICA with a proper OS services layer, move ACPI firmware events, power button handling and S5 shutdown into acpi.sys, add parallel driver startup and atomic publication, replace PnP arrays with dynamic lists, redesign service startup again to be asynchronous, add delayed startup mode for services, allow omitting keys in services.ini, fix acpi ec deferred work handling, fix kernel threads having garbage exit code.
This commit is contained in:
1 parent
d36f19509c
commit
36eef8f58d
696 files changed
+147281
-7530
No files matched your search
+76
-19
@@ -10,11 +10,14 @@
|
||||
#include <kernel/mm_virt.h>
|
||||
#include <kernel/io_pnp.h>
|
||||
#include <kernel/ke_debug.h>
|
||||
#include <kernel/ke_spinlock.h>
|
||||
|
||||
#define DM_NAME_MAX 64u
|
||||
|
||||
typedef enum DM_MODULE_STATE {
|
||||
DmModuleStarting,
|
||||
DmModulePrepared,
|
||||
DmModuleCommitting,
|
||||
DmModuleStarted,
|
||||
DmModuleFailed,
|
||||
DmModuleStopping,
|
||||
@@ -26,11 +29,14 @@ struct NTL_MODULE {
|
||||
char Name[DM_NAME_MAX];
|
||||
uintptr_t ImageBase;
|
||||
DM_MODULE_STATE State;
|
||||
NTL_MODULE_COMMIT_START CommitStart;
|
||||
NTL_MODULE_ABORT_START AbortStart;
|
||||
NTL_MODULE_PREPARE_SHUTDOWN PrepareShutdown;
|
||||
NTL_MODULE_COMMIT_SHUTDOWN CommitShutdown;
|
||||
};
|
||||
|
||||
static NTL_MODULE* gDriverModules;
|
||||
static SPINLOCK gDriverModuleLock = SPINLOCK_INIT;
|
||||
|
||||
static bool DmImageContains(uintptr_t base, size_t imageSize, uintptr_t ptr, size_t bytes) {
|
||||
return ptr >= base && ptr - base <= imageSize && bytes <= imageSize - (ptr - base);
|
||||
@@ -94,7 +100,9 @@ static bool DmValidIoDriver(uintptr_t imageBase, size_t imageSize, const DRIVER_
|
||||
return true;
|
||||
}
|
||||
|
||||
KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
KSTATUS DmPrepareLoadedDriver(const char* name, uintptr_t imageBase, bool* canReleaseImage) {
|
||||
if (!canReleaseImage) return NTLSTATUS_INVALID_PARAMETER;
|
||||
*canReleaseImage = true;
|
||||
if (!name || !*name || !imageBase)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -104,18 +112,13 @@ KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
if (!length || length == DM_NAME_MAX)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
for (NTL_MODULE* it = gDriverModules; it; it = it->Next) {
|
||||
if (strcmp(it->Name, name) == 0 || it->ImageBase == imageBase)
|
||||
return NTLSTATUS_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
size_t imageSize = LdrGetImageSize(imageBase);
|
||||
if (!imageSize)
|
||||
return NTLSTATUS_INVALID_IMAGE_FORMAT;
|
||||
|
||||
const NTL_MODULE_EXPORT* manifest =
|
||||
(const NTL_MODULE_EXPORT*)LdrGetImageExport(imageBase, NTL_DDK_MODULE_EXPORT_NAME);
|
||||
NTL_MODULE_INITIALIZE initialize = (NTL_MODULE_INITIALIZE)0;
|
||||
NTL_MODULE_PREPARE_START prepareStart = (NTL_MODULE_PREPARE_START)0;
|
||||
|
||||
if (!manifest) return NTLSTATUS_INVALID_IMAGE_FORMAT;
|
||||
{
|
||||
@@ -124,15 +127,19 @@ KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
manifest->Version != NTL_DDK_MODULE_ABI_VERSION ||
|
||||
manifest->Size != sizeof(*manifest) || manifest->Flags != 0u ||
|
||||
manifest->Reserved != 0u || manifest->Reserved2 != 0u ||
|
||||
(manifest->Initialize && !DmImageContains(imageBase, imageSize,
|
||||
(uintptr_t)manifest->Initialize, 1u)) ||
|
||||
(manifest->PrepareStart && !DmImageContains(imageBase, imageSize,
|
||||
(uintptr_t)manifest->PrepareStart, 1u)) ||
|
||||
(manifest->PrepareShutdown && !DmImageContains(imageBase, imageSize,
|
||||
(uintptr_t)manifest->PrepareShutdown, 1u)) ||
|
||||
(manifest->CommitShutdown && !DmImageContains(imageBase, imageSize,
|
||||
(uintptr_t)manifest->CommitShutdown, 1u)))
|
||||
(uintptr_t)manifest->CommitShutdown, 1u)) ||
|
||||
(manifest->CommitStart && !DmImageContains(imageBase, imageSize,
|
||||
(uintptr_t)manifest->CommitStart, 1u)) ||
|
||||
(manifest->AbortStart && !DmImageContains(imageBase, imageSize,
|
||||
(uintptr_t)manifest->AbortStart, 1u)))
|
||||
return NTLSTATUS_INVALID_IMAGE_FORMAT;
|
||||
if ((manifest->DeviceCount && !manifest->Devices) ||
|
||||
manifest->DeviceCount > 64u ||
|
||||
manifest->DeviceCount > imageSize / sizeof(NTL_DEVICE_DESC) ||
|
||||
(manifest->DeviceCount &&
|
||||
!DmImageContains(imageBase, imageSize, (uintptr_t)manifest->Devices,
|
||||
(size_t)manifest->DeviceCount * sizeof(NTL_DEVICE_DESC))))
|
||||
@@ -157,7 +164,7 @@ KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
}
|
||||
}
|
||||
if ((manifest->IoDriverCount && !manifest->IoDrivers) ||
|
||||
manifest->IoDriverCount > 64u ||
|
||||
manifest->IoDriverCount > imageSize / sizeof(*manifest->IoDrivers) ||
|
||||
(manifest->IoDriverCount &&
|
||||
!DmImageContains(imageBase, imageSize, (uintptr_t)manifest->IoDrivers,
|
||||
(size_t)manifest->IoDriverCount * sizeof(*manifest->IoDrivers))))
|
||||
@@ -167,7 +174,7 @@ KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
(uintptr_t)manifest->IoDrivers[i], sizeof(DRIVER_OBJECT)))
|
||||
return NTLSTATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
initialize = manifest->Initialize;
|
||||
prepareStart = manifest->PrepareStart;
|
||||
}
|
||||
|
||||
NTL_MODULE* module = (NTL_MODULE*)MmAllocatePool(sizeof(*module));
|
||||
@@ -178,12 +185,30 @@ KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
memcpy(module->Name, name, length);
|
||||
module->ImageBase = imageBase;
|
||||
module->State = DmModuleStarting;
|
||||
module->CommitStart = manifest->CommitStart;
|
||||
module->AbortStart = manifest->AbortStart;
|
||||
module->PrepareShutdown = manifest->PrepareShutdown;
|
||||
module->CommitShutdown = manifest->CommitShutdown;
|
||||
module->Next = gDriverModules;
|
||||
gDriverModules = module;
|
||||
KSTATUS status = NTLSTATUS_SUCCESS;
|
||||
uintptr_t flags = KeAcquireSpinlock(&gDriverModuleLock);
|
||||
for (NTL_MODULE* it = gDriverModules; it; it = it->Next) {
|
||||
if (strcmp(it->Name, name) == 0 || it->ImageBase == imageBase) {
|
||||
status = NTLSTATUS_ALREADY_EXISTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (KSUCCESS(status)) {
|
||||
module->Next = gDriverModules;
|
||||
gDriverModules = module;
|
||||
}
|
||||
KeReleaseSpinlock(&gDriverModuleLock, flags);
|
||||
if (!KSUCCESS(status)) {
|
||||
MmFreePool(module);
|
||||
return status;
|
||||
}
|
||||
|
||||
KSTATUS status = initialize ? initialize(module) : NTLSTATUS_SUCCESS;
|
||||
if (prepareStart && !module->AbortStart) *canReleaseImage = false;
|
||||
status = prepareStart ? prepareStart(module) : NTLSTATUS_SUCCESS;
|
||||
if (!KSUCCESS(status) && !KFAILED(status))
|
||||
status = NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -196,10 +221,42 @@ KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase) {
|
||||
}
|
||||
}
|
||||
if (KSUCCESS(status))
|
||||
status = IoPnpPublishModule(module, manifest->Devices, manifest->DeviceCount,
|
||||
status = IoPnpPrepareModule(module, manifest->Devices, manifest->DeviceCount,
|
||||
manifest->IoDrivers, manifest->IoDriverCount);
|
||||
module->State = KSUCCESS(status) ? DmModuleStarted : DmModuleFailed;
|
||||
return status;
|
||||
if (!KSUCCESS(status)) {
|
||||
if (module->AbortStart) module->AbortStart(module);
|
||||
IoPnpAbortModule(module);
|
||||
uintptr_t flags = KeAcquireSpinlock(&gDriverModuleLock);
|
||||
NTL_MODULE** link = &gDriverModules;
|
||||
while (*link && *link != module) link = &(*link)->Next;
|
||||
if (*link) *link = module->Next;
|
||||
KeReleaseSpinlock(&gDriverModuleLock, flags);
|
||||
MmFreePool(module);
|
||||
return status;
|
||||
}
|
||||
module->State = DmModulePrepared;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Commit activates the module, exports, and PnP registrations.
|
||||
void DmCommitLoadedDriver(uintptr_t imageBase, LDR_KERNEL_MODULE* image) {
|
||||
NTL_MODULE* module = (NTL_MODULE*)0;
|
||||
uintptr_t flags = KeAcquireSpinlock(&gDriverModuleLock);
|
||||
for (NTL_MODULE* it = gDriverModules; it; it = it->Next) {
|
||||
if (it->ImageBase == imageBase && it->State == DmModulePrepared) {
|
||||
module = it;
|
||||
module->State = DmModuleCommitting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinlock(&gDriverModuleLock, flags);
|
||||
if (!module) return;
|
||||
if (module->CommitStart) module->CommitStart(module);
|
||||
LdrPublishModule(image);
|
||||
IoPnpCommitModule(module);
|
||||
flags = KeAcquireSpinlock(&gDriverModuleLock);
|
||||
module->State = DmModuleStarted;
|
||||
KeReleaseSpinlock(&gDriverModuleLock, flags);
|
||||
}
|
||||
|
||||
KSTATUS DmPrepareShutdown(void) {
|
||||
|
||||
Reference in new issue
Block a user