add a realtime scheduler class and priority-inheritance mutexes with timeouts and abandonment, add an HDA audio driver and a SYS_AUDIO_* syscall family, flesh out kernel32 with Win32 threads, events, mutexes, critical sections, and condition variables, add SYS_RESUME_THREAD for suspended thread creation, add KeInitializeMemoryTypes to reprogram MTRRs and install a canonical PAT for WB/WC/UC control, rework the display pipeline with a pitched present path and console output flush, bring back disk.vhd with mtools since vvfat fucking sucks, harden AHCI with serialized cache flush, USB mass storage with SCSI sense-data decoding, and xHCI with cleaner DMA teardown, fix the last stray for(;;) in HalStopProcessor to while(true), pile on smoke tests for audio, win32 sync primitives, and thread suspend, implement AHCI timeout, kill readahead since it was desperetaly trying to murder me, fix doom sound x2.

This commit is contained in:
maksw committed 2026-08-11 18:38:36 +02:00
1 parent 8b254f84f4
commit 4add6789ba
177 files changed
+22565 -3070

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
// Kernel DMA declarations shared by the I/O manager and DDK provider.
#pragma once
#include <ntlite/ddk/dma.h>
struct DEVICE_OBJECT;
// Returns the kernel-owned DDK DMA table.
const NTL_DDK_DMA* IoGetDmaDdk(void);
// Detaches the adapter owned by a device before the device object can die.
void IoDmaDetachDevice(struct DEVICE_OBJECT* device);
+10
View File
@@ -12,6 +12,16 @@
struct PROCESS;
// Initializes filesystem namespace change notification before drivers register volumes.
KSTATUS IoInitializeVolumeNamespace(void);
// Returns the generation of the mounted-volume namespace.
uint64_t IoGetVolumeNamespaceGeneration(void);
// Waits until the mounted-volume namespace changes or the timeout expires.
KSTATUS IoWaitForVolumeNamespaceChange(uint64_t observedGeneration,
uint64_t timeoutMilliseconds);
__declspec(dllexport) KSTATUS IoReadFileAsyncKernel(FILE_OBJECT* file,
void* buf,
size_t size,
+183
View File
@@ -0,0 +1,183 @@
// Kernel audio-core declarations shared by the mixer, syscall layer, and selftests.
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <ntlite/ddk/audio.h>
#include <kernel/ob_object.h>
#include <kernel/ke_event.h>
#define KE_AUDIO_MAX_ENDPOINTS 32u
#define KE_AUDIO_MAX_STREAMS_PER_ENDPOINT 64u
#define KE_AUDIO_STREAM_RING_FRAMES 4096u
#define KE_AUDIO_OUTPUT_SAMPLE_RATE 48000u
#define KE_AUDIO_OUTPUT_CHANNELS 2u
#define KE_AUDIO_OUTPUT_FRAMES_PER_PERIOD 512u
#define KE_AUDIO_OUTPUT_PERIOD_COUNT 4u
#define KE_AUDIO_OUTPUT_BYTES_PER_FRAME 4u
#define KE_AUDIO_OUTPUT_PERIOD_BYTES 2048u
#define KE_AUDIO_GAIN_RAMP_FRAMES 480u
#define KE_AUDIO_IDLE_STOP_MILLISECONDS 250u
#define KE_AUDIO_MIXER_REALTIME_PRIORITY 16u
#define KE_AUDIO_WAIT_WRITABLE 0x00000001u
#define KE_AUDIO_WAIT_CONSUMED 0x00000002u
#define KE_AUDIO_WAIT_PRESENTED 0x00000004u
#define KE_AUDIO_WAIT_STOPPED 0x00000008u
#define KE_AUDIO_WAIT_DRAINED 0x00000010u
#define KE_AUDIO_WAIT_FAILED 0x00000020u
#define KE_AUDIO_WAIT_DISCONTINUITY 0x00000040u
#define KE_AUDIO_WAIT_VALID_MASK 0x0000007Fu
typedef enum KE_AUDIO_ENDPOINT_STATE {
KeAudioEndpointStarting = 1,
KeAudioEndpointReady,
KeAudioEndpointStopping,
KeAudioEndpointFailed,
KeAudioEndpointRemoved
} KE_AUDIO_ENDPOINT_STATE;
typedef enum KE_AUDIO_STREAM_STATE {
KeAudioStreamCreated = 1,
KeAudioStreamRunning,
KeAudioStreamPaused,
KeAudioStreamDraining,
KeAudioStreamStopped,
KeAudioStreamFailed,
KeAudioStreamClosed
} KE_AUDIO_STREAM_STATE;
typedef struct KE_AUDIO_STREAM KE_AUDIO_STREAM;
// Reports one endpoint snapshot without exposing provider-owned pointers.
typedef struct KE_AUDIO_ENDPOINT_INFO {
uint64_t EndpointId;
IO_AUDIO_ENDPOINT_KIND Kind;
KE_AUDIO_ENDPOINT_STATE State;
uint32_t Capabilities;
IO_AUDIO_FORMAT HardwareFormat;
uint32_t PeriodCount;
uint32_t FramesPerPeriod;
uint8_t Available;
uint8_t IsDefault;
uint8_t HardwareRunning;
uint8_t MasterMuted;
int32_t MasterHardwareGainMilliDb;
float MasterRequestedVolume;
uint32_t StreamCount;
uint32_t ActiveStreamCount;
uint64_t PeriodsMixed;
uint64_t PeriodsCompleted;
uint64_t FramesPresented;
uint64_t HardwarePositionFrames;
uint64_t InterruptCount;
uint64_t LastPresentationTimestampTicks;
uint64_t SilenceFramesInserted;
uint64_t Underruns;
uint64_t DiscontinuityGeneration;
KSTATUS FailureStatus;
} KE_AUDIO_ENDPOINT_INFO;
// Selects the next condition that should signal one stream's wait event.
typedef struct KE_AUDIO_STREAM_WAIT_CONDITION {
uint32_t Mask;
uint32_t WritableFrames;
uint64_t ConsumedFrames;
uint64_t PresentedFrames;
uint64_t DrainedGeneration;
uint64_t DiscontinuityGeneration;
} KE_AUDIO_STREAM_WAIT_CONDITION;
// Reports one logical stream snapshot.
typedef struct KE_AUDIO_STREAM_INFO {
KE_AUDIO_STREAM_STATE State;
IO_AUDIO_FORMAT Format;
uint32_t CapacityFrames;
uint32_t BufferedFrames;
uint32_t WritableFrames;
uint64_t FramesSubmitted;
uint64_t FramesConsumed;
uint64_t FramesPresented;
uint64_t FramesDiscarded;
uint64_t OutputFramesMixed;
uint64_t SilenceFramesInserted;
uint64_t Underruns;
uint64_t DrainedGeneration;
uint64_t DiscontinuityGeneration;
KSTATUS FailureStatus;
float Volume;
float Pan;
uint8_t Muted;
} KE_AUDIO_STREAM_INFO;
// Initializes endpoint registry and mixer ownership before drivers load.
void KeAudioInitialize(void);
// Returns the provider-facing audio DDK table.
const NTL_DDK_AUDIO* KeAudioGetDdk(void);
// Copies current endpoint snapshots and reports the full available count.
KSTATUS KeAudioQueryEndpoints(KE_AUDIO_ENDPOINT_INFO* endpoints,
uint32_t capacity,
uint32_t* countOut);
// Returns the currently selected endpoint identifier, or zero when none is usable.
uint64_t KeAudioGetDefaultEndpointId(void);
// Creates one fixed-format logical render stream and returns a caller-owned reference.
KSTATUS KeAudioCreateStream(uint64_t endpointId,
const IO_AUDIO_FORMAT* format,
KE_AUDIO_STREAM** outStream);
// Records one process handle that owns the stream.
void KeAudioStreamHandleOpened(KE_AUDIO_STREAM* stream);
// Releases one process-handle owner without blocking the handle-table path.
void KeAudioStreamHandleClosed(KE_AUDIO_STREAM* stream);
// Returns a borrowed passive event valid while the caller retains the stream.
EVENT* KeAudioStreamWaitEvent(KE_AUDIO_STREAM* stream);
// Arms the stream event for one or more progress conditions without a lost-wakeup window.
KSTATUS KeAudioArmStreamWait(KE_AUDIO_STREAM* stream,
const KE_AUDIO_STREAM_WAIT_CONDITION* condition);
// Copies as many complete source frames as fit without blocking.
KSTATUS KeAudioWriteStream(KE_AUDIO_STREAM* stream,
const void* frames,
uint32_t requestedFrames,
uint32_t* writtenFramesOut);
// Starts one created or stopped stream.
KSTATUS KeAudioStartStream(KE_AUDIO_STREAM* stream);
// Pauses future mixing while preserving source frames not yet consumed.
KSTATUS KeAudioPauseStream(KE_AUDIO_STREAM* stream);
// Resumes one paused stream.
KSTATUS KeAudioResumeStream(KE_AUDIO_STREAM* stream);
// Rejects new writes and stops after every submitted frame is presented or discarded.
KSTATUS KeAudioDrainStream(KE_AUDIO_STREAM* stream);
// Stops future mixing and discards source frames not yet committed to endpoint periods.
KSTATUS KeAudioStopStream(KE_AUDIO_STREAM* stream);
// Invalidates queued presentation accounting and returns an empty stream to position zero.
KSTATUS KeAudioResetStream(KE_AUDIO_STREAM* stream);
// Updates per-stream software gain with a ten-millisecond ramp.
KSTATUS KeAudioSetStreamVolume(KE_AUDIO_STREAM* stream,
float volume,
float pan,
bool muted);
// Updates endpoint master software gain and separate logical mute state.
KSTATUS KeAudioSetMasterVolume(uint64_t endpointId, float volume, bool muted);
// Copies one coherent stream snapshot.
KSTATUS KeAudioQueryStream(KE_AUDIO_STREAM* stream, KE_AUDIO_STREAM_INFO* infoOut);
// Runs the final render path selftest behind KE_DEBUG_AUDIO_SELFTEST.
void KiRunAudioFinalPathSelfTest(void);
+3
View File
@@ -7,6 +7,7 @@
// owns CPU-local scheduler, IRQL, GDT, and TSS state.
#include <stdint.h>
#include <stdbool.h>
#include <kernel/ke_irql.h>
#include <kernel/ke_idt.h>
@@ -83,6 +84,8 @@ extern KCPU gCpus[KE_MAX_CPUS];
extern uint32_t gCpuCount;
void KeInitializeBootstrapCpu(void);
void KeInitializeMemoryTypes(void);
bool KeWriteCombiningAvailable(void);
void KeLoadKernelGsBase(KCPU* cpu);
void KeSetUserGsBase(uintptr_t userGsBase);
uintptr_t KeGetUserGsBase(void);
-15
View File
@@ -10,21 +10,6 @@
#include <ntlite/ddi/hal_api.h>
#include <ntlite/ddk/debug.h>
#define KE_DEBUG_CONSOLE 0x00000001u
#define KE_DEBUG_SELFTEST 0x00000002u
#define KE_DEBUG_FILE_LOG 0x00000004u
#define KE_DEBUG_POOL_CANARY 0x00000008u
#define KE_DEBUG_POOL_POISON 0x00000010u
#define KE_DEBUG_POOL_QUARANTINE 0x00000020u
#define KE_DEBUG_POOL_CALLERS 0x00000040u
#define KE_DEBUG_DISPLAY_ASSERTS 0x00000080u
#define KE_DEBUG_DISPLAY_TRACE 0x00000100u
#define KE_DEBUG_INPUT_TRACE 0x00000200u
#define KE_DEBUG_VM_ASSERTS 0x00000400u
#define KE_DEBUG_SYSCALL_ASSERTS 0x00000800u
#define KE_DEBUG_LIST_CHECKS 0x00001000u
void KeInitDebug(const HAL_API* hal, uint32_t flags);
uint32_t KeGetDebugFlags(void);
__declspec(dllexport) void DbgPrint(const char* fmt, ...);
+3
View File
@@ -28,6 +28,9 @@ typedef struct DISPLAY_CLOCK_OBJECT {
} DISPLAY_CLOCK_OBJECT;
void KeDisplayInitialize(const HAL_API* hal);
// Completes every console glyph queued before the call.
KSTATUS KeDisplayFlushConsoleOutput(void);
DISPLAY_API KSTATUS KeDisplayOpenClock(uint64_t periodMilliseconds, DISPLAY_CLOCK_OBJECT** outClock);
DISPLAY_API EVENT* KeDisplayClockWaitEvent(DISPLAY_CLOCK_OBJECT* clock);
DISPLAY_API void KeDisplayTick(void);
+27 -10
View File
@@ -1,20 +1,37 @@
// Kernel ke mutex declarations shared by implementation files and kernel clients.
// Kernel mutex declarations shared by implementation files and kernel clients.
#pragma once
// ke_mutex.h - binary ownership mutex.
#include <kernel/ob_object.h>
#include <kernel/ke_spinlock.h>
#include <kernel/ke_list.h>
#include <ntlite/ddk/thread.h>
#include <ntlite/status.h>
struct THREAD;
typedef struct MUTEX {
OBJECT Header;
SPINLOCK Lock;
struct THREAD* Owner; // NULL if unowned
LIST_ENTRY WaitList;
OBJECT Header;
SPINLOCK Lock;
struct THREAD* Owner;
LIST_ENTRY WaitList;
LIST_ENTRY OwnerLink;
KE_SCHEDULING_CLASS DonationClass;
uint32_t DonationPriority;
uint8_t HasDonation;
uint8_t Abandoned;
} MUTEX;
__declspec(dllexport) KSTATUS KeMutexCreate(MUTEX **out);
__declspec(dllexport) KSTATUS KeAcquireMutex(MUTEX* mutex);
__declspec(dllexport) KSTATUS KeTryAcquireMutex(MUTEX* mutex);
__declspec(dllexport) void KeReleaseMutex(MUTEX* mutex);
// Tests whether a mutex acquisition transferred ownership to the caller.
#define KE_MUTEX_ACQUIRE_SUCCEEDED(status) \
((status) == NTLSTATUS_SUCCESS || (status) == NTLSTATUS_ABANDONED)
__declspec(dllexport) KSTATUS KeMutexCreate(MUTEX** out);
__declspec(dllexport) KSTATUS KeAcquireMutex(MUTEX* mutex, uint64_t timeoutMilliseconds);
__declspec(dllexport) void KeReleaseMutex(MUTEX* mutex);
// Removes one blocked waiter while preserving priority-inheritance state.
int KiMutexAbortWait(MUTEX* mutex, struct THREAD* thread);
// Releases every mutex owned by a terminating thread as abandoned.
void KiMutexRundownThread(struct THREAD* thread);
+3 -1
View File
@@ -30,6 +30,7 @@
#define HANDLE_RIGHT_QUERY 0x00000020u
#define HANDLE_RIGHT_TERMINATE 0x00000040u
#define HANDLE_RIGHT_LOCK 0x00000080u
#define HANDLE_RIGHT_RESUME 0x00000100u
#define HANDLE_RIGHT_ALL 0xFFFFFFFFu
struct SYS_EXCEPTION_STATS;
@@ -62,7 +63,8 @@ typedef struct PROCESS {
uint8_t CurrentDrive;
SPINLOCK CwdLock;
// Thread list.
// Live thread set. Dead THREAD objects may outlive this membership while
// retained handles remain waitable and queryable.
LIST_ENTRY ThreadList; // links THREAD.ProcessLink
uint32_t ThreadCount;
+57 -2
View File
@@ -1,18 +1,20 @@
// Kernel ke sched declarations shared by implementation files and kernel clients.
#pragma once
// ke_sched.h - Multi-Level Feedback Queue scheduler
// Three run queues (Low / Normal / High). LAPIC timer IRQs drive KeSchedulerTick.
// The scheduler combines dynamic normal queues with static real-time queues.
// LAPIC timer IRQs drive KeSchedulerTick.
#include <kernel/ke_thread.h>
struct KCPU;
#define SCHED_TICK_MS 10u
#define SCHED_REALTIME_QUANTUM_TICKS 1u
#define SCHED_HIGH_QUANTUM_TICKS 2u
#define SCHED_NORMAL_QUANTUM_TICKS 4u
#define SCHED_LOW_QUANTUM_TICKS 8u
#define SCHED_DEMOTE_AFTER_BURST_TICKS 16u
#define SCHED_AGING_INTERVAL_TICKS 100u
#define KE_PRIORITY_INHERITANCE_MAX_DEPTH 64u
typedef struct KE_SCHED_STATS {
uint64_t Ticks;
@@ -27,8 +29,61 @@ typedef struct KE_SCHED_STATS {
uint64_t CpuBurstDemotions;
uint64_t SmtSiblingDeferrals;
uint64_t SmtPrimaryPokes;
uint64_t RealtimeDispatches;
uint64_t RealtimePreemptions;
uint64_t PriorityInheritanceBoosts;
uint64_t PriorityInheritanceDrops;
uint64_t PriorityInheritancePropagations;
uint64_t PriorityInheritanceMaxDepth;
} KE_SCHED_STATS;
struct MUTEX;
typedef struct KE_THREAD_SCHEDULER_SNAPSHOT {
THREAD_STATE State;
KE_SCHEDULING_CLASS BaseSchedulingClass;
uint32_t BasePriority;
KE_SCHEDULING_CLASS EffectiveSchedulingClass;
uint32_t EffectivePriority;
uint32_t RunningCpu;
uint32_t LastCpu;
uint32_t QuantumRemaining;
uint32_t QuantumTicks;
uint32_t CpuBurstTicks;
uint32_t LastRunTicks;
uint32_t WaitObjectType;
KSTATUS WaitStatus;
struct MUTEX* WaitingMutex;
uint8_t Queued;
uint8_t AlertableWait;
} KE_THREAD_SCHEDULER_SNAPSHOT;
// Copies scheduler-owned thread state into a stable diagnostic snapshot.
void KiSchedulerSnapshotThread(THREAD* thread, KE_THREAD_SCHEDULER_SNAPSHOT* snapshot);
// Selects waiters and refreshes donations while the mutex lock is held.
struct THREAD* KiSchedulerSelectMutexWaiter(struct MUTEX* mutex);
int KiSchedulerRefreshMutexDonation(struct MUTEX* mutex);
// Updates one thread's normal-class base priority.
KSTATUS KiSchedulerSetNormalPriority(THREAD* thread, THREAD_PRIORITY priority);
// Publishes one mutex dependency atomically with cycle detection.
KSTATUS KiSchedulerPrepareMutexWait(THREAD* thread, struct MUTEX* mutex, THREAD* owner);
void KiSchedulerCancelMutexWait(THREAD* thread, struct MUTEX* mutex);
// Associates mutex ownership with priority-inheritance bookkeeping.
void KiSchedulerAcquireMutexOwnership(THREAD* thread, struct MUTEX* mutex);
void KiSchedulerTransferMutexOwnership(THREAD* oldOwner, THREAD* newOwner,
struct MUTEX* mutex);
void KiSchedulerReleaseMutexOwnership(THREAD* thread, struct MUTEX* mutex);
struct MUTEX* KiSchedulerFirstOwnedMutex(THREAD* thread);
void KiSchedulerNotePriorityPropagation(uint32_t depth);
// Recomputes effective rank and optionally returns a referenced upstream mutex.
int KiSchedulerRefreshEffectivePriority(THREAD* thread, struct MUTEX** waitingMutexOut);
// Called once by KernelMain before any threads are created.
void KeInitializeScheduler(void);
+1 -2
View File
@@ -17,6 +17,5 @@ typedef struct SEMAPHORE {
} SEMAPHORE;
__declspec(dllexport) KSTATUS KeSemaphoreCreate(int32_t initial, int32_t max, SEMAPHORE **out);
__declspec(dllexport) KSTATUS KeWaitSemaphore(SEMAPHORE* semaphore);
__declspec(dllexport) KSTATUS KeTrySemaphore(SEMAPHORE* semaphore);
__declspec(dllexport) KSTATUS KeWaitSemaphore(SEMAPHORE* semaphore, uint64_t timeoutMilliseconds);
__declspec(dllexport) void KeSignalSemaphore(SEMAPHORE* semaphore);
+47 -17
View File
@@ -18,6 +18,7 @@
#define KE_USER_EXCEPTION_MAX_DEPTH 8u
typedef struct THREAD THREAD;
struct MUTEX;
#ifndef NTL_THREAD_PRIORITY_DEFINED
typedef enum THREAD_PRIORITY {
@@ -34,6 +35,7 @@ typedef enum THREAD_STATE {
ThreadRunning = 1,
ThreadWaiting = 2,
ThreadDead = 3,
ThreadSuspended = 4,
} THREAD_STATE;
typedef void (*KE_WAIT_RUNDOWN_ROUTINE)(struct THREAD* thread,
@@ -51,17 +53,20 @@ typedef struct KCONTEXT {
struct THREAD {
OBJECT Header; // must be first
uint32_t ThreadId;
THREAD_STATE State;
THREAD_PRIORITY Priority;
uint32_t ThreadId;
THREAD_STATE State;
KE_SCHEDULING_CLASS BaseSchedulingClass;
uint32_t BasePriority;
KE_SCHEDULING_CLASS EffectiveSchedulingClass;
uint32_t EffectivePriority;
// CPU-burst mirror kept here for the assembly-stable THREAD layout.
// Dynamic quantum state lives later in the structure.
uint32_t QuantaConsumed;
uint32_t QuantaConsumed;
PROCESS* Owner;
LIST_ENTRY ProcessLink; // node in Owner->ThreadList
LIST_ENTRY SchedulerLink; // node in run queue or wait list
LIST_ENTRY SchedulerLink; // node in run queue or object wait list
// Kernel stack - never PAGE_USER, pointed to by TssRsp0.
void* KernelStackBase;
@@ -108,6 +113,12 @@ struct THREAD {
uint32_t CpuBurstTicks;
uint32_t LastRunTicks;
uint32_t RunningCpu;
uint32_t SuspendCount;
// Priority inheritance ownership is scheduler-owned. Mutex wait-list
// membership remains protected by the mutex spinlock.
LIST_ENTRY OwnedMutexList;
struct MUTEX* WaitingMutex;
// Scheduler hardening state. Queued means membership in a scheduler ready
// queue only; wait-object membership is tracked by WaitListHead. Idle
@@ -125,7 +136,9 @@ struct THREAD {
KSTATUS WaitStatus;
LIST_ENTRY* WaitListHead;
uint8_t AlertableWait;
uint64_t SleepUntilTick;
LIST_ENTRY TimeoutLink;
uint8_t TimeoutArmed;
uint64_t TimeoutTick;
KSTATUS TimeoutStatus;
// Optional cleanup hook for waits that use auxiliary wait blocks.
@@ -167,6 +180,11 @@ struct THREAD {
uint32_t UserExceptionNoncontinuableMask;
uintptr_t UserExceptionFrameUserAddress;
KSTATUS UserExceptionExitStatus[KE_USER_EXCEPTION_MAX_DEPTH];
// Synchronous kernel work can temporarily retain caller-owned stack or
// process memory. Process termination must wait until that ownership has
// returned instead of freeing the thread underneath an active driver.
volatile long TerminationDeferralCount;
};
// Creates and queues a user thread. On success, *out receives a referenced
@@ -174,24 +192,31 @@ struct THREAD {
// after copying any needed IDs/state. The live scheduler/thread lifetime is
// separate and remains valid until the thread exits and is reaped.
__declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, uintptr_t arg,
THREAD_PRIORITY priority, THREAD** out);
const KE_THREAD_CREATE_PARAMETERS* parameters, THREAD** out);
// Create a kernel-mode-only thread. fn is called directly in ring 0 with
// Cancels a thread that has never left its initial suspended state. This drops
// the scheduler-owned lifetime reference but leaves the caller's reference
// intact.
KSTATUS KeCancelSuspendedThread(THREAD* thread);
// Creates a kernel-mode-only thread. fn is called directly in ring 0 with
// arg; when fn returns the thread exits automatically. No user stack or TEB
// is allocated. The thread is owned by the system process and runs at the
// given priority. On success, non-NULL out receives a referenced THREAD
// pointer owned by the caller; release it with ObDereferenceObject() after
// copying any needed IDs/state or after joining/waiting on caller-owned
// completion state. The scheduler's live thread reference is separate.
// is allocated. The thread is owned by the system process. On success,
// non-NULL out receives a referenced THREAD pointer owned by the caller;
// release it with ObDereferenceObject() after copying any needed IDs/state or
// after joining caller-owned completion state. The scheduler's live thread
// reference is separate.
__declspec(dllexport) KSTATUS KeCreateKernelThread(uintptr_t fn, uintptr_t arg,
THREAD_PRIORITY priority, THREAD** out);
__declspec(dllexport) KSTATUS KeCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg,
THREAD_PRIORITY priority, uint64_t affinityMask,
const KE_THREAD_CREATE_PARAMETERS* parameters,
THREAD** out);
// Mark a thread dead and deschedule it permanently.
__declspec(dllexport) void KeExitThread(THREAD* thread, int code);
// Publishes completion, releases per-thread user memory, and removes one dead
// thread from its process live-thread set. Retained handles remain waitable.
void KeFinalizeThreadExit(THREAD* thread);
// Block / unblock primitives used by sync objects.
// Correct wait pattern:
@@ -213,12 +238,17 @@ KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable);
KSTATUS KeBlockThread(THREAD* thread, OBJECT* waitObject, uint8_t alertable);
void KeUnblockThreadWithStatus(THREAD* thread, KSTATUS status);
void KeUnblockThreadFromWaitListWithStatus(THREAD* thread, KSTATUS status);
void KeAbortThreadWait(THREAD* thread, KSTATUS status);
int KeAbortThreadWait(THREAD* thread, KSTATUS status);
void KeUnblockThread(THREAD* thread);
KSTATUS KeAlertThread(THREAD* thread);
void KiWakeThreadForKernelApc(THREAD* thread);
void KiWakeThreadForUserApc(THREAD* thread);
// Defers process termination while kernel work owns caller-backed storage.
void KeEnterTerminationDeferral(void);
void KeLeaveTerminationDeferral(void);
int KeThreadTerminationDeferred(const THREAD* thread);
// Assembly stub - implemented in ke_switch.asm.
void KeSwitchContext(THREAD* from, THREAD* to);
__declspec(noreturn) void KeStartInitialThread(THREAD* thread);
+3
View File
@@ -11,3 +11,6 @@ void KeTimeInitialize(const BOOT_INFO* bootInfo, const HAL_API* hal);
KSTATUS KeTimeReloadSettings(void);
__declspec(dllexport) KSTATUS KeQuerySystemTime(SYS_SYSTEM_TIME* outTime);
__declspec(dllexport) uint64_t KeQueryUnixTimeSeconds(void);
// Returns the monotonic platform counter in microseconds.
uint64_t KeQueryMonotonicTicks(void);
@@ -43,19 +43,6 @@ typedef struct MM_FILE_CACHE_STATS {
uint64_t DropFailures;
uint64_t StandbyTransitions;
uint64_t StandbyHits;
uint64_t ReadAheadRequests;
uint64_t ReadAheadPagesRequested;
uint64_t ReadAheadPagesQueued;
uint64_t ReadAheadPagesLoaded;
uint64_t ReadAheadPagesSkipped;
uint64_t ReadAheadFailures;
uint64_t ReadAheadPagesThrottled;
uint64_t MaxReadAheadPagesPerRequest;
uint64_t BatchReads;
uint64_t BatchPagesRequested;
uint64_t BatchPagesLoaded;
uint64_t MaxBatchPagesRequested;
uint64_t MaxBatchPagesLoaded;
uint64_t ResidentPages;
uint64_t ActivePages;
uint64_t StandbyPages;
@@ -92,8 +79,4 @@ void MmFileCacheInvalidateAll(FILE_OBJECT* file);
// it never writes back because v1 stores only clean file data.
KSTATUS MmFileCacheDropOnePageForPressure(void);
// Queues best-effort read-ahead for clean file pages. The queue owns a file
// reference until the worker has consumed the request.
KSTATUS MmFileCacheScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, uint32_t pages);
void MmFileCacheQueryStats(MM_FILE_CACHE_STATS* out);
+6
View File
@@ -124,6 +124,12 @@ __declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateInRange(PHYSICAL_ADDRESS min
PHYSICAL_ADDRESS maxExclusive,
MM_PFN_USAGE usage);
__declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateContiguous(size_t count, MM_PFN_USAGE usage);
PHYSICAL_ADDRESS MmPfnAllocateContiguousInRange(size_t count,
PHYSICAL_ADDRESS minInclusive,
PHYSICAL_ADDRESS maxExclusive,
size_t alignment,
size_t boundary,
MM_PFN_USAGE usage);
__declspec(dllexport) KSTATUS MmPfnFree(PHYSICAL_ADDRESS frame);
__declspec(dllexport) KSTATUS MmPfnRetain(PHYSICAL_ADDRESS frame);
__declspec(dllexport) KSTATUS MmPfnRelease(PHYSICAL_ADDRESS frame);
+5 -4
View File
@@ -12,10 +12,11 @@
#define PAGE_PRESENT (1ULL << 0)
#define PAGE_WRITE (1ULL << 1)
#define PAGE_USER (1ULL << 2)
#ifndef PAGE_WRITETHROUGH
#define PAGE_WRITETHROUGH (1ULL << 3)
#endif
#define PAGE_NOCACHE (1ULL << 4)
// Cache policy is selected through the canonical PAT layout.
#define PAGE_CACHE_WB 0ULL
#define PAGE_CACHE_WC (1ULL << 3)
#define PAGE_CACHE_UC (1ULL << 4)
#define PAGE_CACHE_MASK (PAGE_CACHE_WC | PAGE_CACHE_UC)
#define PAGE_ACCESSED (1ULL << 5)
#define PAGE_DIRTY (1ULL << 6)
#define PAGE_NX (1ULL << 63)
+11
View File
@@ -66,6 +66,15 @@ typedef struct MM_PINNED_USER_PAGE {
} MM_PINNED_USER_PAGE;
typedef struct MM_LOCKED_USER_BUFFER MM_LOCKED_USER_BUFFER;
typedef struct MM_KERNEL_VIEW MM_KERNEL_VIEW;
// Maps existing frames into a stable kernel-only virtual range. The view owns
// virtual address space and PTEs, but it does not own the physical frames.
KSTATUS MmCreateKernelViewFromFrames(const PHYSICAL_ADDRESS* frames,
size_t pageCount,
MM_KERNEL_VIEW** outView);
void* MmKernelViewBase(const MM_KERNEL_VIEW* view);
void MmDestroyKernelView(MM_KERNEL_VIEW* view);
// Pins one user page and returns a kernel direct-map alias for the requested
// address. Callers may copy through KernelAddress + PageOffset while the page is
@@ -80,6 +89,8 @@ __declspec(dllexport) void MmUnpinUserPage(MM_PINNED_USER_PAGE* page);
// unlocked. WriteAccess describes kernel writes to the user buffer.
__declspec(dllexport) KSTATUS MmLockUserBuffer(PROCESS* process, void* userAddress, size_t size, int writeAccess, MM_LOCKED_USER_BUFFER** out);
__declspec(dllexport) void MmUnlockUserBuffer(MM_LOCKED_USER_BUFFER* buffer);
size_t MmLockedUserBufferPageCount(const MM_LOCKED_USER_BUFFER* buffer);
PHYSICAL_ADDRESS MmLockedUserBufferPageFrame(const MM_LOCKED_USER_BUFFER* buffer, size_t index);
// Virtual address descriptors.
// The single shared address space still has per-process VAD ownership so process
+134 -118
View File
@@ -17,138 +17,154 @@
#define SYS_GET_PROCESS_LIST 6
#define SYS_GET_PROCESS_PID 7
#define SYS_CREATE_THREAD 8
#define SYS_GET_THREAD_LIST 9
#define SYS_LOAD_MODULE 10
#define SYS_UNLOAD_MODULE 11
#define SYS_GET_MODULE_INFO 12
#define SYS_GET_MODULE_EXPORT 13
#define SYS_GET_MODULE_LIST 14
#define SYS_GET_CURRENT_TID 15
#define SYS_GET_CURRENT_PID 16
#define SYS_SET_THREAD_PRIORITY 17
#define SYS_YIELD 18
#define SYS_SLEEP 19
#define SYS_WAIT_SINGLE 20
#define SYS_WAIT_MANY 21
#define SYS_SET_USER_APC_DISPATCHER 22
#define SYS_APC_RETURN 23
#define SYS_SET_EXCEPTION_DISPATCHER 24
#define SYS_GET_EXCEPTION_DISPATCHER 25
#define SYS_CONTINUE_EXCEPTION 26
#define SYS_RAISE_EXCEPTION 27
#define SYS_RESUME_THREAD 9
#define SYS_GET_THREAD_LIST 10
#define SYS_LOAD_MODULE 11
#define SYS_UNLOAD_MODULE 12
#define SYS_GET_MODULE_INFO 13
#define SYS_GET_MODULE_EXPORT 14
#define SYS_GET_MODULE_LIST 15
#define SYS_GET_CURRENT_TID 16
#define SYS_GET_CURRENT_PID 17
#define SYS_SET_THREAD_PRIORITY 18
#define SYS_YIELD 19
#define SYS_SLEEP 20
#define SYS_WAIT_SINGLE 21
#define SYS_WAIT_MANY 22
#define SYS_SET_USER_APC_DISPATCHER 23
#define SYS_APC_RETURN 24
#define SYS_SET_EXCEPTION_DISPATCHER 25
#define SYS_GET_EXCEPTION_DISPATCHER 26
#define SYS_CONTINUE_EXCEPTION 27
#define SYS_RAISE_EXCEPTION 28
// Virtual memory, mappings, and handles.
#define SYS_ALLOC_VM 28
#define SYS_FREE_VM 29
#define SYS_PROTECT_VM 30
#define SYS_QUERY_VM 31
#define SYS_CLOSE_HANDLE 32
#define SYS_DUPLICATE_HANDLE 33
#define SYS_CREATE_FILE_MAPPING 34
#define SYS_MAP_FILE 35
#define SYS_ALLOC_VM 29
#define SYS_FREE_VM 30
#define SYS_PROTECT_VM 31
#define SYS_QUERY_VM 32
#define SYS_CLOSE_HANDLE 33
#define SYS_DUPLICATE_HANDLE 34
#define SYS_CREATE_FILE_MAPPING 35
#define SYS_MAP_FILE 36
// Synchronization objects.
#define SYS_CREATE_MUTEX 36
#define SYS_TRY_ACQUIRE_MUTEX 37
#define SYS_RELEASE_MUTEX 38
#define SYS_CREATE_SEM 39
#define SYS_TRY_WAIT_SEM 40
#define SYS_SIGNAL_SEM 41
#define SYS_CREATE_EVENT 42
#define SYS_SIGNAL_EVENT 43
#define SYS_CLEAR_EVENT 44
#define SYS_CREATE_MUTEX 37
#define SYS_TRY_ACQUIRE_MUTEX 38
#define SYS_RELEASE_MUTEX 39
#define SYS_CREATE_SEM 40
#define SYS_TRY_WAIT_SEM 41
#define SYS_SIGNAL_SEM 42
#define SYS_CREATE_EVENT 43
#define SYS_SIGNAL_EVENT 44
#define SYS_CLEAR_EVENT 45
// Queues and named queues.
#define SYS_CREATE_QUEUE 45
#define SYS_SEND_QUEUE 46
#define SYS_RECV_QUEUE 47
#define SYS_PUBLISH_QUEUE 48
#define SYS_OPEN_NAMED_QUEUE 49
#define SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS 50
#define SYS_CREATE_QUEUE 46
#define SYS_SEND_QUEUE 47
#define SYS_RECV_QUEUE 48
#define SYS_PUBLISH_QUEUE 49
#define SYS_OPEN_NAMED_QUEUE 50
#define SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS 51
// Files, directories, and current directory.
#define SYS_OPEN_FILE 51
#define SYS_READ_FILE 52
#define SYS_WRITE_FILE 53
#define SYS_READ_FILE_ASYNC 54
#define SYS_WRITE_FILE_ASYNC 55
#define SYS_CANCEL_IO 56
#define SYS_SEEK_FILE 57
#define SYS_GET_FILE_POS 58
#define SYS_GET_FILE_SIZE 59
#define SYS_GET_FILE_STAT 60
#define SYS_STAT_FILE 61
#define SYS_TRUNCATE_FILE 62
#define SYS_FLUSH_FILE 63
#define SYS_DELETE_FILE 64
#define SYS_RENAME_FILE 65
#define SYS_LOCK_FILE 66
#define SYS_UNLOCK_FILE 67
#define SYS_OPEN_DIR 68
#define SYS_READ_DIR 69
#define SYS_CREATE_DIR 70
#define SYS_REMOVE_DIR 71
#define SYS_SET_CWD 72
#define SYS_REAL_PATH 73
#define SYS_OPEN_FILE 52
#define SYS_READ_FILE 53
#define SYS_WRITE_FILE 54
#define SYS_READ_FILE_ASYNC 55
#define SYS_WRITE_FILE_ASYNC 56
#define SYS_CANCEL_IO 57
#define SYS_SEEK_FILE 58
#define SYS_GET_FILE_POS 59
#define SYS_GET_FILE_SIZE 60
#define SYS_GET_FILE_STAT 61
#define SYS_STAT_FILE 62
#define SYS_TRUNCATE_FILE 63
#define SYS_FLUSH_FILE 64
#define SYS_DELETE_FILE 65
#define SYS_RENAME_FILE 66
#define SYS_LOCK_FILE 67
#define SYS_UNLOCK_FILE 68
#define SYS_OPEN_DIR 69
#define SYS_READ_DIR 70
#define SYS_CREATE_DIR 71
#define SYS_REMOVE_DIR 72
#define SYS_SET_CWD 73
#define SYS_REAL_PATH 74
// Console, display, and surfaces.
#define SYS_WRITE_CONSOLE 74
#define SYS_GET_CONSOLE_INFO 75
#define SYS_SET_CONSOLE_CURSOR 76
#define SYS_FILL_CONSOLE_CHARACTER 77
#define SYS_FILL_CONSOLE_ATTRIBUTE 78
#define SYS_PUT_SCREEN_CHAR 79
#define SYS_CLEAR_SCREEN 80
#define SYS_GET_SCREEN_SIZE 81
#define SYS_QUERY_DISPLAY_INFO 82
#define SYS_OPEN_DISPLAY_CLOCK 83
#define SYS_CREATE_SURFACE 84
#define SYS_MAP_SURFACE 85
#define SYS_QUERY_SURFACE 86
#define SYS_PRESENT_SURFACE 87
#define SYS_WRITE_CONSOLE 75
#define SYS_GET_CONSOLE_INFO 76
#define SYS_SET_CONSOLE_CURSOR 77
#define SYS_FILL_CONSOLE_CHARACTER 78
#define SYS_FILL_CONSOLE_ATTRIBUTE 79
#define SYS_PUT_SCREEN_CHAR 80
#define SYS_CLEAR_SCREEN 81
#define SYS_GET_SCREEN_SIZE 82
#define SYS_QUERY_DISPLAY_INFO 83
#define SYS_OPEN_DISPLAY_CLOCK 84
#define SYS_CREATE_SURFACE 85
#define SYS_MAP_SURFACE 86
#define SYS_QUERY_SURFACE 87
#define SYS_PRESENT_SURFACE 88
// Native render audio.
#define SYS_AUDIO_ENUMERATE_ENDPOINTS 89
#define SYS_AUDIO_OPEN_STREAM 90
#define SYS_AUDIO_WRITE 91
#define SYS_AUDIO_ARM_WAIT 92
#define SYS_AUDIO_QUERY_STREAM 93
#define SYS_AUDIO_START 94
#define SYS_AUDIO_PAUSE 95
#define SYS_AUDIO_RESUME 96
#define SYS_AUDIO_DRAIN 97
#define SYS_AUDIO_STOP 98
#define SYS_AUDIO_RESET 99
#define SYS_AUDIO_SET_VOLUME 100
#define SYS_AUDIO_SET_MASTER_VOLUME 101
// Input.
#define SYS_POLL_KEYBOARD 88
#define SYS_IS_KEY_DOWN 89
#define SYS_READ_KEYBOARD_CHAR 90
#define SYS_READ_KEY 91
#define SYS_GET_KEY_MODIFIERS 92
#define SYS_QUERY_GLOBAL_INPUT_STATE 93
#define SYS_OPEN_INPUT_QUEUE 94
#define SYS_READ_INPUT_EVENT 95
#define SYS_PEEK_INPUT_EVENT 96
#define SYS_PEEK_MOUSE 97
#define SYS_READ_MOUSE 98
#define SYS_GET_MOUSE_POS 99
#define SYS_POLL_KEYBOARD 102
#define SYS_IS_KEY_DOWN 103
#define SYS_READ_KEYBOARD_CHAR 104
#define SYS_READ_KEY 105
#define SYS_GET_KEY_MODIFIERS 106
#define SYS_QUERY_GLOBAL_INPUT_STATE 107
#define SYS_OPEN_INPUT_QUEUE 108
#define SYS_READ_INPUT_EVENT 109
#define SYS_PEEK_INPUT_EVENT 110
#define SYS_PEEK_MOUSE 111
#define SYS_READ_MOUSE 112
#define SYS_GET_MOUSE_POS 113
// Time, debug, and system information.
#define SYS_CREATE_TIMER 100
#define SYS_SET_TIMER 101
#define SYS_CANCEL_TIMER 102
#define SYS_GET_TICK 103
#define SYS_GET_TICK_FREQUENCY 104
#define SYS_GET_SYSTEM_TIME 105
#define SYS_PRINT_DEBUG 106
#define SYS_QUERY_TRAP_FRAME 107
#define SYS_GET_MEMORY_STATUS 108
#define SYS_QUERY_KERNEL_STATS 109
#define SYS_CREATE_TIMER 114
#define SYS_SET_TIMER 115
#define SYS_CANCEL_TIMER 116
#define SYS_GET_TICK 117
#define SYS_GET_TICK_FREQUENCY 118
#define SYS_GET_SYSTEM_TIME 119
#define SYS_PRINT_DEBUG 120
#define SYS_QUERY_TRAP_FRAME 121
#define SYS_GET_MEMORY_STATUS 122
#define SYS_QUERY_KERNEL_STATS 123
// Native sockets and polling.
#define SYS_CREATE_SOCKET 110
#define SYS_SOCKET_IO_ASYNC 111
#define SYS_BIND_SOCKET 112
#define SYS_LISTEN_SOCKET 113
#define SYS_ACCEPT_SOCKET 114
#define SYS_CONNECT_SOCKET 115
#define SYS_SEND_SOCKET 116
#define SYS_RECV_SOCKET 117
#define SYS_SHUTDOWN_SOCKET 118
#define SYS_SEND_TO_SOCKET 119
#define SYS_RECV_FROM_SOCKET 120
#define SYS_RESOLVE_HOST 121
#define SYS_SET_SOCKET_OPTION 122
#define SYS_GET_SOCKET_OPTION 123
#define SYS_POLL 124
#define SYS_UNPUBLISH_QUEUE 125
#define SYS_CREATE_SOCKET 124
#define SYS_SOCKET_IO_ASYNC 125
#define SYS_BIND_SOCKET 126
#define SYS_LISTEN_SOCKET 127
#define SYS_ACCEPT_SOCKET 128
#define SYS_CONNECT_SOCKET 129
#define SYS_SEND_SOCKET 130
#define SYS_RECV_SOCKET 131
#define SYS_SHUTDOWN_SOCKET 132
#define SYS_SEND_TO_SOCKET 133
#define SYS_RECV_FROM_SOCKET 134
#define SYS_RESOLVE_HOST 135
#define SYS_SET_SOCKET_OPTION 136
#define SYS_GET_SOCKET_OPTION 137
#define SYS_POLL 138
#define SYS_UNPUBLISH_QUEUE 139
#define SYS_MAX 126
#define SYS_MAX 140