6.4 KiB
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.batbuild.batrun.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
- UEFI loads
boot.ini, readsdrivers.ini - bootloader maps kernel, HAL, and boot drivers into the upper half
- direct physical window at
0xFFFF880000000000 - jumps to
KernelMain - PMM, VMM, GDT, IDT, HAL, IRQs, scheduler
- loads runtime drivers from disk
- 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
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: 62990 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.80 MB
-> Kernel Pool: 4.00 MB
-> User Heap: 0.47 MB
LaunchUserProcess: IoOpenFile: 0
LaunchUserProcess: IoGetFileSize: 5120
LaunchUserProcess: MmAllocateUserMemory: 0x7A020
LaunchUserProcess: IoReadFile: 0
LaunchUserProcess: IoCloseFile
Created process (PID 2) with command line: init.exe
LaunchUserProcess: PE Image mapped! Base 0x7c020, Entry 0x7D600
LaunchUserProcess: Thread created and queued!
[init] starting
[init] waiting
shell: ready
shell.exe
> clear
>
>
>
> 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
> clear
> video.exe
video: starting
video.exe
video: video.bk2 loaded
shell: goodbye
>
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.
