Files
nt-lite/code/kernel/kmain.c
T
maksw 73abd6f90d isolate POSIX builds from the host UCRT, wire lwext4 and ntfs-3g as ext4.sys and ntfs.sys, split the FAT driver into directory/file/async/driver/mount units, add posixsrv and dwm plus input/console/desktop syscall clients and a pile of new smoke targets, rename serial.sys to cereal.sys, name HDA/USB/lwIP/AHCI workers, harden ATA probing/reset/removal around actual hardware deadlines, absent-channel detection, diagnostics and explicit worker lifetime, redo ACPI S5 shutdown around GAS/MMIO and HW-reduced firmware, scan SSDTs for _S5 and deal with Intel SMI sleep trapping, make serial and SMP timeouts use real monotonic deadlines, add thread names and fix terminal thread teardown, scheduler and APC prepare/commit races, make advisory file locks queryable and preserve split ranges and add mutable file append state, add shared-memory pipes with kernel-assisted wait/wake, introduce capability-scoped input and display managers, split surface map rights into read/write, add explicit unmap and replace present with commit/generation/damage tracking while keeping physical presentation under the display manager, decouple native exception classes from Win32 exception numbers and translate them in kernel32, add opaque process startup data, bump the resource protocol to v3 with namespace directories, symlinks and enumeration and service control to v2 with generic READY handle exports, add the new POSIX errno/status surface and rebuild fds around posixsrv-owned shared open descriptions, descriptor-local flags, exact inheritance snapshots, dup/fcntl/record locks and shared-ring pipes, add waitpid, POSIX credentials/groups/sessions/passwd/group lookups and move sockets onto stable open descriptions, port the shells and apps to the new console/input services and surface commit API, teach init to load services.ini and start/supervise RSSRV, DWM and generic services under restricted capabilities while publishing their endpoints through RSSRV, split RSSRV into namespace, volume, display, session, input, console and resource components and make /SystemRoot a real symlink to the independently published system volume, shift the syscall table again, expand lock/resource/surface/POSIX/service/thread smoke coverage, make docs scream ASK QUESTIONS and DISCUSS at LLMs, replace MIT No Attribution with WTFPL+.
2026-09-16 10:33:20 +02:00

854 lines
32 KiB
C

