This guide explains how to build and run AdrOS on your local machine (Linux/WSL).
-AdrOS is a Unix-like, POSIX-compatible OS kernel with threads, futex synchronization, networking (TCP/IP + DNS via lwIP), dynamic linking infrastructure, FAT16 filesystem, ASLR, vDSO, zero-copy DMA, and a POSIX shell. See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for the full compatibility checklist.
+AdrOS is a Unix-like, POSIX-compatible OS kernel with threads, futex synchronization, networking (TCP/IP + DNS via lwIP), dynamic linking infrastructure, FAT16 filesystem, ASLR, vDSO, zero-copy DMA, a POSIX shell, framebuffer graphics (`/dev/fb0`), raw keyboard input (`/dev/kbd`), uid/gid/euid/egid permission enforcement, and a working DOOM port. See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for the full compatibility checklist.
## 1. Dependencies
- `/bin/echo` — argv/envp test
- `/bin/sh` — POSIX sh-compatible shell with `$PATH` search, pipes, redirects, builtins
- `/bin/cat`, `/bin/ls`, `/bin/mkdir`, `/bin/rm` — core utilities
+- `/bin/doom.elf` — DOOM (doomgeneric port) — included in initrd if built (see below)
- `/lib/ld.so` — stub dynamic linker (placeholder for future shared library support)
-The ulibc provides: `printf`, `malloc`/`free`/`calloc`/`realloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h`, `signal.h` (with `raise`, `sigaltstack`, `sigpending`, `sigsuspend`), `stdio.h` (buffered I/O with `fopen`/`fread`/`fwrite`/`fclose`), `sys/times.h`, `sys/uio.h`, `linux/futex.h`, and `realpath()`.
+The ulibc provides: `printf`, `malloc`/`free`/`calloc`/`realloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h`, `signal.h` (with `raise`, `sigaltstack`, `sigpending`, `sigsuspend`), `stdio.h` (buffered I/O with `fopen`/`fread`/`fwrite`/`fclose`), `stdlib.h` (`atof`, `strtol`, `getenv` stub, `system` stub), `ctype.h`, `sys/mman.h` (`mmap`/`munmap`), `sys/ioctl.h` (`ioctl`), `time.h` (`nanosleep`/`clock_gettime`), `sys/times.h`, `sys/uio.h`, `sys/types.h`, `sys/stat.h`, `math.h` (`fabs`), `assert.h`, `fcntl.h`, `strings.h`, `inttypes.h`, `linux/futex.h`, and `realpath()`.
### Smoke tests
The init program (`/bin/init.elf`) runs a comprehensive suite of smoke tests on boot, covering:
- `QEMU_DEBUG=1` enables QEMU logging to `qemu.log` using `-d guest_errors,cpu_reset -D qemu.log`.
- `QEMU_INT=1` appends `-d int` to QEMU debug flags.
-## 3. Building & Running (ARM64)
+## 3. Building DOOM
+
+The DOOM port uses the [doomgeneric](https://github.com/ozkl/doomgeneric) engine with an AdrOS-specific platform adapter.
+
+### Setup
+```bash
+cd user/doom
+git clone https://github.com/ozkl/doomgeneric.git
+make
+```
+
+This produces `user/doom/doom.elf` (\~450KB). The main `Makefile` will **automatically include** `doom.elf` in the initrd if it exists.
+
+### Running DOOM
+```bash
+make iso
+qemu-system-i386 -cdrom adros-x86.iso -m 128M -vga std \
+ -drive file=disk.img,if=ide,format=raw
+```
+
+From the AdrOS shell:
+```
+/bin/doom.elf -iwad /path/to/doom1.wad
+```
+
+DOOM requires:
+- A VBE framebuffer (`-vga std` in QEMU)
+- `doom1.wad` (shareware) accessible from the filesystem
+- Kernel support: `/dev/fb0` (mmap framebuffer), `/dev/kbd` (raw PS/2 scancodes), `nanosleep`, `clock_gettime`
+
+## 4. Building & Running (ARM64)
### Build
```bash
- **Kernel heap** — doubly-linked free list with coalescing, dynamic growth up to 64MB
- **Slab allocator** — `slab_cache_t` with free-list-in-place and spinlock
- **Shared memory** — System V IPC style (`shmget`/`shmat`/`shmdt`/`shmctl`)
-- **`mmap`/`munmap`** — anonymous mappings + shared memory backing
+- **`mmap`/`munmap`** — anonymous mappings, shared memory backing, and file-backed (fd) mappings
- **SMEP** — Supervisor Mode Execution Prevention enabled in CR4
- **W^X** — user `.text` segments marked read-only after ELF load; NX on data segments
-- **Guard pages** — 32KB user stack with unmapped guard page below (triggers SIGSEGV on overflow)
+- **Guard pages** — 32KB user stack with unmapped guard page below (triggers SIGSEGV on overflow); kernel stacks use dedicated guard-paged region at `0xC8000000`
- **ASLR** — TSC-seeded xorshift32 PRNG randomizes user stack base by up to 1MB per `execve`
- **vDSO** — kernel-updated shared page mapped read-only into every user process at `0x007FE000`
- **TLS** — `set_thread_area` via GDT entry 22 (user GS segment, ring 3)
- **Futex** — `FUTEX_WAIT`/`FUTEX_WAKE` with global waiter table for efficient thread synchronization
- **Sessions & groups** — `setsid`, `setpgid`, `getpgrp`
-- **Permissions** — per-process `uid`/`gid`; `chmod`, `chown`, `setuid`, `setgid`, `access`, `umask`
+- **Permissions** — per-process `uid`/`gid`/`euid`/`egid`; `chmod`, `chown`, `setuid`, `setgid`, `seteuid`, `setegid`, `access`, `umask`; VFS permission enforcement on `open()`
- **User heap** — `brk`/`sbrk` syscall
- **Time** — `nanosleep`, `clock_gettime` (`CLOCK_REALTIME` via RTC, `CLOCK_MONOTONIC`), `alarm`/`SIGALRM`, `times` (CPU accounting)
- **File I/O:** `open`, `openat`, `read`, `write`, `close`, `lseek`, `stat`, `fstat`, `fstatat`, `dup`, `dup2`, `dup3`, `pipe`, `pipe2`, `select`, `poll`, `ioctl`, `fcntl`, `getdents`, `pread`, `pwrite`, `readv`, `writev`, `truncate`, `ftruncate`, `fsync`, `fdatasync`
- **Directory ops:** `mkdir`, `rmdir`, `unlink`, `unlinkat`, `rename`, `chdir`, `getcwd`, `link`, `symlink`, `readlink`, `chmod`, `chown`, `access`, `umask`
- **Signals:** `sigaction` (`SA_SIGINFO`), `sigprocmask`, `kill`, `sigreturn` (full trampoline), `sigpending`, `sigsuspend`, `sigaltstack`
-- **Process:** `setuid`, `setgid`, `alarm`, `times`, `futex`
+- **Process:** `setuid`, `setgid`, `seteuid`, `setegid`, `getuid`, `getgid`, `geteuid`, `getegid`, `alarm`, `times`, `futex`
- **FD flags:** `O_NONBLOCK`, `O_CLOEXEC`, `O_APPEND`, `FD_CLOEXEC` via `fcntl` (`F_GETFD`/`F_SETFD`/`F_GETFL`/`F_SETFL`)
- **File locking:** `flock` (advisory, no-op stub)
- **Shared memory:** `shmget`, `shmat`, `shmdt`, `shmctl`
### Filesystems (8 types)
- **tmpfs** — in-memory filesystem
-- **devfs** — `/dev/null`, `/dev/zero`, `/dev/random`, `/dev/urandom`, `/dev/console`, `/dev/tty`, `/dev/ptmx`, `/dev/pts/N`
+- **devfs** — `/dev/null`, `/dev/zero`, `/dev/random`, `/dev/urandom`, `/dev/console`, `/dev/tty`, `/dev/ptmx`, `/dev/pts/N`, `/dev/fb0` (framebuffer), `/dev/kbd` (raw scancodes)
- **overlayfs** — copy-up semantics
- **diskfs** — hierarchical inode-based on-disk filesystem at `/disk` with symlinks and hard links
- **persistfs** — minimal persistence at `/persist`
- **LAPIC + IOAPIC** — replaces legacy PIC; ISA IRQ routing
- **SMP** — 4 CPUs via INIT-SIPI-SIPI, per-CPU data via GS segment
- **ACPI** — MADT parsing for CPU topology and IOAPIC discovery
-- **VBE framebuffer** — maps LFB, pixel drawing, font rendering
+- **VBE framebuffer** — maps LFB, pixel drawing, font rendering; `/dev/fb0` device with `ioctl`/`mmap` for userspace access
- **UART**, **VGA text**, **PS/2 keyboard**, **PIT timer**, **LAPIC timer**
- **RTC** — CMOS real-time clock driver for wall-clock time (`CLOCK_REALTIME`)
- **E1000 NIC** — Intel 82540EM Ethernet controller
- **MTRR** — write-combining support via variable-range MTRR programming
### Userland
-- **ulibc** — `printf`, `malloc`/`free`/`calloc`/`realloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h` (buffered I/O), `sys/times.h`, `sys/uio.h`, `linux/futex.h`, `realpath()`
+- **ulibc** — `printf`, `malloc`/`free`/`calloc`/`realloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h` (buffered I/O), `stdlib.h` (`atof`, `strtol`), `ctype.h`, `sys/mman.h` (`mmap`/`munmap`), `sys/ioctl.h`, `sys/times.h`, `sys/uio.h`, `sys/types.h`, `sys/stat.h`, `time.h` (`nanosleep`/`clock_gettime`), `math.h`, `assert.h`, `fcntl.h`, `strings.h`, `inttypes.h`, `linux/futex.h`, `realpath()`
- **ELF32 loader** — secure with W^X + ASLR; supports `ET_EXEC` + `ET_DYN` + `PT_INTERP` (dynamic linking)
- **Shell** — `/bin/sh` (POSIX sh-compatible with builtins, pipes, redirects, `$PATH` search)
- **Core utilities** — `/bin/cat`, `/bin/ls`, `/bin/mkdir`, `/bin/rm`, `/bin/echo`
- `/bin/init.elf` — comprehensive smoke test suite
+- `/bin/doom.elf` — DOOM (doomgeneric port) — runs on `/dev/fb0` + `/dev/kbd`
- `/lib/ld.so` — stub dynamic linker (placeholder for future shared library support)
### Dynamic Linking (infrastructure)
See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for a detailed checklist.
-**All 31 planned POSIX implementation tasks are complete.** The kernel covers ~90% of the core POSIX interfaces needed for a practical Unix-like system.
+**All 31 planned POSIX implementation tasks are complete**, plus additional features including the DOOM game port, uid/gid/euid/egid permission enforcement, framebuffer device, raw keyboard device, fd-backed mmap, and kernel stack guard pages. The kernel covers **~93%** of the core POSIX interfaces needed for a practical Unix-like system.
### Remaining work for full POSIX compliance
- **Full `ld.so`** — relocation processing for shared libraries (`dlopen`/`dlsym`)
- **`sigqueue`** — queued real-time signals
- **`setitimer`/`getitimer`** — interval timers
- **ext2 filesystem** — standard on-disk filesystem
-- **File-backed `mmap`** — map file contents into memory
- **Per-CPU scheduler runqueues** — SMP scalability
+- **SMAP** — Supervisor Mode Access Prevention
- **Multi-arch bring-up** — ARM/RISC-V functional kernels
## Directory Structure
-- `src/kernel/` — Architecture-independent kernel (VFS, syscalls, scheduler, tmpfs, diskfs, devfs, overlayfs, procfs, FAT16, PTY, TTY, shm, signals, networking, threads, vDSO, KASLR)
+- `src/kernel/` — Architecture-independent kernel (VFS, syscalls, scheduler, tmpfs, diskfs, devfs, overlayfs, procfs, FAT16, PTY, TTY, shm, signals, networking, threads, vDSO, KASLR, permissions)
- `src/arch/x86/` — x86-specific (boot, VMM, IDT, LAPIC, IOAPIC, SMP, ACPI, CPUID, SYSENTER, ELF loader, MTRR)
- `src/hal/x86/` — HAL x86 (CPU, keyboard, timer, UART, PCI, ATA PIO/DMA, E1000 NIC, RTC)
- `src/drivers/` — Device drivers (VBE, initrd, VGA, timer)
-- `src/mm/` — Memory management (PMM, heap, slab)
+- `src/mm/` — Memory management (PMM, heap, slab, arch-independent VMM wrappers)
- `src/net/` — Networking (lwIP port, DNS resolver)
- `include/` — Header files
- `user/` — Userland programs (`init.c`, `echo.c`, `sh.c`, `cat.c`, `ls.c`, `mkdir.c`, `rm.c`, `ldso.c`)
-- `user/ulibc/` — Minimal C library (`printf`, `malloc`, `string.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h`, `sys/uio.h`, `linux/futex.h`)
+- `user/doom/` — DOOM port (doomgeneric engine + AdrOS platform adapter)
+- `user/ulibc/` — Minimal C library (`printf`, `malloc`, `string.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h`, `stdlib.h`, `ctype.h`, `math.h`, `sys/mman.h`, `sys/ioctl.h`, `sys/uio.h`, `time.h`, `linux/futex.h`)
- `tests/` — Host unit tests, smoke tests, GDB scripted checks
- `tools/` — Build tools (`mkinitrd`)
- `docs/` — Documentation (POSIX roadmap, audit report, supplementary analysis, testing plan)
User stacks now have a 4KB unmapped guard page below the 32KB stack region.
Stack overflow triggers a page fault → SIGSEGV instead of silent corruption.
-Kernel stacks (4KB) still lack guard pages — enhancement for the future.
+Kernel stacks now use a dedicated guard-paged region at `0xC8000000` with
+an unmapped page below each 4KB stack (`kstack_alloc()`).
---
| 2.7 | MODERATE | Logic | utils.c | itoa UB for INT_MIN | Open |
| 3.5 | MODERATE | Security | syscall.c | fd bounds not always checked | Open |
| 4.2 | MODERATE | Memory | heap.c | kfree doesn't zero | Open |
-| 4.3 | MODERATE | Memory | scheduler.c | No stack guard pages | **USER FIXED** (kernel stacks still open) |
+| 4.3 | MODERATE | Memory | scheduler.c | No stack guard pages | **FIXED** (user + kernel stacks) |
## 7. Fix Summary
**5 HIGH fixed**: slab uses kmalloc instead of phys_to_virt, execve sp bounds check,
SMEP enabled via CR4, heap grows dynamically to 64MB, waitpid NULL guard.
-**1 MODERATE fixed**: User stack guard pages implemented (unmapped page below 32KB stack).
+**2 MODERATE fixed**: User stack guard pages (unmapped page below 32KB stack) and kernel stack guard pages (`kstack_alloc()` at `0xC8000000` with unmapped guard page per stack).
-**Remaining**: 1 CRITICAL (layer violation — arch refactor), 7 MODERATE (open).
-SMAP not yet enabled (SMEP is active). Kernel stacks still lack guard pages.
+**Remaining**: 1 CRITICAL (layer violation — arch refactor), 6 MODERATE (open).
+SMAP not yet enabled (SMEP is active).
| `setpgid` | [x] | |
| `getpgrp` | [x] | |
| `getuid`/`getgid` | [x] | Per-process uid/gid |
-| `setuid`/`setgid` | [x] | Set process uid/gid |
+| `geteuid`/`getegid` | [x] | Effective uid/gid |
+| `setuid`/`setgid` | [x] | Set process uid/gid; permission checks (only root can set arbitrary) |
+| `seteuid`/`setegid` | [x] | Set effective uid/gid; permission checks |
| `brk`/`sbrk` | [x] | `syscall_brk_impl()` — per-process heap break |
-| `mmap`/`munmap` | [x] | Anonymous mappings + shared memory |
+| `mmap`/`munmap` | [x] | Anonymous mappings, shared memory backing, and file-backed (fd) mappings |
| `clone` | [x] | Thread creation with `CLONE_VM`/`CLONE_FILES`/`CLONE_THREAD`/`CLONE_SETTLS` |
| `set_thread_area` | [x] | GDT-based TLS via GS segment (GDT entry 22, ring 3) |
| `nanosleep`/`sleep` | [x] | `syscall_nanosleep_impl()` with tick-based sleep |
| `struct vfs_dirent` (generic) | [x] | Unified format across all FS |
| **tmpfs** | [x] | In-memory; dirs + files; `readdir` |
| **overlayfs** | [x] | Copy-up; `readdir` delegates to upper/lower |
-| **devfs** | [x] | `/dev/null`, `/dev/zero`, `/dev/random`, `/dev/urandom`, `/dev/console`, `/dev/tty`, `/dev/ptmx`, `/dev/pts/N` |
+| **devfs** | [x] | `/dev/null`, `/dev/zero`, `/dev/random`, `/dev/urandom`, `/dev/console`, `/dev/tty`, `/dev/ptmx`, `/dev/pts/N`, `/dev/fb0`, `/dev/kbd` |
| **diskfs** (on-disk) | [x] | Hierarchical inodes; full POSIX ops; symlinks; hard links with `nlink` tracking |
| **persistfs** | [x] | Minimal persistence at `/persist` |
| **procfs** | [x] | `/proc/meminfo` + per-process `/proc/[pid]/status`, `/proc/[pid]/maps` |
| **FAT16** (read-only) | [x] | BPB parsing, FAT chain traversal, root dir finddir, VFS read |
-| Permissions (`uid`/`gid`/mode) | [x] | `chmod`, `chown`; mode bits stored in VFS nodes |
+| Permissions (`uid`/`gid`/`euid`/`egid`/mode) | [x] | `chmod`, `chown` with permission checks; VFS `open()` enforces rwx bits vs process euid/egid and file uid/gid/mode |
| Hard links | [x] | `diskfs_link()` with shared data blocks and `nlink` tracking |
| Symbolic links | [x] | `symlink`, `readlink`; followed by VFS lookup |
| ext2 support | [ ] | |
| W^X for user ELFs | [x] | Text segments read-only after load |
| SMEP | [x] | Enabled in CR4 if CPU supports |
| `brk`/`sbrk` | [x] | Per-process heap break |
-| `mmap`/`munmap` | [x] | Anonymous mappings, shared memory backing |
+| `mmap`/`munmap` | [x] | Anonymous mappings, shared memory backing, file-backed (fd) mappings |
| Shared memory (`shmget`/`shmat`/`shmdt`) | [x] | System V IPC style |
| Copy-on-write (COW) fork | [x] | PTE bit 9 as CoW marker + page fault handler |
| PAE + NX bit | [x] | PAE paging with NX (bit 63) on data segments |
-| Guard pages | [x] | 32KB user stack with unmapped guard page below (triggers SIGSEGV on overflow) |
+| Guard pages | [x] | 32KB user stack with unmapped guard page below (triggers SIGSEGV on overflow); kernel stacks in guard-paged region at `0xC8000000` |
| ASLR | [x] | TSC-seeded xorshift32 PRNG; randomizes user stack base by up to 1MB per `execve` |
| vDSO shared page | [x] | Kernel-updated `tick_count` mapped read-only at `0x007FE000` in every user process |
| LAPIC + IOAPIC | [x] | Replaces legacy PIC |
| SMP (multi-CPU boot) | [x] | 4 CPUs via INIT-SIPI-SIPI, per-CPU data via GS |
| CPUID feature detection | [x] | Leaf 0/1/7/extended; SMEP/SMAP detection |
-| VBE framebuffer | [x] | Maps LFB, pixel drawing, font rendering |
+| VBE framebuffer | [x] | Maps LFB, pixel drawing, font rendering; `/dev/fb0` device with `ioctl`/`mmap` |
+| Raw keyboard (`/dev/kbd`) | [x] | PS/2 scancode ring buffer; non-blocking read for game input |
| SYSENTER fast syscall | [x] | MSR setup + handler |
| E1000 NIC (Intel 82540EM) | [x] | MMIO-based, IRQ-driven, lwIP integration |
| RTC (real-time clock) | [x] | CMOS RTC driver; provides wall-clock time for `CLOCK_REALTIME` |
| `/bin/ls` | [x] | Uses `getdents` |
| `/bin/mkdir` | [x] | |
| `/bin/rm` | [x] | |
+| `/bin/doom.elf` | [x] | DOOM (doomgeneric port) running on `/dev/fb0` + `/dev/kbd` |
| `/lib/ld.so` | [~] | Stub dynamic linker (placeholder for future shared library support) |
-| Minimal libc (ulibc) | [x] | `printf`, `malloc`/`free`/`calloc`/`realloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h`, `signal.h`, `sys/times.h`, `sys/uio.h`, `linux/futex.h`, `stdio.h` (buffered I/O) |
+| Minimal libc (ulibc) | [x] | `printf`, `malloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h`, `stdlib.h`, `ctype.h`, `sys/mman.h`, `sys/ioctl.h`, `time.h`, `math.h`, `assert.h`, `fcntl.h`, `strings.h`, `inttypes.h`, `sys/types.h`, `sys/stat.h`, `sys/times.h`, `sys/uio.h`, `linux/futex.h` |
| `$PATH` search | [x] | Shell resolves commands via `$PATH` |
## 14. Scheduler
## Implementation Progress
-### All 31 planned tasks completed ✅
+### All 31 planned tasks completed ✅ + 7 additional features
**High Priority (8/8):**
1. ~~`raise()` em ulibc~~ ✅
30. ~~Userspace `ld.so` stub~~ ✅
31. ~~ASLR~~ ✅
+**Additional Features (post-31 tasks):**
+32. ~~DevFS ↔ TTY/PTY decoupling (`devfs_register_device` API)~~ ✅
+33. ~~VMM arch separation (`src/mm/vmm.c` generic wrappers)~~ ✅
+34. ~~`/dev/fb0` framebuffer device (ioctl + mmap)~~ ✅
+35. ~~`/dev/kbd` raw scancode device~~ ✅
+36. ~~fd-backed `mmap` (file descriptor memory mapping)~~ ✅
+37. ~~Kernel stack guard pages (0xC8000000 region)~~ ✅
+38. ~~uid/gid/euid/egid with VFS permission enforcement~~ ✅
+39. ~~DOOM port (doomgeneric + AdrOS adapter, 450KB doom.elf)~~ ✅
+
---
## Remaining Work for Full POSIX Compliance
| Gap | Impact | Effort |
|-----|--------|--------|
| **ext2 filesystem** | No standard on-disk filesystem | Large |
-| **`mmap` file-backed** — map file contents into memory | Only anonymous/shm maps supported | Large |
| **`pipe` capacity** — `F_GETPIPE_SZ`/`F_SETPIPE_SZ` | Fixed-size pipe buffer | Small |
| **`waitid`** — extended wait | Missing POSIX interface | Small |
| **`posix_spawn`** — efficient process creation | Missing POSIX interface | Medium |
| CPUID feature detection | ✅ `cpu_get_features()` for PAE/NX | ✅ Full CPUID leaf 0/1/7/extended; SMEP/SMAP detection | None |
| SMEP | Not discussed | ✅ Enabled in CR4 if CPU supports | **AdrOS is ahead** |
| Copy-on-Write (CoW) | ✅ Full implementation | ✅ `vmm_as_clone_user_cow()` + `vmm_handle_cow_fault()` | None |
-| `vmm_find_free_area()` | ✅ Scan user VA space for holes | ❌ Not implemented | Enhancement (mmap works with fixed addresses) |
+| `vmm_find_free_area()` | ✅ Scan user VA space for holes | ❌ Not implemented | Enhancement (mmap works with fixed/hint addresses) |
| `vmm_map_dma_buffer()` | ✅ Map phys into user VA | ✅ `ata_dma_read_direct`/`ata_dma_write_direct` zero-copy DMA | None |
| TLB flush | ✅ `invlpg` + full flush | ✅ `invlpg()` per page | None |
| Spinlock on VMM ops | ✅ `vmm_kernel_lock` | ❌ No lock | Enhancement for SMP |
-**Summary:** AdrOS VMM is fully featured with CoW fork, recursive mapping, SMEP, PAE+NX hardware W^X, guard pages, ASLR, and vDSO shared page.
+**Summary:** AdrOS VMM is fully featured with CoW fork, recursive mapping, SMEP, PAE+NX hardware W^X, guard pages (user + kernel stacks), ASLR, vDSO shared page, and fd-backed mmap.
---
## Part 2 — POSIX Compatibility Assessment
-### Overall Score: **~90% toward a practical Unix-like POSIX system**
+### Overall Score: **~93% toward a practical Unix-like POSIX system**
This score reflects that AdrOS has a **mature and feature-rich kernel** with virtually
all core POSIX subsystems implemented and working end-to-end. All 31 planned tasks
-have been completed, covering syscalls, signals, filesystem operations, threads,
-synchronization, networking, security hardening, and userland tooling.
+have been completed, plus 8 additional features including DOOM game port, uid/gid/euid/egid
+permission enforcement, framebuffer device (`/dev/fb0`), raw keyboard device (`/dev/kbd`),
+fd-backed mmap, kernel stack guard pages, VMM arch separation, and DevFS decoupling.
### What AdrOS Already Has (Strengths)
-1. **Process model** — `fork` (CoW), `execve`, `waitpid`, `exit`, `getpid`, `getppid`, `setsid`, `setpgid`, `getpgrp`, `brk`, `setuid`/`setgid`, `alarm`, `times`, `futex` — all working
+1. **Process model** — `fork` (CoW), `execve`, `waitpid`, `exit`, `getpid`, `getppid`, `setsid`, `setpgid`, `getpgrp`, `brk`, `setuid`/`setgid`/`seteuid`/`setegid`/`getuid`/`getgid`/`geteuid`/`getegid`, `alarm`, `times`, `futex` — all working
2. **File I/O** — `open`, `read`, `write`, `close`, `lseek`, `stat`, `fstat`, `dup`, `dup2`, `dup3`, `pipe`, `pipe2`, `fcntl`, `getdents`, `pread`/`pwrite`, `readv`/`writev`, `truncate`/`ftruncate`, `fsync`, `O_CLOEXEC`, `O_APPEND`, `FD_CLOEXEC` — comprehensive
3. **Signals** — `sigaction`, `sigprocmask`, `kill`, `sigreturn`, `raise`, `sigpending`, `sigsuspend`, `sigaltstack`, Ctrl+C/Z/D signal chars — **complete**
4. **VFS** — 8 filesystem types (tmpfs, devfs, overlayfs, diskfs, persistfs, procfs, FAT16, initrd), mount table, path resolution, hard links — excellent
5. **TTY/PTY** — Line discipline, raw mode, job control, signal chars, `TIOCGWINSZ`, PTY, VMIN/VTIME — very good
6. **Select/Poll** — Working for pipes, TTY, PTY, `/dev/null`, sockets
-7. **Memory management** — PMM (spinlock + refcount + contiguous alloc), VMM (CoW, recursive PD, PAE+NX), heap (dynamic 64MB), slab allocator, SMEP, shared memory, guard pages, ASLR, vDSO
+7. **Memory management** — PMM (spinlock + refcount + contiguous alloc), VMM (CoW, recursive PD, PAE+NX), heap (dynamic 64MB), slab allocator, SMEP, shared memory, guard pages (user + kernel stacks), ASLR, vDSO, fd-backed mmap
8. **Hardware** — PCI, ATA PIO+DMA (bounce + zero-copy), LAPIC/IOAPIC, SMP (4 CPUs), ACPI, VBE framebuffer, SYSENTER, CPUID, RTC, MTRR write-combining
9. **Networking** — E1000 NIC, lwIP TCP/IP, socket API (TCP+UDP), DNS resolver
-10. **Userland** — ulibc (`printf`, `malloc`, `string.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h`, `realpath`), ELF loader with W^X + ASLR, POSIX shell, core utilities, `ld.so` stub
+10. **Userland** — ulibc (`printf`, `malloc`, `string.h`, `errno.h`, `pthread.h`, `signal.h`, `stdio.h`, `stdlib.h`, `ctype.h`, `sys/mman.h`, `sys/ioctl.h`, `time.h`, `math.h`, `fcntl.h`, `realpath`), ELF loader with W^X + ASLR, POSIX shell, core utilities, DOOM port, `ld.so` stub
11. **Testing** — 47 host unit tests, 19 smoke tests, cppcheck, sparse, gcc -fanalyzer, GDB scripted checks
-12. **Security** — SMEP, PAE+NX, ASLR, guard pages, user_range_ok hardened, sigreturn eflags sanitized, atomic file refcounts
+12. **Security** — SMEP, PAE+NX, ASLR, guard pages (user + kernel), user_range_ok hardened, sigreturn eflags sanitized, atomic file refcounts, VFS permission enforcement (uid/gid/euid/egid vs file mode)
13. **Scheduler** — O(1) with bitmap + active/expired, 32 priority levels, decay-based priority, CPU time accounting
14. **Threads** — `clone`, `gettid`, TLS via GDT, pthread in ulibc, futex synchronization
| Gap | Impact | Effort |
|-----|--------|--------|
| **ext2 filesystem** | No standard on-disk filesystem | Large |
-| **File-backed `mmap`** | Only anonymous/shm maps supported | Large |
| **Per-CPU scheduler runqueues** | SMP processes all run on BSP | Very Large |
| **SMAP** | Missing hardware security feature | Small |
| **Virtio-blk driver** | Only ATA PIO/DMA disk access | Medium |
14. ~~PAE + NX~~ ✅ Hardware W^X
15. ~~Networking (E1000 + lwIP + sockets)~~ ✅ TCP + UDP + DNS
16. ~~Threads (`clone`/`pthread`)~~ ✅ + futex
-17. ~~Permissions (`chmod`/`chown`/`access`/`umask`/`setuid`/`setgid`)~~ ✅
+17. ~~Permissions (`chmod`/`chown`/`access`/`umask`/`setuid`/`setgid`/`seteuid`/`setegid`/`getuid`/`getgid`/`geteuid`/`getegid` + VFS enforcement)~~ ✅
18. ~~Hard links~~ ✅ `diskfs_link()` with `nlink` tracking
19. ~~`pread`/`pwrite`/`readv`/`writev`~~ ✅
20. ~~`sigpending`/`sigsuspend`/`sigaltstack`~~ ✅
#### High Priority
1. **Full `ld.so`** — relocation processing for shared libraries
-2. **File-backed `mmap`** — map file contents into memory
-3. **ext2 filesystem** — standard on-disk filesystem
+2. **ext2 filesystem** — standard on-disk filesystem
#### Medium Priority
-4. **`getaddrinfo`** / `/etc/hosts` — userland name resolution
-5. **Per-CPU scheduler runqueues** — SMP scalability
-6. **`setitimer`/`getitimer`** — interval timers
-7. **SMAP** — Supervisor Mode Access Prevention
+3. **`getaddrinfo`** / `/etc/hosts` — userland name resolution
+4. **Per-CPU scheduler runqueues** — SMP scalability
+5. **`setitimer`/`getitimer`** — interval timers
+6. **SMAP** — Supervisor Mode Access Prevention
#### Long-Term
8. **Multi-arch bring-up** — ARM/RISC-V functional kernels
with ASLR and W^X, networking (TCP/UDP/DNS), futex synchronization, a POSIX shell with
core utilities, and a comprehensive ulibc with buffered I/O.
-It is approximately **90% of the way** to a practical POSIX-compatible system.
+It is approximately **93% of the way** to a practical POSIX-compatible system.
The supplementary material's architectural blueprints have been **fully realized and
exceeded**: CoW memory, O(1) scheduling, slab allocator, PCI enumeration, CPUID detection,
guard pages, SMEP).
The remaining gaps are primarily **shared library support** (full `ld.so` relocation
-processing), **file-backed mmap**, **ext2 filesystem**, and **SMP scheduler scalability**
-(per-CPU runqueues). These are non-trivial but well-defined engineering tasks.
+processing), **ext2 filesystem**, and **SMP scheduler scalability** (per-CPU runqueues).
+These are non-trivial but well-defined engineering tasks.
3. **Layer 4** (host unit tests) — catches logic bugs in pure functions
4. **Layer 3** (GDB scripted) — for deep debugging, lower priority
+## DOOM Smoke Test
+
+The DOOM port (`/bin/doom.elf`) serves as a heavyweight integration test:
+- Exercises `mmap` (fd-backed for `/dev/fb0`), `brk` (Z_Malloc heap), `nanosleep`, `clock_gettime`
+- Tests `/dev/fb0` ioctl (`FBIOGET_VSCREENINFO`, `FBIOGET_FSCREENINFO`) and framebuffer mmap
+- Tests `/dev/kbd` raw scancode reads (non-blocking)
+- Stresses the VFS, memory allocator, and process model simultaneously
+
+To run manually: boot AdrOS with `-vga std`, then execute `/bin/doom.elf` from the shell.
+
## Makefile Targets
```makefile