# NT-Lite -- an x86-64 kernel Boots. Runs processes. Mimics Windows to some extent. ## what is it? A 64-bit operating system kernel written from scratch. UEFI bootloader, physical and virtual memory managers, preemptive scheduler, HAL, VFS, PE loader, partial Win32 layer. It boots into a shell. ~20k lines of C and assembly. ## features - UEFI bootloader - physical memory manager - virtual memory manager with kernel pool - HAL (screen, keyboard, mouse, timer, disk, PCI, APIC) - preemptive scheduler with priority levels - processes and threads - VFS with IRPs - drive-letter paths (`0:\apps\shell.exe`) - INI-based boot and driver configuration - PE import resolution and dynamic driver loading - Win32 personality (partial) - POSIX personality (partial) ## how 2 build * open vs x64 build tools as admin * cd into this directory * `mkimage.bat` * `build.bat` * `run.bat`(ide)/`rund.bat`(ide, debug)/`runa.bat`(ahci)/`runad.bat`(ahci, debug) * enjoy ## how it looks when built I have some strong opinions on OS design. ``` efi/boot/ bootx64.efi boot.ini hal.dll colonel.exe drivers/ drivers.ini ide.sys ahci.sys fat32.sys syscall.dll win32.dll posix.dll shell.exe video.exe ``` ## driver model drivers are PE32+ `.sys` files with an entry point preferably named DriverEntry accepting a constant pointer to HAL_API. drivers to be loaded have their path stored in `drivers.ini`, split into essential for boot (loaded by bootloader) and not required for boot (loaded by kernel). a disk driver fills in a `DISK_DRIVER` vtable and calls `IoRegisterDisk(index, &driver)`. a filesystem driver fills in an `IO_FILESYSTEM` vtable and calls `IoRegisterFilesystem(index, &fs, &vol)`. currently shipping: AHCI (interrupts), IDE (PIO/DMA) and FAT32. ## how it boots 1. UEFI loads `boot.ini`, reads `drivers.ini` 2. bootloader maps kernel, HAL, and boot drivers into the upper half 3. direct physical window at `0xFFFF880000000000` 4. jumps to `KernelMain` 5. PMM, VMM, GDT, IDT, HAL, IRQs, scheduler 6. loads runtime drivers from disk 7. launches `shell.exe` ## paths (because they're different) ``` "apps\shell.exe" -> current working directory "0:\apps\shell.exe" -> drive 0 "2:\data\config.ini" -> drive 2 ``` Drives 0-7. A drive only works if a filesystem registered on it. The Win32 personality translates drive letters to drive numbers, the POSIX personality maps drives onto a tree. ## screenshots ![video.exe running bink video 2](image.png)
Boot logs ``` BdsDxe: loading Boot0001 "UEFI QEMU HARDDISK QM00005 " from PciRoot(0x0)/Pci(0x4,0x0)/Sata(0x0,0xFFFF,0x0) BdsDxe: starting Boot0001 "UEFI QEMU HARDDISK QM00005 " from PciRoot(0x0)/Pci(0x4,0x0)/Sata(0x0,0xFFFF,0x0) 1 2 3 4 Loading colonel.exe... Loading hal.dll... 5 6 7 8 Found RSDP at: 0xF77E014 9 HAL: screen 1280x800 HAL: FADT PM1a_CNT=0xb004 PM1b_CNT=0x0000 DSDT=0x0f77a000 HAL: _S5_ SLP_TYP_A=0x00 SLP_TYP_B=0x00 HAL: LAPIC=00000000fee00000 IOAPIC=00000000fec00000 HPET=00000000fed00000 HAL: lapicPhys=0xFEE00000, lapicVirt=0xFFFF8800FEE00000, hpetPhys=0xFED00000 HAL: Attempting to calibrate APIC timer via HPET... HAL: APIC timer: 62981 ticks/ms HAL: initialisation complete. KernelMain: Handing over to scheduler... SystemInitThread: Thread started. Igniting the system... InitializeDrivers: Initializing drivers... InitializeDrivers: Executing DriverEntry for ide.sys IDE: Init IDE: No drive on primary channel InitializeDrivers: Driver ide.sys failed to init! InitializeDrivers: Executing DriverEntry for ahci.sys AHCI: driver loading... AHCI: controller at PCI 00:04.0 AHCI: PCI IRQ line = 11 AHCI: ABAR phys=0x81060000 version=0x00010000 AHCI: cap=0xc0141f05 ports=6 slots=32 64bit=1 AHCI: port 0: link up, initializing... AHCI: port COMRESET done: sig=0x00000101 ssts=0x00000113 AHCI: drive 0: 524288 sectors (256 MB) AHCI: drive 0 registered AHCI: port 1: no link (ssts=0x00000000) AHCI: port 2: no link (ssts=0x00000000) AHCI: port 3: no link (ssts=0x00000000) AHCI: port 4: no link (ssts=0x00000000) AHCI: port 5: no link (ssts=0x00000000) AHCI: ISR registered on IRQ 11; initialised 1 drive(s) InitializeDrivers: Executing DriverEntry for fat32.sys FAT32: Init FAT32: Init complete (status=0, clusters=128480). Found runtime driver: usb.sys Test runtime driver SystemInitThread: Loading system DLLs... Memory Status: -> Free (PMM): 151.71 MB -> Kernel Pool: 4.00 MB -> User Heap: 0.55 MB LaunchUserProcess: IoOpenFile: 0 LaunchUserProcess: IoGetFileSize: 5120 LaunchUserProcess: MmAllocateUserMemory: 0x8E020 LaunchUserProcess: IoReadFile: 0 LaunchUserProcess: IoCloseFile Created process (PID 2) with command line: init.exe LaunchUserProcess: PE Image mapped! Base 0x90020, Entry 0x91600 LaunchUserProcess: Thread created and queued! [init] starting [init] waiting shell: ready > help Available commands: help - Show this list dir - List files cd - Change directory type - Display file contents del - Delete a file write - Create a file with text exit - Close the shell > dir System Volume Information drivers efi colonel.exe hal.dll syscall.dll win32.dll posix.dll init.exe shell_win32.exe shell_posix.exe shell_native.exe doom.exe video.exe boot.ini bink2w64.dll video.bk2 doom1.wad > shell_win32.exe shell: ready shell_win32.exe > doom.exe doom: starting getenv: Unknown variable DOOMWADDIR DOOM Shareware Startup v1.10 V_Init: allocate screens. M_LoadDefaults: Load system defaults. Z_Init: Init zone memory allocation daemon. W_Init: Init WADfiles. adding ./doom1.wad =========================================================================== Shareware! =========================================================================== M_Init: Init miscellaneous info. R_Init: Init DOOM refresh daemon - [.. ] InitTextures InitFlats........ InitSprites InitColormaps R_InitData R_InitPointToAngle R_InitTables R_InitPlanes R_InitLightTables R_InitSkyMap R_InitTranslationsTables P_Init: Init Playloop state. I_Init: Setting up machine state. I_InitSound: I_InitSound: pre-cached all sound data I_InitSound: sound module ready D_CheckNetGame: Checking network game status. startskill 2 deathmatch: 0 startmap: 1 startepisode: 1 player 1 of 1 (1 nodes) S_Init: Setting up sound. S_Init: default sfx volume 8 HU_Init: Setting up heads up display. ST_Init: Init status bar. doom: entering game loop I_ShutdownSound: NOT finishing pending sounds > shell_posix.exe shell: ready > help Available commands: help - Show this list dir [path] - List directory contents cd - Change directory type - Display file contents del - Delete a file write - Create a file with text exit - Close the shell > dir System Volume Information drivers efi colonel.exe hal.dll syscall.dll win32.dll posix.dll init.exe shell_win32.exe shell_posix.exe shell_native.exe doom.exe video.exe boot.ini bink2w64.dll video.bk2 doom1.wad .doo > video.exe video: starting video.exe video: video.bk2 loaded shell: goodbye > exit shell: goodbye > exit shell: goodbye > exit shell: goodbye [init] done ProcessWatcherThread: Process "init.exe" (PID 2) exited with code 0. ProcessWatcherThread: Shutting down. ```
## faq Q: Why? A: Learning. Fun. Q: Does it run Doom? A: `doom.exe` Q: Is the Win32 layer real? A: Real enough to load binaries that expect it. Not real enough to run Notepad. Q: Is the scheduler preemptive? A: As much as it will ever be. Q: Will it corrupt my data? A: It shouldn't. Q: Is this finished? A: Not in the slightest. Q: Can I use this in production? A: Don't.