Files
nt-lite/readme.md
T

303 lines
7.8 KiB
Markdown

# 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)
<details><summary>Boot logs</summary>
```
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 <path> - Change directory
type <file> - Display file contents
del <file> - Delete a file
write <file> <tx> - 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 <path> - Change directory
type <file> - Display file contents
del <file> - Delete a file
write <file> <txt> - 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.
```
</details>
## 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.