rewrite init to restart failed processes, add file renaming, directory creation, directory renaming, directory removal, add process killing, unify shells, readme changes.
This commit is contained in:
1 parent
f80e66ecde
commit
ddb074f0e0
16 files changed
+476
-641
No files matched your search
@@ -4,88 +4,93 @@ 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.
|
||||
NT-Lite is a 64-bit operating system kernel written from scratch. It includes a UEFI bootloader, physical and virtual memory managers, a preemptive scheduler, a HAL, a VFS, a PE loader, and partial Win32 and POSIX layers. It boots into a shell.
|
||||
|
||||
The codebase is roughly 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)
|
||||
- HAL for screen, keyboard, mouse, timer, disk, PCI, and APIC
|
||||
- preemptive scheduler with priority levels
|
||||
- processes and threads
|
||||
- VFS with IRPs
|
||||
- drive-letter paths (`0:\apps\shell.exe`)
|
||||
- drive-letter paths such as `0:\apps\shell.exe`
|
||||
- INI-based boot and driver configuration
|
||||
- PE import resolution and dynamic driver loading
|
||||
- Win32 personality (partial)
|
||||
- POSIX personality (partial)
|
||||
- partial Win32 personality
|
||||
- partial POSIX personality
|
||||
|
||||
## how 2 build
|
||||
## architecture notes
|
||||
|
||||
* 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
|
||||
### memory layout
|
||||
|
||||
## how it looks when built
|
||||
NT-Lite uses a single virtual address space per booted system rather than a fully separate kernel address space and user address space. The distinction between kernel and user mode comes from page permissions and CPU privilege checks, not from having a different page table for the kernel.
|
||||
|
||||
I have some strong opinions on OS design.
|
||||
The kernel is mapped into the higher half of virtual memory and user processes only receive the regions they are explicitly granted. Kernel pages are marked supervisor-only, so user-mode code cannot read or write them directly. User pages are mapped with user permissions and are isolated from one another by the kernel’s allocator, VMM, and process creation path.
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
### boot chain
|
||||
|
||||
## driver model
|
||||
The bootloader reads configuration, loads the core images, maps the higher-half layout, and hands control to `KernelMain`. After that, the kernel takes over interrupt setup, paging, scheduler bring-up, runtime driver loading, and user process launch.
|
||||
|
||||
drivers are PE32+ `.sys` files with an entry point preferably named DriverEntry accepting a constant pointer to HAL_API.
|
||||
### drivers
|
||||
|
||||
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).
|
||||
Drivers are PE32+ `.sys` files with a conventional `DriverEntry` export that accepts a pointer to `HAL_API`.
|
||||
|
||||
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)`.
|
||||
Drivers are split into two groups:
|
||||
|
||||
currently shipping: AHCI (interrupts), IDE (PIO/DMA) and FAT32.
|
||||
- essential boot drivers, which are loaded before the kernel starts doing real work
|
||||
- runtime drivers, which are loaded later from disk once storage and the VFS are available
|
||||
|
||||
The driver model is intentionally small. Disk drivers expose a `DISK_DRIVER` vtable and register with `IoRegisterDisk(index, &driver)`. Filesystem drivers expose an `IO_FILESYSTEM` vtable and register with `IoRegisterFilesystem(index, &fs, &vol)`.
|
||||
|
||||
Currently shipping: AHCI (interrupts), IDE (PIO/DMA), and FAT32.
|
||||
|
||||
### I/O and filesystems
|
||||
|
||||
All file access flows through the VFS layer. That keeps disk access, filesystem parsing, and path translation separate instead of spreading storage logic across the rest of the kernel.
|
||||
|
||||
Paths are not interpreted as Windows paths by default. A drive such as `0:\` is a mounted namespace, while the Win32 and POSIX personalities translate their own path styles into the same underlying VFS.
|
||||
|
||||
### processes, threads, and syscalls
|
||||
|
||||
User processes are launched from PE images, imports are resolved before the first thread is queued, and the syscall layer provides the boundary between user code and kernel services. `syscall.dll` is the shared entry point for the supported personalities.
|
||||
|
||||
The scheduler is preemptive and priority-based, so threads do not depend on cooperative yielding to keep the system responsive. Process state is tracked separately from thread state, which allows a process to exit, be reaped, or be restarted by `init` without bringing down the rest of the system.
|
||||
|
||||
### personalities
|
||||
|
||||
The Win32 personality supports programs that expect drive letters, familiar process APIs, and a Windows-style runtime. The POSIX personality maps the same kernel primitives into a tree-shaped namespace and a different userspace contract.
|
||||
|
||||
## 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`
|
||||
1. UEFI loads `boot.ini` and reads `drivers.ini`
|
||||
2. the bootloader maps the kernel, HAL, and boot drivers into the upper half
|
||||
3. a direct physical window is mapped at `0xFFFF880000000000`
|
||||
4. control passes to `KernelMain`
|
||||
5. PMM, VMM, GDT, IDT, HAL, IRQs, and scheduler initialization run
|
||||
6. runtime drivers are loaded from disk
|
||||
7. `shell.exe` is launched
|
||||
|
||||
## paths (because they're different)
|
||||
## how to build
|
||||
|
||||
```
|
||||
"apps\shell.exe" -> current working directory
|
||||
"0:\apps\shell.exe" -> drive 0
|
||||
"2:\data\config.ini" -> drive 2
|
||||
- open the VS x64 build tools as administrator
|
||||
- change into this directory
|
||||
- run `mkimage.bat`
|
||||
- run `build.bat`
|
||||
- use one of `run.bat` (IDE), `rund.bat` (IDE, debug), `runa.bat` (AHCI), or `runad.bat` (AHCI, debug)
|
||||
|
||||
## paths
|
||||
|
||||
```text
|
||||
"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.
|
||||
Drives 0-7 are available. A drive only works if a filesystem is registered on it. The Win32 personality translates drive letters to drive numbers, while the POSIX personality maps drives onto a tree.
|
||||
|
||||
## screenshots
|
||||
|
||||
@@ -93,7 +98,7 @@ The Win32 personality translates drive letters to drive numbers, the POSIX perso
|
||||
|
||||
<details><summary>Boot logs</summary>
|
||||
|
||||
```
|
||||
```text
|
||||
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
|
||||
@@ -204,7 +209,7 @@ W_Init: Init WADfiles.
|
||||
Shareware!
|
||||
===========================================================================
|
||||
M_Init: Init miscellaneous info.
|
||||
R_Init: Init DOOM refresh daemon - [.. ]
|
||||
R_Init: Init Doom refresh daemon - [.. ]
|
||||
InitTextures
|
||||
InitFlats........
|
||||
InitSprites
|
||||
@@ -239,7 +244,7 @@ Available commands:
|
||||
type <file> - Display file contents
|
||||
del <file> - Delete a file
|
||||
write <file> <txt> - Create a file with text
|
||||
exit - Close the shell
|
||||
exit - Close the shell
|
||||
> dir
|
||||
System Volume Information
|
||||
drivers
|
||||
@@ -289,14 +294,23 @@ 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: Are processes isolated?
|
||||
A: No. But IPC is free.
|
||||
|
||||
Q: Is this finished?
|
||||
A: Not in the slightest.
|
||||
A: No.
|
||||
|
||||
Will it corrupt my data?
|
||||
A: It shouldn't.
|
||||
|
||||
Q: Why is the path syntax so weird?
|
||||
A: It makes sense to me.
|
||||
|
||||
Q: Why are the logs so verbose?
|
||||
A: How else do I debug it?
|
||||
|
||||
Q: What should I read first?
|
||||
A: This document.
|
||||
|
||||
Q: Can I use this in production?
|
||||
A: Don't.
|
||||
Reference in new issue
Block a user