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

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.

S
Description
No description provided
Readme
37 MiB
0 Stars 1 Watchers 0 Forks
Languages
C 98.9%
Assembly 0.9%
C++ 0.1%