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:
maksw committed 2026-10-28 15:18:43 +01:00
1 parent d36f19509c
commit 36eef8f58d
696 files changed
+147281 -7530

No files matched your search

+1
View File
@@ -36,6 +36,7 @@ typedef struct DM_EDGES {
typedef enum DM_RUN_STATE {
DmRunWaiting,
DmRunStarting,
DmRunStarted,
DmRunFailed,
DmRunBlocked,
+4 -1
View File
@@ -1,9 +1,12 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <ntlite/status.h>
KSTATUS DmStartLoadedDriver(const char* name, uintptr_t imageBase);
KSTATUS DmPrepareLoadedDriver(const char* name, uintptr_t imageBase, bool* canReleaseImage);
struct LDR_KERNEL_MODULE;
void DmCommitLoadedDriver(uintptr_t imageBase, struct LDR_KERNEL_MODULE* image);
KSTATUS DmPrepareShutdown(void);
void DmCommitShutdown(void);
+14 -12
View File
@@ -132,7 +132,6 @@ typedef struct HAL_TIMER {
void (*Stall)(uint32_t us);
void (*HandleInterrupt)(void);
void (*ConfigureCurrentProcessor)(void);
uint8_t IrqNumber;
} HAL_TIMER;
#define HAL_RTC_TIME_FLAG_VALID 0x0001u
@@ -173,24 +172,27 @@ typedef struct HAL_PCI {
} HAL_PCI;
typedef struct HAL_INTERRUPT_CONTROLLER {
void (*RouteIrq)(uint8_t irq);
void (*MaskIrq)(uint8_t irq);
void (*UnmaskIrq)(uint8_t irq);
KSTATUS (*RouteGsi)(uint32_t gsi, uint8_t vector, uint32_t hardwareId,
uint16_t flags, bool masked);
KSTATUS (*MaskGsi)(uint32_t gsi, bool masked);
KSTATUS (*ResolveIsa)(uint8_t isaIrq, uint32_t* gsiOut, uint16_t* flagsOut);
void (*SendEoi)(void);
// The APIC task priority must follow the kernel's per-CPU IRQL.
void (*SetTaskPriority)(uint8_t priority);
uint8_t (*QueryTaskPriority)(void);
// Queries the current CPU's pending and in-service APIC bits for a vector.
bool (*VectorPending)(uint8_t vector);
void (*InitializeCurrentProcessor)(void);
void (*SendProcessorInterrupt)(uint32_t hardwareId, uint8_t vector);
void (*SendProcessorNmi)(uint32_t hardwareId);
void (*BroadcastNmi)(void);
KSTATUS (*ComposeMsi)(uint8_t vector, HAL_MSI_MESSAGE* messageOut);
KSTATUS (*ComposeMsi)(uint32_t hardwareId, uint8_t vector,
HAL_MSI_MESSAGE* messageOut);
} HAL_INTERRUPT_CONTROLLER;
typedef struct HAL_POWER {
// ACPI fixed-feature button events. Control-method devices require an AML owner.
KSTATUS (*QueryFixedButtonIrq)(uint8_t* irqOut);
KSTATUS (*ArmFixedButton)(void);
bool (*ConsumeFixedButton)(void);
// ACPI S5 soft-off. Disables interrupts, writes SLP_EN to PM1a/b_CNT,
// and halts if firmware doesn't respond. Does not return.
// Basic platform shutdown and reset, available without a firmware driver.
// The HAL halts if its final hardware transition returns.
void (*Shutdown)(void);
void (*Reset)(void);
} HAL_POWER;
@@ -231,7 +233,7 @@ typedef struct HAL_INIT_PARAMS {
} HAL_INIT_PARAMS;
// Increment whenever the kernel/HAL table ABI changes.
#define HAL_API_VERSION 4u
#define HAL_API_VERSION 8u
// Returns the HAL table. Processor interrupt-state operations are valid before HalInitialize().
HAL_ENTRY const HAL_API* HalGetApi(void);
+10 -8
View File
@@ -6,15 +6,17 @@
#include <ntlite/status.h>
#include <kernel/hal/hal_api.h>
void HalApicRouteIrq(uint8_t irq);
void HalApicSetGsiBase(uint32_t gsiBase);
KSTATUS HalApicRouteGsi(uint32_t gsi, uint8_t vector, uint32_t hardwareId,
uint16_t flags, bool masked);
KSTATUS HalApicMaskGsi(uint32_t gsi, bool masked);
KSTATUS HalApicResolveIsa(uint8_t irq, uint32_t* gsiOut, uint16_t* flagsOut);
void HalApicAddIoapic(uintptr_t physical, uint32_t gsiBase);
void HalApicSetIsaOverride(uint8_t irq, uint32_t gsi, uint16_t flags);
void HalApicSetSciIrq(uint16_t irq);
bool HalApicCanRouteIrq(uint8_t irq);
void HalApicMaskIrq(uint8_t irq);
void HalApicUnmaskIrq(uint8_t irq);
void HalApicSendEoi(void);
void HalApicInitialize(uintptr_t lapicPhys, uintptr_t ioapicPhys);
void HalApicSetTaskPriority(uint8_t priority);
uint8_t HalApicQueryTaskPriority(void);
bool HalApicVectorPending(uint8_t vector);
void HalApicInitialize(uintptr_t lapicPhys);
uint32_t HalApicGetBootProcessorId(void);
uint8_t HalApicUsingX2Apic(void);
uint8_t HalApicCanAddressId(uint32_t hardwareId);
@@ -23,4 +25,4 @@ void HalApicBroadcastNmi(void);
void HalApicSendProcessorInterrupt(uint32_t hardwareId, uint8_t vector);
void HalApicSendProcessorNmi(uint32_t hardwareId);
KSTATUS HalApicStartProcessor(uint32_t hardwareId, uintptr_t startPhysical);
KSTATUS HalApicComposeMsi(uint8_t vector, HAL_MSI_MESSAGE* messageOut);
KSTATUS HalApicComposeMsi(uint32_t hardwareId, uint8_t vector, HAL_MSI_MESSAGE* messageOut);
+3 -1
View File
@@ -9,9 +9,11 @@ struct NTL_MODULE;
struct DRIVER_OBJECT;
KSTATUS IoPnpInitialize(void);
KSTATUS IoPnpPublishModule(struct NTL_MODULE* module,
KSTATUS IoPnpPrepareModule(struct NTL_MODULE* module,
const NTL_DEVICE_DESC* descriptors, uint32_t count,
struct DRIVER_OBJECT* const* ioDrivers, uint32_t ioCount);
void IoPnpCommitModule(struct NTL_MODULE* module);
void IoPnpAbortModule(struct NTL_MODULE* module);
KSTATUS IoPnpPhysicalDeviceArrived(struct DEVICE_OBJECT* pdo);
void IoPnpPhysicalDevicePublished(struct DEVICE_OBJECT* pdo);
void IoPnpPhysicalDeviceRemoved(struct DEVICE_OBJECT* pdo);
@@ -6,14 +6,12 @@
#include <stdint.h>
#include <ntlite/status.h>
#define KE_BOOT_COMMAND_LINE_MAX 256u
#define KE_BOOT_SYSTEM_VOLUME_MAX 128u
typedef struct KE_BOOT_CONFIG {
uint32_t Debug;
// Opaque system-volume selector interpreted by storage policy, never as a legacy drive slot.
char SystemVolume[KE_BOOT_SYSTEM_VOLUME_MAX];
char CommandLine[KE_BOOT_COMMAND_LINE_MAX];
} KE_BOOT_CONFIG;
// Parses the kernel-owned boot.ini settings from the raw bootloader string.
+8
View File
@@ -0,0 +1,8 @@
// Firmware roots retained from the verified bootloader handoff.
#pragma once
#include <ntlite/boot_info.h>
void KeFirmwareInitialize(const BOOT_INFO* bootInfo);
void KeFirmwareLog(void);
+1 -3
View File
@@ -51,6 +51,4 @@ extern void KeFaultPF(void); // #PF page fault
extern void KeFaultUD(void); // #UD invalid opcode
extern void KeNmiIpiStub(void); // returning NMI SMP-control stub
// CPU-local IPI vector. This uses the common interrupt entry machinery but is
// not an external/device IRQ and is never routed through the external interrupt controller.
#define KE_VECTOR_RESCHEDULE_IPI 0xF0u
#include <kernel/ke_vectors.h>
+7 -12
View File
@@ -1,18 +1,13 @@
// Kernel ke irq declarations shared by implementation files and kernel clients.
// Kernel interrupt-manager declarations.
#pragma once
#include <stdint.h>
#include <ntlite/ddk/interrupt.h>
#include <kernel/hal/hal_api.h>
#include <ntlite/status.h>
void KeIrqInitialize(const HAL_API* hal);
__declspec(dllexport) KSTATUS KeIrqAllocateMsiVector(uint8_t* outIrq);
__declspec(dllexport) void KeIrqRegister(uint8_t irq, void (*handler)(void));
void KeIrqDispatch(uint8_t irq); // called from ke_syscall.asm
// Low-level interrupt entry/exit hooks. These are called by the common IRQ
// assembly stub around KeIrqDispatch. The exit hook is where deferred
// interrupt-time scheduling now happens, so IRQ handlers never switch away
// before KeIrqDispatch has returned and sent EOI.
void KeIrqRegisterLocalTimerHandler(void (*handler)(void));
void KeIrqDispatch(uint8_t vector);
void KiEnterInterrupt(void);
void KiExitInterrupt(void);
// CPU offlining requires the interrupt manager to evacuate every route first.
KSTATUS KiInterruptPrepareCpuOffline(uint32_t cpuIndex);
+1 -3
View File
@@ -2,9 +2,7 @@
#pragma once
// ke_irql.h - software IRQL skeleton.
// The level constants are DDK-visible because current synchronization and IRP
// layouts expose KIRQL. Kernel routines remain declared here.
// IRQL levels are DDK-visible; the kernel synchronizes them with APIC TPR.
#include <stdbool.h>
#include <ntlite/ddk/irql.h>
+3 -2
View File
@@ -5,9 +5,10 @@
struct PROCESS;
struct EVENT;
struct HAL_API;
KSTATUS KePowerInitialize(void);
void KePowerInitializeButton(const struct HAL_API* hal);
void KePowerInitializePolicy(void);
KSTATUS KePowerPrepareFirmware(uint32_t action);
KSTATUS KePowerEnterFirmware(uint32_t action);
void KePowerSetInitProcess(struct PROCESS* init);
KSTATUS KePowerRequest(uint32_t action);
KSTATUS KePowerRequestHardware(uint32_t action);
+12
View File
@@ -0,0 +1,12 @@
// x86-64 interrupt-vector assignments shared by the kernel and HAL.
#pragma once
// CPU exception gates occupy vectors 0x00 through 0x1f.
// Software gates occupy 0x20 through 0x2f; only the syscall gate is active.
#define KE_VECTOR_SYSCALL 0x2Fu
#define KE_VECTOR_DEVICE_FIRST 0x30u
#define KE_VECTOR_DEVICE_LAST 0xCFu
#define KE_VECTOR_CPU_TIMER 0xE0u
#define KE_VECTOR_RESCHEDULE_IPI 0xF0u
#define KE_VECTOR_SPURIOUS 0xFFu
+5 -2
View File
@@ -42,6 +42,9 @@ KSTATUS LdrProtectImageForProcess(struct PROCESS* process, uintptr_t imageBase,
// Called by KernelMain to register the fixed kernel/HAL bootstrap images so LdrGetExport can find them.
struct BOOT_INFO; // forward declaration
KSTATUS LdrRegisterModulesFromBootInfo(const struct BOOT_INFO* bootInfo);
KSTATUS LdrRegisterModule(const char* name, uintptr_t base);
KSTATUS LdrSetModuleExportsAvailable(const char* name, bool available);
typedef struct LDR_KERNEL_MODULE LDR_KERNEL_MODULE;
KSTATUS LdrRegisterModule(const char* name, uintptr_t base, LDR_KERNEL_MODULE** out);
void LdrPublishModule(LDR_KERNEL_MODULE* module);
void LdrDiscardModule(LDR_KERNEL_MODULE* module);
void LdrReleaseKernelImage(uintptr_t imageBase);
const char* LdrFindKernelModuleByAddress(uintptr_t address, uintptr_t* baseOut, size_t* sizeOut);
+1 -1
View File
@@ -2,7 +2,7 @@
#pragma once
// INT 0x40 calling convention, MS x64.
// INT 0x2F calling convention, MS x64.
// RAX selects the syscall number. RCX, RDX, R8, and R9 carry args 0-3.
// Syscalls use at most four register arguments; larger operations use request structures.
// RAX carries the return value.