move keyboard and mouse out of HAL into a standalone ps2.sys driver, implement usb stack with xhci controller discovery, hid keyboard/mouse, and bulk-only mass storage, add pci msi support with capability chain walking and software irq vector allocation (slots 16-23), rewrite user virtual memory as a USER_VA_REGION descriptor arena with per-process ownership tracking and guard page support, replacing the old bump allocator and top-down image region, add MmCreateUserRegion/MmDestroyAllUserRegions so process teardown reclaims all user va in one pass, allocate a pool-backed shadow framebuffer in hal_screen to fix cursor tearing and scroll corruption, reserve ap trampoline page below 1mb in uefi bootloader before boot services exit, rewrite memset/memcpy/memmove/memcmp with __stosq/__movsq intrinsics, promote driver flag literals to macros and add multi-tu STANDALONE_DRIVERS table to build.c, split rtl8139/rtl816x into header+source, rename KbReadScancode to KbReadKey, improve page fault output with MmDebugDescribeAddress and user region dump, fix %p to %016llX throughout.
This commit is contained in:
1 parent
b970d7f59c
commit
b838f8d83d
130 files changed
+8137
-2932
No files matched your search
+31
-22
@@ -16,7 +16,7 @@
|
||||
#define FPU_FCW_DEFAULT 0x037Fu
|
||||
#define FPU_MXCSR_DEFAULT 0x1F80u
|
||||
|
||||
// These offsets are consumed directly by ke_switch.asm. Keep the asserts
|
||||
// These offsets are consumed directly by ke_switch.asm. Keep the asserts
|
||||
// here so THREAD layout edits fail at build time instead of corrupting
|
||||
// context switches at runtime.
|
||||
#define STATIC_ASSERT_OFFSET(type, field, expected) \
|
||||
@@ -41,6 +41,20 @@ static void KiThreadDestroy(OBJECT* obj) {
|
||||
thread->ExitEvent = (EVENT*)0;
|
||||
}
|
||||
|
||||
PROCESS* ownerForUserRegions = thread->Owner;
|
||||
if (ownerForUserRegions) {
|
||||
if (thread->Teb && thread->TebSize) {
|
||||
MmFreeUserMemoryForProcess(ownerForUserRegions, thread->Teb);
|
||||
thread->Teb = (void*)0;
|
||||
thread->TebSize = 0;
|
||||
}
|
||||
|
||||
if (thread->UserStackBase) {
|
||||
MmFreeUserMemoryForProcess(ownerForUserRegions, thread->UserStackBase);
|
||||
thread->UserStackBase = (void *)0;
|
||||
}
|
||||
}
|
||||
|
||||
if (thread->Owner) {
|
||||
PROCESS* owner = thread->Owner;
|
||||
uint32_t remaining = 0;
|
||||
@@ -63,17 +77,6 @@ static void KiThreadDestroy(OBJECT* obj) {
|
||||
MmFreePool(thread->KernelStackBase);
|
||||
thread->KernelStackBase = (void *)0;
|
||||
}
|
||||
|
||||
if (thread->Teb && thread->TebSize) {
|
||||
MmFreeUserMemory(thread->Teb);
|
||||
thread->Teb = (void*)0;
|
||||
thread->TebSize = 0;
|
||||
}
|
||||
|
||||
if (thread->UserStackBase) {
|
||||
MmFreeUserMemory(thread->UserStackBase);
|
||||
thread->UserStackBase = (void *)0;
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, uintptr_t arg,
|
||||
@@ -119,8 +122,14 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
thread->KernelStackTop = (uintptr_t)kstack + KSTACK_SIZE;
|
||||
thread->TssRsp0 = thread->KernelStackTop;
|
||||
|
||||
void* ustack = MmAllocateUserMemory(USTACK_SIZE);
|
||||
if (!ustack) {
|
||||
KSTATUS s;
|
||||
void* ustack = (void*)0;
|
||||
s = MmCreateUserRegion(owner, USTACK_SIZE, PAGE_SIZE,
|
||||
PAGE_PRESENT | PAGE_WRITE | PAGE_USER | PAGE_NX,
|
||||
USER_REGION_ZERO | USER_REGION_GUARD_LOW | USER_REGION_GUARD_HIGH,
|
||||
UserRegionStack,
|
||||
&ustack);
|
||||
if (!KSUCCESS(s) || !ustack) {
|
||||
MmFreePool(kstack);
|
||||
thread->KernelStackBase = (void*)0;
|
||||
ObDereferenceObject(&thread->Header);
|
||||
@@ -128,14 +137,14 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
}
|
||||
thread->UserStackBase = ustack;
|
||||
// Ring-3 starts at the image entry via IRET, not CALL, so there is no
|
||||
// pushed return address. The x64 ABI expects RSP % 16 == 8 at function
|
||||
// pushed return address. The x64 ABI expects RSP % 16 == 8 at function
|
||||
// entry; bias the initial stack as if a call had happened so compiler
|
||||
// generated aligned SSE spills (movaps) are safe.
|
||||
uintptr_t userStackTop = (uintptr_t)ustack + USTACK_SIZE - 8;
|
||||
|
||||
SYS_TEB* teb = (SYS_TEB*)MmAllocateUserMemory(sizeof(SYS_TEB));
|
||||
SYS_TEB* teb = (SYS_TEB*)MmAllocateUserMemoryForProcess(owner, sizeof(SYS_TEB));
|
||||
if (!teb) {
|
||||
MmFreeUserMemory(ustack);
|
||||
MmFreeUserMemoryForProcess(owner, ustack);
|
||||
thread->UserStackBase = (void*)0;
|
||||
MmFreePool(kstack);
|
||||
thread->KernelStackBase = (void*)0;
|
||||
@@ -177,12 +186,12 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui
|
||||
// Allocate the exit event before the thread becomes visible. Manual-reset
|
||||
// so multiple joiners (if any) all wake up when the thread exits.
|
||||
EVENT* exitEvent;
|
||||
KSTATUS s = KeEventCreate(EventManualReset, 0, &exitEvent);
|
||||
s = KeEventCreate(EventManualReset, 0, &exitEvent);
|
||||
if (!KSUCCESS(s)) {
|
||||
if (thread->Teb && thread->TebSize) MmFreeUserMemory(thread->Teb);
|
||||
if (thread->Teb && thread->TebSize) MmFreeUserMemoryForProcess(owner, thread->Teb);
|
||||
thread->Teb = (void*)0;
|
||||
thread->TebSize = 0;
|
||||
MmFreeUserMemory(ustack);
|
||||
MmFreeUserMemoryForProcess(owner, ustack);
|
||||
thread->UserStackBase = (void*)0;
|
||||
MmFreePool(kstack);
|
||||
thread->KernelStackBase = (void*)0;
|
||||
@@ -238,7 +247,7 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg,
|
||||
THREAD_PRIORITY priority,
|
||||
uint64_t affinityMask,
|
||||
THREAD** out) {
|
||||
// Kernel worker threads are owned by the system process. The scheduler's
|
||||
// Kernel worker threads are owned by the system process. The scheduler's
|
||||
// hand-built CPU idle thread stays attached to PID 0 (idle), while driver,
|
||||
// async I/O, and init worker threads are grouped under PID 1 (system).
|
||||
PROCESS* owner = KeGetSystemProcess();
|
||||
@@ -331,7 +340,7 @@ __declspec(dllexport) KSTATUS KeCreateKernelThreadWithAffinity(uintptr_t fn, uin
|
||||
|
||||
void KePrepareBlockThread(THREAD* thread, OBJECT* waitObject, uint8_t alertable) {
|
||||
// Called with the synchronization object's spinlock held, so the caller is
|
||||
// normally at DISPATCH_LEVEL here. This function only marks intent to
|
||||
// normally at DISPATCH_LEVEL here. This function only marks intent to
|
||||
// block; the actual scheduling point is KeCommitBlockThread at PASSIVE.
|
||||
KeAssertIrqlAtOrBelow(DISPATCH_LEVEL);
|
||||
if (!thread) return;
|
||||
|
||||
Reference in new issue
Block a user