// Kernel entry point. This file connects boot information to core subsystem initialization and scheduler start.
#include <stdint.h>
#include <string.h>
#include <intrin.h>
#pragma intrinsic(_disable)
#include <ntlite/boot_info.h>
#include <kernel/ke_hal.h>
#include <kernel/mm_phys.h>
#include <kernel/mm_pfn.h>
#include <kernel/mm_virt.h>
#include <kernel/mm_swap.h>
#include <kernel/ob_object.h>
#include <kernel/ke_process.h>
#include <kernel/ke_thread.h>
#include <kernel/ke_sched.h>
#include <kernel/ke_cpu.h>
#include <kernel/ke_idt.h>
#include <kernel/ke_irq.h>
#include <kernel/ke_dpc.h>
#include <kernel/ke_syscall.h>
#include <ntlite/ddi/net_device.h>
#include <kernel/ke_debug.h>
#include <kernel/ldr_image.h>
#include <kernel/hal/hal_api.h>
#include <kernel/io_file.h>
#include <kernel/io_volume.h>
#include <kernel/io_partition.h>
#include <kernel/io_ddk.h>
#include <kernel/ke_selftest.h>
#include <kernel/ke_smp.h>
#include <kernel/ke_input.h>
#include <kernel/ke_time.h>
#include <kernel/ke_display.h>
#include <kernel/ke_audio.h>
#include <kernel/ke_settings.h>
#include <kernel/ke_work.h>
#include <kernel/ke_system_root.h>
#include <kernel/se_security.h>
#include <kernel/ke_boot_config.h>
typedef struct {
BOOT_INFO* BootInfo;
const HAL_API* Hal;
KE_BOOT_CONFIG BootConfig;
} SYSTEM_INIT_ARGS;
#define KI_SWAP_MIN_MB 4ull
#define KI_SWAP_MAX_MB 8192ull
// Parses a required unsigned decimal integer from settings.ini.
// Configuration errors are treated as boot-time corruption instead of guessed defaults.
static uint64_t KiParseRequiredUInt64Setting(const char* section, const char* key) {
char value[64];
KSTATUS s = KeGetSettingString(section, key, value, sizeof(value));
if (!KSUCCESS(s)) {
KePanic(KE_PANIC_CODE_INIT,
"settings: missing required [%s] %s entry, status=0x%x\n",
section,
key,
s);
}
uint64_t result = 0;
const char* p = value;
if (!*p) {
KePanic(KE_PANIC_CODE_INIT,
"settings: empty numeric value for [%s] %s\n",
section,
key);
}
while (*p) {
if (*p < '0' || *p > '9') {
KePanic(KE_PANIC_CODE_INIT,
"settings: invalid numeric value for [%s] %s: %s\n",
section,
key,
value);
}
uint64_t digit = (uint64_t)(*p - '0');
if (result > (UINT64_MAX - digit) / 10ull) {
KePanic(KE_PANIC_CODE_INIT,
"settings: numeric value for [%s] %s is too large: %s\n",
section,
key,
value);
}
result = result * 10ull + digit;
++p;
}
return result;
}
// Initializes swap according to settings.ini.
// A size of zero is the explicit opt-out. Any missing or invalid size is a broken configuration.
static void KiInitializeSwapFromSettings(void) {
uint64_t swapMb = KiParseRequiredUInt64Setting("vm", "swap_size_mb");
if (swapMb == 0) {
DbgPrint("swap: disabled by settings\n");
return;
}
if (swapMb < KI_SWAP_MIN_MB || swapMb > KI_SWAP_MAX_MB) {
KePanic(KE_PANIC_CODE_INIT,
"settings: [vm] swap_size_mb=%llu is outside the allowed range %llu..%llu MB\n",
(unsigned long long)swapMb,
(unsigned long long)KI_SWAP_MIN_MB,
(unsigned long long)KI_SWAP_MAX_MB);
}
uint64_t swapBytes = swapMb * 1024ull * 1024ull;
KSTATUS s = MmSwapInitialize("pagefile.sys", swapBytes);
if (!KSUCCESS(s)) {
KePanic(KE_PANIC_CODE_INIT,
"swap: failed to initialize %llu MB system-root pagefile, status=0x%x\n",
(unsigned long long)swapMb,
s);
}
}
typedef KSTATUS (*DRIVER_ENTRY_FN)(const NTL_DDK* ddk, NTL_DRIVER_INIT* init);
// HAL pointer cached at boot for subsystems that still need platform services.
static const HAL_API* gKmainHal;
// Implements the page In Bootloader Region operation.
static int KiPageInBootloaderRegion(const BOOT_INFO* bootInfo, PHYSICAL_ADDRESS page) {
for (uint32_t i = 0; i < bootInfo->MemoryMap.RegionCount; i++) {
const MEMORY_REGION* r = &bootInfo->MemoryMap.Regions[i];
if (r->Type != MemoryBootloader) continue;
uintptr_t start = r->Base & PAGE_MASK;
uintptr_t end = (r->Base + r->Length + PAGE_SIZE - 1) & PAGE_MASK;
if ((uintptr_t)page >= start && (uintptr_t)page < end) {
return 1;
}
}
return 0;
}
// Reclaims one exact page-backed blob after its boot consumer has copied or materialized it.
static void KiReclaimBootBlob(const BOOT_INFO* bootInfo, uintptr_t physicalBase, uint32_t pageCount) {
for (uint32_t index = 0; index < pageCount; ++index) {
PHYSICAL_ADDRESS page = (PHYSICAL_ADDRESS)(physicalBase + (uintptr_t)index * PAGE_SIZE);
if (KiPageInBootloaderRegion(bootInfo, page))
MmPfnFree(page);
}
}
// Reclaims raw boot-driver/configuration pages while leaving mapped kernel/HAL/page-table memory owned by bootstrap state.
static void KiReclaimBootloaderMemory(const BOOT_INFO* bootInfo) {
const BOOT_FILE_LIST* list = &bootInfo->BootDrivers;
const BOOT_FILE* files = list->FilesPhysical
? (const BOOT_FILE*)(bootInfo->PhysicalMapBase + list->FilesPhysical)
: NULL;
for (uint32_t index = 0; files && index < list->Count; ++index) {
if (files[index].PhysicalBase && files[index].PageCount)
KiReclaimBootBlob(bootInfo, files[index].PhysicalBase, files[index].PageCount);
}
if (list->FilesPhysical && list->PageCount)
KiReclaimBootBlob(bootInfo, list->FilesPhysical, list->PageCount);
if (bootInfo->BootIni.PhysicalBase && bootInfo->BootIni.PageCount)
KiReclaimBootBlob(bootInfo, bootInfo->BootIni.PhysicalBase, bootInfo->BootIni.PageCount);
}
// Returns whether one drivers.ini line character is horizontal whitespace.
static int KiDriverConfigSpace(char c) {
return c == ' ' || c == '\t' || c == '\r';
}
// Trims horizontal whitespace from one immutable drivers.ini line span.
static void KiDriverConfigTrim(const char** begin, const char** end) {
while (*begin < *end && KiDriverConfigSpace(**begin))
++*begin;
while (*end > *begin && KiDriverConfigSpace((*end)[-1]))
--*end;
}
// Returns whether one immutable drivers.ini span exactly matches an ASCII string.
static int KiDriverConfigSpanEquals(const char* begin, const char* end, const char* text) {
while (begin < end && *text) {
if (*begin++ != *text++)
return 0;
}
return begin == end && *text == '\0';
}
// Loads one runtime driver filename from the system-root drivers directory.
static KSTATUS KiLoadRuntimeDriverByName(const char* name, const NTL_DDK* ddk) {
char relative[512];
size_t length = strlen(name);
if (length + 9u > sizeof(relative))
return NTLSTATUS_BUFFER_TOO_SMALL;
memcpy(relative, "drivers/", 8);
memcpy(relative + 8, name, length + 1);
FILE_OBJECT* file = NULL;
KSTATUS status = KeOpenSystemRootFile(relative, &file);
if (!KSUCCESS(status))
return status;
uint64_t driverSize = IoGetFileSize(file);
if (driverSize == 0 || driverSize > SIZE_MAX) {
IoCloseFile(file);
return NTLSTATUS_INVALID_PARAMETER;
}
void* driverMemory = MmAllocatePool((size_t)driverSize);
if (!driverMemory) {
IoCloseFile(file);
return NTLSTATUS_NO_MEMORY;
}
size_t got = 0;
status = IoReadFile(file, driverMemory, (size_t)driverSize, &got);
IoCloseFile(file);
if (!KSUCCESS(status) || got != (size_t)driverSize) {
MmFreePool(driverMemory);
return KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
}
uintptr_t mappedBase = 0;
status = LdrLoadKernelImage(driverMemory, (size_t)driverSize, &mappedBase);
MmFreePool(driverMemory);
if (!KSUCCESS(status))
return status;
status = LdrResolveImports(mappedBase);
if (!KSUCCESS(status))
return status;
status = LdrRegisterModule(name, mappedBase);
if (!KSUCCESS(status))
return status;
DRIVER_ENTRY_FN entry = (DRIVER_ENTRY_FN)LdrGetEntryPoint(mappedBase);
if (!entry)
return NTLSTATUS_FAILURE;
NTL_DRIVER_INIT init = {0};
return entry(ddk, &init);
}
// Scans only the [runtime] section of drivers.ini and loads each filename immediately.
static KSTATUS KiLoadRuntimeDriversFromConfig(const char* text, size_t length, const NTL_DDK* ddk) {
int inRuntime = 0;
size_t offset = 0;
while (offset < length) {
size_t lineStart = offset;
while (offset < length && text[offset] != '\n')
++offset;
size_t lineEnd = offset;
if (offset < length)
++offset;
const char* begin = text + lineStart;
const char* end = text + lineEnd;
KiDriverConfigTrim(&begin, &end);
if (begin == end || *begin == ';' || *begin == '#')
continue;
if (*begin == '[') {
if (end[-1] != ']')
return NTLSTATUS_INVALID_PARAMETER;
const char* sectionBegin = begin + 1;
const char* sectionEnd = end - 1;
KiDriverConfigTrim(&sectionBegin, &sectionEnd);
inRuntime = KiDriverConfigSpanEquals(sectionBegin, sectionEnd, "runtime");
continue;
}
if (!inRuntime)
continue;
size_t nameLength = (size_t)(end - begin);
if (nameLength == 0 || nameLength >= BOOT_FILE_NAME_MAX)
return NTLSTATUS_INVALID_PARAMETER;
for (const char* p = begin; p < end; ++p) {
if (*p == '=' || *p == '/' || *p == '\\')
return NTLSTATUS_INVALID_PARAMETER;
}
char name[BOOT_FILE_NAME_MAX];
memcpy(name, begin, nameLength);
name[nameLength] = '\0';
DbgPrint("Found runtime driver: %s\n", name);
KSTATUS status = KiLoadRuntimeDriverByName(name, ddk);
if (!KSUCCESS(status))
DbgPrint("KiInitializeDrivers: runtime driver %s failed, status=0x%x\n", name, status);
}
return NTLSTATUS_SUCCESS;
}
// Initializes drivers.
static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) {
(void)hal;
const NTL_DDK* ddk = IoGetDdk();
DbgPrint("KiInitializeDrivers: Initializing drivers...\n");
// Boot drivers are page-backed raw files supplied by the bootloader.
const BOOT_FILE* bootFiles = bootInfo->BootDrivers.FilesPhysical
? (const BOOT_FILE*)(bootInfo->PhysicalMapBase + bootInfo->BootDrivers.FilesPhysical)
: NULL;
for (uint32_t i = 0; bootFiles && i < bootInfo->BootDrivers.Count; ++i) {
const BOOT_FILE* file = &bootFiles[i];
if (!file->PhysicalBase || !file->Length) {
DbgPrint("KiInitializeDrivers: invalid boot driver descriptor at index %u\n", i);
continue;
}
DbgPrint("KiInitializeDrivers: Loading boot driver %s\n", file->Name);
void* rawPeBuffer = (void*)(bootInfo->PhysicalMapBase + file->PhysicalBase);
uintptr_t mappedBase = 0;
KSTATUS st = LdrLoadKernelImage(rawPeBuffer, file->Length, &mappedBase);
if (!KSUCCESS(st)) {
DbgPrint("ERROR: Failed to map driver %s (0x%X)\n", file->Name, st);
continue;
}
if (!KSUCCESS(LdrResolveImports(mappedBase))) {
DbgPrint("ERROR: Failed to resolve imports for %s\n", file->Name);
continue;
}
KSTATUS registerStatus = LdrRegisterModule(file->Name, mappedBase);
if (!KSUCCESS(registerStatus)) {
DbgPrint("ERROR: Failed to register driver %s (0x%X)\n", file->Name, registerStatus);
continue;
}
DRIVER_ENTRY_FN entry = (DRIVER_ENTRY_FN)LdrGetEntryPoint(mappedBase);
if (entry) {
NTL_DRIVER_INIT init = {0};
KSTATUS ds = entry(ddk, &init);
if (!KSUCCESS(ds))
DbgPrint("WARNING: Driver %s returned failure status 0x%X\n", file->Name, ds);
}
}
// runtime drivers.
KSTATUS s;
FILE_OBJECT* f;
s = KeInitializeSystemRootVolume();
if (s != NTLSTATUS_SUCCESS) {
KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to find system root volume (status %d)\n", s);
}
s = KeOpenSystemRootFile("drivers/drivers.ini", &f);
if (s != NTLSTATUS_SUCCESS) {
KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to open drivers.ini on system root (status %d)\n", s);
}
uint64_t fileSize = IoGetFileSize(f);
if (fileSize == 0 || fileSize >= SIZE_MAX) {
IoCloseFile(f);
KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: drivers.ini has an invalid size.\n");
}
size_t size = (size_t)fileSize;
char* mem = (char*)MmAllocatePool(size + 1u);
if (!mem) {
IoCloseFile(f);
KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to allocate drivers.ini buffer.\n");
}
size_t got = 0;
KSTATUS readStatus = IoReadFile(f, mem, size, &got);
IoCloseFile(f);
if (!KSUCCESS(readStatus) || got != size) {
MmFreePool(mem);
KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to read drivers.ini.\n");
}
mem[got] = '\0';
KSTATUS runtimeStatus = KiLoadRuntimeDriversFromConfig(mem, got, ddk);
MmFreePool(mem);
if (!KSUCCESS(runtimeStatus)) {
KePanic(KE_PANIC_CODE_INIT,
"KiInitializeDrivers: drivers.ini [runtime] is malformed, status=0x%x\n",
runtimeStatus);
}
}
// Phase Helper: Load and launch a process from the filesystem.
// Returns the new PROCESS* with one reference owned by the caller.
// Returns NULL on failure.
static PROCESS* KiLaunchUserProcess(const char* filePath, const char* args) {
KSTATUS s;
FILE_OBJECT* f;
// Kernel-launched user images are rooted at the selected system volume.
s = KeOpenSystemRootFile(filePath, &f);
if (s != NTLSTATUS_SUCCESS) {
DbgPrint("Failed to load system file: \"%s\" (status %d)!\n", filePath, s);
return 0;
}
uint64_t size = IoGetFileSize(f);
(void)size;
// Create the process object.
PROCESS* proc;
THREAD* thread;
s = KeCreateProcess(filePath, SeGetRootSecurityContext(), &proc);
if (!KSUCCESS(s)) {
DbgPrint("Failed to create process. System halted.\n");
IoCloseFile(f);
return 0;
}
DbgPrint("Created process (PID %u) with command line: %s\n", proc->ProcessId, (args && args[0]) ? args : filePath);
s = KeSetupUserProcessEnvironment(proc,
SysSvFromCstr(filePath),
SysSvFromCstr(args));
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: Failed to build user process environment. Status: %d\n", s);
IoCloseFile(f);
ObDereferenceObject(&proc->Header);
return 0;
}
// The bootstrap service manager receives only the capabilities required to construct
// the initial user-mode resource plane. Its PID is deliberately not part of this ABI.
IO_VOLUME* systemVolume = (IO_VOLUME*)0;
SYS_HANDLE systemVolumeHandle = SYS_HANDLE_INVALID;
SYS_HANDLE namespaceVolumeHandle = SYS_HANDLE_INVALID;
SYS_HANDLE volumeManagerHandle = SYS_HANDLE_INVALID;
SYS_HANDLE inputManagerHandle = SYS_HANDLE_INVALID;
SYS_HANDLE displayManagerHandle = SYS_HANDLE_INVALID;
s = KeReferenceSystemRootVolume(&systemVolume);
if (KSUCCESS(s)) {
s = KeCreateHandle(proc, &systemVolume->Header,
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN,
&systemVolumeHandle);
if (KSUCCESS(s)) {
s = KeCreateHandle(proc, &systemVolume->Header,
SYS_RIGHT_DUPLICATE | SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY |
SYS_VOLUME_RIGHT_OPEN | SYS_VOLUME_RIGHT_MODIFY,
&namespaceVolumeHandle);
}
IoReleaseVolume(systemVolume);
}
if (KSUCCESS(s)) {
IO_VOLUME_MANAGER* volumeManager = (IO_VOLUME_MANAGER*)0;
s = IoReferenceVolumeManager(&volumeManager);
if (KSUCCESS(s)) {
s = KeCreateHandle(proc, &volumeManager->Header,
SYS_RIGHT_DUPLICATE | SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY |
SYS_VOLUME_MANAGER_RIGHT_ENUMERATE | SYS_VOLUME_MANAGER_RIGHT_OPEN |
SYS_VOLUME_MANAGER_RIGHT_WAIT,
&volumeManagerHandle);
ObDereferenceObject(&volumeManager->Header);
}
}
if (KSUCCESS(s)) {
KE_INPUT_MANAGER* inputManager = (KE_INPUT_MANAGER*)0;
s = KeInputReferenceManager(&inputManager);
if (KSUCCESS(s)) {
s = KeCreateHandle(proc, &inputManager->Header,
SYS_RIGHT_DUPLICATE | SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY |
SYS_INPUT_MANAGER_RIGHT_READ | SYS_INPUT_MANAGER_RIGHT_CONFIGURE,
&inputManagerHandle);
ObDereferenceObject(&inputManager->Header);
}
}
if (KSUCCESS(s)) {
KE_DISPLAY_MANAGER* displayManager = (KE_DISPLAY_MANAGER*)0;
s = KeDisplayReferenceManager(&displayManager);
if (KSUCCESS(s)) {
// Init must be able to attenuate this manager again when RSSRV publishes
// narrower display capabilities such as /Device/Display0.
s = KeCreateHandle(proc, &displayManager->Header,
SYS_RIGHT_DUPLICATE | SYS_RIGHT_DERIVE | SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY |
SYS_DISPLAY_MANAGER_RIGHT_ENUMERATE | SYS_DISPLAY_MANAGER_RIGHT_MODESET |
SYS_DISPLAY_MANAGER_RIGHT_PRESENT | SYS_DISPLAY_MANAGER_RIGHT_CURSOR |
SYS_DISPLAY_MANAGER_RIGHT_CONSOLE,
&displayManagerHandle);
ObDereferenceObject(&displayManager->Header);
}
}
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: Failed to create bootstrap startup capabilities. Status: %d\n", s);
IoCloseFile(f);
ObDereferenceObject(&proc->Header);
return 0;
}
SYS_STARTUP_CAPABILITY startupCapabilities[5] = {
{ SYS_STARTUP_CAP_SYSTEM_VOLUME, systemVolumeHandle },
{ SYS_STARTUP_CAP_SYSTEM_VOLUME_NAMESPACE, namespaceVolumeHandle },
{ SYS_STARTUP_CAP_VOLUME_MANAGER, volumeManagerHandle },
{ SYS_STARTUP_CAP_INPUT_MANAGER, inputManagerHandle },
{ SYS_STARTUP_CAP_DISPLAY_MANAGER, displayManagerHandle },
};
s = KeSetProcessStartupCapabilities(proc, startupCapabilities, 5);
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: Failed to install startup capabilities. Status: %d\n", s);
IoCloseFile(f);
ObDereferenceObject(&proc->Header);
return 0;
}
// Map the executable through an image section backed by the open file.
uintptr_t imageBase = 0;
s = LdrLoadImageFileForProcess(proc, f, &imageBase);
IoCloseFile(f);
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: LdrLoadImageFileForProcess failed with status: %d\n", s);
ObDereferenceObject(&proc->Header);
return 0;
}
s = LdrRequireNoImports(imageBase);
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: bootstrap image %s must be import-free (status %d)\n", filePath, s);
ObDereferenceObject(&proc->Header);
return 0;
}
s = LdrProtectImageForProcess(proc, imageBase, true);
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: Failed to protect EXE image for %s (status %d)\n", filePath, s);
ObDereferenceObject(&proc->Header);
return 0;
}
proc->ImageBase = imageBase;
proc->ImageSize = LdrGetMappedImageSize(proc, imageBase);
uintptr_t entryPoint = LdrGetEntryPoint(imageBase);
// Create the main thread last. KeCreateThread queues it before returning.
const KE_THREAD_CREATE_PARAMETERS threadParameters =
KE_THREAD_CREATE_NAMED_NORMAL(PriorityNormal, proc->Name);
s = KeCreateThread(proc, (uintptr_t)entryPoint, 0, &threadParameters, &thread);
if (!KSUCCESS(s)) {
DbgPrint("KiLaunchUserProcess: Failed to create thread. Status: %d\n", s);
proc->ImageBase = 0;
proc->ImageSize = 0;
ObDereferenceObject(&proc->Header);
return 0;
}
uint32_t tid = thread->ThreadId;
DbgPrint("KiLaunchUserProcess: Thread created and queued! TID=%u\n", tid);
ObDereferenceObject(&thread->Header);
// Caller owns the reference returned by KeCreateProcess.
return proc;
}
// Implements the system Init Thread operation.
void SystemInitThread(void* arg) {
SYSTEM_INIT_ARGS* args = (SYSTEM_INIT_ARGS*)arg;
DbgPrint("SystemInitThread: Thread started. Igniting the system...\n");
KiRunEarlyKernelSelfTests();
KiInitializeDrivers(args->BootInfo, args->Hal);
KeTimeReloadSettings();
KiInitializeSwapFromSettings();
KiReclaimBootloaderMemory(args->BootInfo);
if (args->BootConfig.Debug & KE_DEBUG_SELFTEST)
KiRunKernelSelfTests(args->Hal);
// Launch the bootstrap service manager. Its allocated PID is not a system contract.
PROCESS* initProcess = KiLaunchUserProcess("system/init.exe", args->BootConfig.CommandLine);
if (!initProcess) {
DbgPrint("SystemInitThread: Failed to start system/init.exe.\n");
KePanic(KE_PANIC_CODE_INIT, "SystemInitThread: Failed to start system/init.exe.\n");
}
KeWaitForEvent(initProcess->ExitEvent, 0);
int exitCode = initProcess->ExitCode;
if (exitCode != 0) {
KePanic(KE_PANIC_CODE_INIT, "SystemInitThread: init.exe exited with code %d.\n", exitCode);
}
DbgPrint("SystemInitThread: init.exe exited with code %d.\n", exitCode);
ObDereferenceObject(&initProcess->Header);
if (args->BootConfig.Debug & (KE_DEBUG_CONSOLE | KE_DEBUG_FILE_LOG)) {
KSTATUS logStatus = KeFlushDebugLogToSystemRoot("kernel.log");
if (!KSUCCESS(logStatus))
DbgPrint("debuglog: shutdown flush failed st=0x%x\n", logStatus);
}
gKmainHal->Power.Shutdown();
MmFreePool(args);
}
// Returns whether one page-backed boot allocation is aligned, nonempty, and does not overflow.
static int KiValidateBootPageRange(uintptr_t physicalBase, uint32_t pageCount) {
if (!physicalBase || (physicalBase & (PAGE_SIZE - 1u)) != 0 || pageCount == 0)
return 0;
uint64_t byteCount = (uint64_t)pageCount * PAGE_SIZE;
return byteCount != 0 && physicalBase <= UINTPTR_MAX - byteCount;
}
// Returns whether one page-backed raw boot file is fully contained in its recorded allocation.
static int KiValidateBootFile(const BOOT_FILE* file) {
if (!file || !KiValidateBootPageRange(file->PhysicalBase, file->PageCount) || file->Length == 0)
return 0;
uint64_t capacity = (uint64_t)file->PageCount * PAGE_SIZE;
if ((uint64_t)file->Length + 1u > capacity || file->Name[0] == '\0')
return 0;
return memchr(file->Name, '\0', sizeof(file->Name)) != NULL;
}
// Returns whether one fixed core-image descriptor fits inside its page-backed physical allocation.
static int KiValidateBootImage(const BOOT_IMAGE* image, int requireEntry) {
if (!image || !image->VirtualBase || (image->VirtualBase & (PAGE_SIZE - 1u)) != 0 ||
!KiValidateBootPageRange(image->PhysicalBase, image->PageCount) || !image->ImageSize) {
return 0;
}
uint64_t capacity = (uint64_t)image->PageCount * PAGE_SIZE;
if (image->ImageSize > capacity || image->VirtualBase > UINTPTR_MAX - image->ImageSize)
return 0;
if (requireEntry && image->EntryRva >= image->ImageSize)
return 0;
return 1;
}
// Validates the exact bootloader/kernel handoff contract before dereferencing variable physical blobs.
static int KiValidateBootInfo(const BOOT_INFO* bootInfo) {
if (!bootInfo || bootInfo->Magic != BOOT_INFO_MAGIC ||
bootInfo->Version != BOOT_INFO_VERSION || bootInfo->Size != sizeof(BOOT_INFO) ||
bootInfo->MemoryMap.Magic != MEMORY_MAP_MAGIC ||
bootInfo->MemoryMap.RegionCount > MEMORY_MAX_REGIONS ||
bootInfo->PhysicalMapBase == 0) {
return 0;
}
uint64_t bootIniCapacity = (uint64_t)bootInfo->BootIni.PageCount * PAGE_SIZE;
if (!KiValidateBootPageRange(bootInfo->BootIni.PhysicalBase, bootInfo->BootIni.PageCount) ||
bootInfo->BootIni.Length == 0 || (uint64_t)bootInfo->BootIni.Length + 1u > bootIniCapacity ||
bootInfo->BootIni.PhysicalBase > UINTPTR_MAX - bootInfo->PhysicalMapBase) {
return 0;
}
uint64_t driverListCapacity = (uint64_t)bootInfo->BootDrivers.PageCount * PAGE_SIZE;
uint64_t driverListBytes = (uint64_t)bootInfo->BootDrivers.Count * sizeof(BOOT_FILE);
if (!KiValidateBootPageRange(bootInfo->BootDrivers.FilesPhysical, bootInfo->BootDrivers.PageCount) ||
bootInfo->BootDrivers.Count == 0 || driverListBytes > driverListCapacity ||
bootInfo->BootDrivers.FilesPhysical > UINTPTR_MAX - bootInfo->PhysicalMapBase) {
return 0;
}
const BOOT_FILE* bootFiles =
(const BOOT_FILE*)(bootInfo->PhysicalMapBase + bootInfo->BootDrivers.FilesPhysical);
for (uint32_t index = 0; index < bootInfo->BootDrivers.Count; ++index) {
if (!KiValidateBootFile(&bootFiles[index]) ||
bootFiles[index].PhysicalBase > UINTPTR_MAX - bootInfo->PhysicalMapBase) {
return 0;
}
}
if (!KiValidateBootImage(&bootInfo->KernelImage, 1) ||
!KiValidateBootImage(&bootInfo->HalImage, 0)) {
return 0;
}
return 1;
}
// Main Kernel Entry.
extern void KernelMain(BOOT_INFO* bootInfo) {
// Firmware is not required to transfer control with IF clear. Keep the
// bootstrap CPU masked until the interrupt manager and scheduler are ready.
_disable();
if (!KiValidateBootInfo(bootInfo)) {
for (;;)
__halt();
}
if (!KSUCCESS(KeBindBootstrapHal())) {
for (;;)
__halt();
}
const HAL_API* hal = KeGetHal();
// Physical & Virtual Memory initialization.
if (!MmInitializePhysical(&bootInfo->MemoryMap, bootInfo->PhysicalMapBase))
KeStopProcessor();
PHYSICAL_ADDRESS pml4 = (PHYSICAL_ADDRESS)__readcr3();
// The early virtual allocator starts small because it only needs bootstrap page tables before the PMM is online.
MmInitializeVirtual(pml4, 1 * 1024 * 1024);
// Bootstrap CPU and architecture setup (GDT/IDT/Faults).
KeInitializeBootstrapCpu();
KeInitializeGdt();
KeInitializeIdt();
// Register boot modules (Allows LdrGetExport to work for drivers and the HAL)
// Note: Kept to a single call here to avoid the duplicate in your original code.
KSTATUS moduleRegistryStatus = LdrRegisterModulesFromBootInfo(bootInfo);
if (!KSUCCESS(moduleRegistryStatus))
KeStopProcessor();
// Parse the raw mandatory boot.ini handoff once before HAL policy consumes debug flags.
KE_BOOT_CONFIG bootConfig = {0};
const char* bootIniText = (const char*)(bootInfo->PhysicalMapBase + bootInfo->BootIni.PhysicalBase);
KSTATUS bootConfigStatus = KeParseBootConfiguration(bootIniText, bootInfo->BootIni.Length, &bootConfig);
// HAL Initialization.
HAL_INIT_PARAMS halParams = {
.Size = sizeof(HAL_INIT_PARAMS),
.Flags = 0,
.PhysicalWindowBase = bootInfo->PhysicalMapBase,
.FramebufferBase = bootInfo->FramebufferBase,
.FramebufferWidth = bootInfo->FramebufferWidth,
.FramebufferHeight = bootInfo->FramebufferHeight,
.FramebufferStride = bootInfo->FramebufferStride,
.RsdpPhysical = bootInfo->RsdpPhysical,
.Debug = KSUCCESS(bootConfigStatus) ? (int)(bootConfig.Debug & 1u) : 0,
.AllocatePool = MmAllocatePool
};
KSTATUS s = KeInitializeHal(&halParams);
if (!KSUCCESS(s))
KeStopProcessor();
IoInitializeDdk(hal, bootInfo->PhysicalMapBase);
gKmainHal = hal;
KeInitDebug(hal, KSUCCESS(bootConfigStatus) ? bootConfig.Debug : 0);
if (!KSUCCESS(bootConfigStatus)) {
KePanic(KE_PANIC_CODE_INIT,
"boot.ini: malformed or missing mandatory configuration, status=0x%x\n",
bootConfigStatus);
}
DbgPrint("Boot: system volume selector=%s\n", bootConfig.SystemVolume);
// Bind IRQ dispatch while IF remains clear. Interrupt sources are armed
// later, after their kernel consumers have registered.
KeIrqInitialize(hal);
DbgPrint("CPU: PAT owns WB/WC/UC policy; MTRR default=WB fixed=off variable=off.\n");
KeTimeInitialize(bootInfo, hal);
KeDisplayInitialize(hal);
// CPU startup intentionally lives after HAL initialization but before IRQs
// and scheduler startup. HAL owns firmware processor discovery and platform
// startup signaling; the kernel owns KCPU records, per-CPU stacks, GDT/TSS/IDT state, and the
// AP park loop. External device IRQs remain routed to the boot processor during this
// step; APs only become runnable after scheduler admission below.
KeSetApplicationProcessorTrampoline((uint64_t)bootInfo->ApTrampolinePhys);
KSTATUS smpStatus = KeStartApplicationProcessors();
if (!KSUCCESS(smpStatus)) {
KePanic(KE_PANIC_CODE_INIT, "SMP: failed to start application processors, status=0x%x\n", smpStatus);
}
KeInitializeDpcSystem();
KeInputInitialize(hal);
KeIrqRegister(hal->Timer.IrqNumber, hal->Timer.HandleInterrupt);
KeSyscallInit(hal);
KSTATUS securityStatus = SeInitializeSecurity();
if (!KSUCCESS(securityStatus)) {
KePanic(KE_PANIC_CODE_INIT,
"security: failed to initialize root context, status=0x%x\n",
securityStatus);
}
// Dynamic Linking & Driver Execution.
// Scheduler Prep & Status Update.
KeInitializeScheduler();
KeIrqRegister(hal->Timer.IrqNumber, KeSchedulerTick);
KeConfigureCurrentProcessorTimer();
KSTATUS volumeManagerStatus = IoInitializeVolumeManager();
if (!KSUCCESS(volumeManagerStatus)) {
KePanic(KE_PANIC_CODE_INIT,
"I/O: failed to initialize volume manager notifications, status=0x%x\n",
volumeManagerStatus);
}
KSTATUS partitionStatus = IoInitializePartitionManager(bootConfig.SystemVolume);
if (!KSUCCESS(partitionStatus)) {
KePanic(KE_PANIC_CODE_INIT,
"I/O: failed to initialize partition discovery, status=0x%x\n",
partitionStatus);
}
KeAudioInitialize();
KSTATUS workStatus = KeStartWorkQueue();
if (!KSUCCESS(workStatus)) {
KePanic(KE_PANIC_CODE_INIT, "workq: failed to start passive work queue, status=0x%x\n", workStatus);
}
KSTATUS smpSchedStatus = KeAdmitApplicationProcessorsToScheduler();
if (!KSUCCESS(smpSchedStatus)) {
KePanic(KE_PANIC_CODE_INIT, "SMP: failed to admit APs to scheduler, status=0x%x\n", smpSchedStatus);
}
KiRunCoreHardeningSelfTests();
// Pack the arguments for the init thread.
SYSTEM_INIT_ARGS* initArgs = MmAllocatePool(sizeof(SYSTEM_INIT_ARGS));
if (!initArgs)
KePanic(KE_PANIC_CODE_INIT, "SystemInitThread: failed to allocate initialization arguments.\n");
initArgs->BootInfo = bootInfo;
initArgs->Hal = hal;
initArgs->BootConfig = bootConfig;
// Spawn the Initialization Thread. No creator reference is needed; the
// scheduler owns the live thread lifetime.
const KE_THREAD_CREATE_PARAMETERS initThreadParameters =
KE_THREAD_CREATE_NAMED_NORMAL(PriorityNormal, "system-init");
KSTATUS st = KeCreateKernelThread((uintptr_t)SystemInitThread,
(uintptr_t)initArgs,
&initThreadParameters, (THREAD**)0);
if (!KSUCCESS(st)) {
KePanic(KE_PANIC_CODE_INIT, "KernelMain: Failed to create SystemInitThread (status 0x%x)\n", st);
}
DbgPrint("KernelMain: Handing over to scheduler...\n");
// The bootstrap CPU becomes the scheduler idle context once interrupts are enabled.
while (true)
KeWaitForInterrupt();
}