303 lines
7.8 KiB
Markdown
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
|
|
|
|

|
|
|
|
<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.
|