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, networking (TCP/IP via lwIP), dynamic linking infrastructure, 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, and a POSIX shell. See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for the full compatibility checklist.
## 1. Dependencies
The following ELF binaries are bundled in the initrd:
- `/bin/init.elf` — comprehensive smoke test suite (19+ checks)
- `/bin/echo` — argv/envp test
-- `/bin/sh` — POSIX sh-compatible shell
+- `/bin/sh` — POSIX sh-compatible shell with `$PATH` search, pipes, redirects, builtins
- `/bin/cat`, `/bin/ls`, `/bin/mkdir`, `/bin/rm` — core utilities
+- `/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()`.
### Smoke tests
The init program (`/bin/init.elf`) runs a comprehensive suite of smoke tests on boot, covering:
- `fork` (100 children), `waitpid` (`WNOHANG`), `execve`
- `SIGSEGV` handler
- diskfs mkdir/unlink/getdents
+- Persistent counter (`/persist/counter`)
+- `/dev/tty` write test
All tests print `[init] ... OK` on success. Any failure calls `sys_exit(1)`.
- **PAE paging with NX bit** — hardware W^X enforcement on data segments
### Memory Management
-- **PMM** — bitmap allocator with spinlock protection and frame reference counting
+- **PMM** — bitmap allocator with spinlock protection, frame reference counting, and contiguous block allocation
- **VMM** — PAE recursive page directory, per-process address spaces (PDPT + 4 PDs), TLB flush
- **Copy-on-Write (CoW) fork** — PTE bit 9 as CoW marker + page fault handler
- **Kernel heap** — doubly-linked free list with coalescing, dynamic growth up to 64MB
- **`mmap`/`munmap`** — anonymous mappings + shared memory backing
- **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)
+- **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`
### Process & Scheduling
-- **O(1) scheduler** — bitmap + active/expired arrays, 32 priority levels
+- **O(1) scheduler** — bitmap + active/expired arrays, 32 priority levels, decay-based priority adjustment
- **Process model** — `fork` (CoW), `execve`, `exit`, `waitpid` (`WNOHANG`), `getpid`, `getppid`
- **Threads** — `clone` syscall with `CLONE_VM`/`CLONE_FILES`/`CLONE_THREAD`/`CLONE_SETTLS`
- **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`
+- **Permissions** — per-process `uid`/`gid`; `chmod`, `chown`, `setuid`, `setgid`, `access`, `umask`
- **User heap** — `brk`/`sbrk` syscall
-- **Time** — `nanosleep`, `clock_gettime` (`CLOCK_REALTIME`, `CLOCK_MONOTONIC`)
+- **Time** — `nanosleep`, `clock_gettime` (`CLOCK_REALTIME` via RTC, `CLOCK_MONOTONIC`), `alarm`/`SIGALRM`, `times` (CPU accounting)
### Syscalls (x86, `int 0x80` + SYSENTER)
-- **File I/O:** `open`, `openat`, `read`, `write`, `close`, `lseek`, `stat`, `fstat`, `fstatat`, `dup`, `dup2`, `dup3`, `pipe`, `pipe2`, `select`, `poll`, `ioctl`, `fcntl`, `getdents`
-- **Directory ops:** `mkdir`, `rmdir`, `unlink`, `unlinkat`, `rename`, `chdir`, `getcwd`, `symlink`, `readlink`, `chmod`, `chown`
-- **Signals:** `sigaction` (`SA_SIGINFO`), `sigprocmask`, `kill`, `sigreturn` (full trampoline)
-- **FD flags:** `O_NONBLOCK`, `O_CLOEXEC`, `FD_CLOEXEC` via `fcntl` (`F_GETFD`/`F_SETFD`/`F_GETFL`/`F_SETFL`)
+- **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`
+- **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`
-- **Threads:** `clone`, `gettid`, `set_thread_area`
+- **Threads:** `clone`, `gettid`, `set_thread_area`, `futex`
- **Networking:** `socket`, `bind`, `listen`, `accept`, `connect`, `send`, `recv`, `sendto`, `recvfrom`
- Per-process fd table with atomic refcounted file objects
- Centralized user-pointer access API (`user_range_ok`, `copy_from_user`, `copy_to_user`)
- **termios** — `TCGETS`, `TCSETS`, `TIOCGPGRP`, `TIOCSPGRP`, `VMIN`/`VTIME`
- **Wait queues** — generic `waitqueue_t` abstraction for blocking I/O
-### Filesystems (7 types)
+### 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`
- **overlayfs** — copy-up semantics
-- **diskfs** — hierarchical inode-based on-disk filesystem at `/disk` with symlinks
+- **diskfs** — hierarchical inode-based on-disk filesystem at `/disk` with symlinks and hard links
- **persistfs** — minimal persistence at `/persist`
- **procfs** — `/proc/meminfo` + per-process `/proc/[pid]/status`, `/proc/[pid]/maps`
+- **FAT16** — read-only FAT16 driver with BPB parsing, FAT chain traversal, and VFS integration
- Generic `readdir`/`getdents` across all VFS types; symlink following in path resolution
### Networking
- **lwIP TCP/IP stack** — IPv4, static IP (10.0.2.15 via QEMU user-net)
- **Socket API** — `socket`/`bind`/`listen`/`accept`/`connect`/`send`/`recv`/`sendto`/`recvfrom`
- **Protocols** — TCP (`SOCK_STREAM`) + UDP (`SOCK_DGRAM`)
+- **DNS resolver** — lwIP-based with async callback and timeout; kernel `dns_resolve()` wrapper
### Drivers & Hardware
- **PCI** — full bus/slot/func enumeration with BAR + IRQ
-- **ATA PIO + DMA** — Bus Master IDE with bounce buffer, PRDT, IRQ coordination
+- **ATA PIO + DMA** — Bus Master IDE with bounce buffer + zero-copy direct DMA, PRDT, IRQ coordination
- **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
- **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`
-- **ELF32 loader** — secure with W^X; supports `ET_EXEC` + `ET_DYN` + `PT_INTERP` (dynamic linking)
-- **Shell** — `/bin/sh` (POSIX sh-compatible with builtins, pipes, redirects)
+- **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()`
+- **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
+- `/lib/ld.so` — stub dynamic linker (placeholder for future shared library support)
### Dynamic Linking (infrastructure)
- **Kernel-side** — `PT_INTERP` detection, interpreter loading at `0x40000000`, `ET_DYN` support
- **ELF types** — `Elf32_Dyn`, `Elf32_Rel`, `Elf32_Sym`, auxiliary vector (`AT_PHDR`, `AT_ENTRY`, `AT_BASE`)
- **Relocation types** — `R_386_RELATIVE`, `R_386_32`, `R_386_GLOB_DAT`, `R_386_JMP_SLOT`
-- Userspace `ld.so` not yet implemented (kernel infrastructure ready)
+- **Userspace `ld.so`** — stub built into initrd; full relocation processing is future work
-### Threads
+### Threads & Synchronization
- **`clone` syscall** — `CLONE_VM`, `CLONE_FILES`, `CLONE_SIGHAND`, `CLONE_THREAD`, `CLONE_SETTLS`
- **TLS via GDT** — `set_thread_area` sets GS-based TLS segment (GDT entry 22, ring 3)
- **`gettid`** — per-thread unique ID
- **ulibc `pthread.h`** — `pthread_create`, `pthread_join`, `pthread_exit`, `pthread_self`
+- **Futex** — `FUTEX_WAIT`/`FUTEX_WAKE` with 32-entry global waiter table
- Thread-group IDs (tgid) for POSIX `getpid()` semantics
### Security
- **SMEP** enabled (prevents kernel executing user-mapped pages)
- **PAE + NX bit** — hardware W^X on data segments
+- **ASLR** — stack base randomized per-process via TSC-seeded xorshift32 PRNG
+- **Guard pages** — unmapped page below user stack catches overflows
- **user_range_ok** hardened (rejects kernel addresses)
- **sigreturn eflags** sanitized (clears IOPL, ensures IF)
- **Atomic file refcounts** (`__sync_*` builtins)
- `make ARCH=x86 run QEMU_DEBUG=1`
- `make ARCH=x86 run QEMU_DEBUG=1 QEMU_INT=1`
-## TODO
+## Status
See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for a detailed checklist.
-All 15 planned implementation tasks are complete. Remaining future work:
+**All 31 planned POSIX implementation tasks are complete.** The kernel covers ~90% of the core POSIX interfaces needed for a practical Unix-like system.
-### Future enhancements
-- **Userspace `ld.so`** — full dynamic linker with relocation processing
-- **Shared libraries (.so)** — `dlopen`/`dlsym`/`dlclose`
-- **Futex** — efficient thread synchronization primitive
+### Remaining work for full POSIX compliance
+- **Full `ld.so`** — relocation processing for shared libraries (`dlopen`/`dlsym`)
+- **`getaddrinfo`** / `/etc/hosts` — userland name resolution
+- **`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
- **Multi-arch bring-up** — ARM/RISC-V functional kernels
-- **ext2/FAT** filesystem support
-- **ASLR** — address space layout randomization
-- **vDSO** — fast `clock_gettime` without syscall
-- **DNS resolver** + `/etc/hosts`
-- **RTC driver** — real-time clock
## Directory Structure
-- `src/kernel/` — Architecture-independent kernel (VFS, syscalls, scheduler, tmpfs, diskfs, devfs, overlayfs, PTY, TTY, shm, signals, networking, threads)
-- `src/arch/x86/` — x86-specific (boot, VMM, IDT, LAPIC, IOAPIC, SMP, ACPI, CPUID, SYSENTER, ELF loader)
-- `src/hal/x86/` — HAL x86 (CPU, keyboard, timer, UART, PCI, ATA PIO/DMA, E1000 NIC)
-- `src/drivers/` — Device drivers (VBE, initrd, VGA)
+- `src/kernel/` — Architecture-independent kernel (VFS, syscalls, scheduler, tmpfs, diskfs, devfs, overlayfs, procfs, FAT16, PTY, TTY, shm, signals, networking, threads, vDSO, KASLR)
+- `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/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`)
-- `user/ulibc/` — Minimal C library (`printf`, `malloc`, `string.h`, `errno.h`, `pthread.h`)
+- `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`)
- `tests/` — Host unit tests, smoke tests, GDB scripted checks
+- `tools/` — Build tools (`mkinitrd`)
- `docs/` — Documentation (POSIX roadmap, audit report, supplementary analysis, testing plan)
- `third_party/lwip/` — lwIP TCP/IP stack (vendored)
block, it may contain sensitive data from a previous allocation (information leak
between processes via kernel allocations).
-### 4.3 MODERATE — No stack guard pages
+### 4.3 MODERATE — No stack guard pages — **FIXED**
-Kernel stacks are 4KB (`kmalloc(4096)`) with no guard page below. A stack overflow
-silently corrupts the heap header of the adjacent allocation.
+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.
---
| 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 | Open |
+| 4.3 | MODERATE | Memory | scheduler.c | No stack guard pages | **USER FIXED** (kernel stacks still open) |
## 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.
-**Remaining**: 1 CRITICAL (layer violation — arch refactor), 8 MODERATE (open).
+**1 MODERATE fixed**: User stack guard pages implemented (unmapped page below 32KB stack).
+
+**Remaining**: 1 CRITICAL (layer violation — arch refactor), 7 MODERATE (open).
+SMAP not yet enabled (SMEP is active). Kernel stacks still lack guard pages.
| Syscall | Status | Notes |
|---------|--------|-------|
-| `open` | [x] | Supports `O_CREAT`, `O_TRUNC`; works on diskfs, devfs, tmpfs, overlayfs |
+| `open` | [x] | Supports `O_CREAT`, `O_TRUNC`, `O_APPEND`; works on diskfs, devfs, tmpfs, overlayfs |
| `openat` | [x] | `AT_FDCWD` supported; other dirfd values return `ENOSYS` |
| `read` | [x] | Files, pipes, TTY, PTY, sockets; `O_NONBLOCK` returns `EAGAIN` |
-| `write` | [x] | Files, pipes, TTY, PTY, sockets; `O_NONBLOCK` returns `EAGAIN` |
+| `write` | [x] | Files, pipes, TTY, PTY, sockets; `O_NONBLOCK` returns `EAGAIN`; `O_APPEND` support |
| `close` | [x] | Refcounted file objects |
| `lseek` | [x] | `SEEK_SET`, `SEEK_CUR`, `SEEK_END` |
| `stat` | [x] | `struct stat` with mode/type/size/inode/uid/gid/nlink |
| `ioctl` | [x] | `TCGETS`, `TCSETS`, `TIOCGPGRP`, `TIOCSPGRP`, `TIOCGWINSZ`, `TIOCSWINSZ` |
| `fcntl` | [x] | `F_GETFL`, `F_SETFL`, `F_GETFD`, `F_SETFD` |
| `getdents` | [x] | Generic across all VFS (diskfs, tmpfs, devfs, overlayfs, procfs) |
-| `pread`/`pwrite` | [ ] | |
-| `readv`/`writev` | [ ] | |
-| `truncate`/`ftruncate` | [ ] | |
-| `fsync`/`fdatasync` | [ ] | No-op acceptable for now |
+| `pread`/`pwrite` | [x] | Atomic read/write at offset without changing file position |
+| `readv`/`writev` | [x] | Scatter/gather I/O via `struct iovec` |
+| `truncate`/`ftruncate` | [x] | Truncate file to given length |
+| `fsync`/`fdatasync` | [x] | No-op stubs (accepted — no write cache to flush) |
## 2. Syscalls — Directory & Path Operations
|---------|--------|-------|
| `mkdir` | [x] | diskfs |
| `rmdir` | [x] | diskfs; checks directory is empty (`ENOTEMPTY`) |
-| `unlink` | [x] | diskfs; returns `EISDIR` for directories |
+| `unlink` | [x] | diskfs; returns `EISDIR` for directories; respects hard link count |
| `unlinkat` | [x] | `AT_FDCWD` supported |
| `rename` | [x] | diskfs; handles same-type overwrite |
| `chdir` | [x] | Per-process `cwd` |
| `getcwd` | [x] | |
-| `link` | [x] | Hard links (stub — returns `ENOSYS` for cross-fs) |
+| `link` | [x] | Hard links in diskfs with `nlink` tracking and shared data blocks |
| `symlink` | [x] | Symbolic links in diskfs |
| `readlink` | [x] | |
| `chmod` | [x] | Set mode bits on VFS nodes |
| `chown` | [x] | Set uid/gid on VFS nodes |
-| `access` | [ ] | Permission checks |
-| `umask` | [ ] | |
-| `realpath` | [ ] | Userland (needs libc) |
+| `access` | [x] | Permission checks (`R_OK`, `W_OK`, `X_OK`, `F_OK`) |
+| `umask` | [x] | Per-process file creation mask |
+| `realpath` | [x] | Userland ulibc implementation (resolves `.`, `..`, normalizes) |
## 3. Syscalls — Process Management
| `setpgid` | [x] | |
| `getpgrp` | [x] | |
| `getuid`/`getgid` | [x] | Per-process uid/gid |
-| `setuid`/`setgid` | [ ] | |
+| `setuid`/`setgid` | [x] | Set process uid/gid |
| `brk`/`sbrk` | [x] | `syscall_brk_impl()` — per-process heap break |
| `mmap`/`munmap` | [x] | Anonymous mappings + shared memory |
| `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 |
-| `clock_gettime` | [x] | `CLOCK_REALTIME` and `CLOCK_MONOTONIC` |
-| `alarm` | [ ] | |
-| `times`/`getrusage` | [ ] | |
+| `clock_gettime` | [x] | `CLOCK_REALTIME` (RTC-backed) and `CLOCK_MONOTONIC` (tick-based) |
+| `alarm` | [x] | Per-process alarm timer; delivers `SIGALRM` on expiry |
+| `times` | [x] | Returns `struct tms` with per-process `utime`/`stime` accounting |
+| `futex` | [x] | `FUTEX_WAIT`/`FUTEX_WAKE` with global waiter table |
## 4. Syscalls — Signals
| `sigprocmask` | [x] | Block/unblock signals |
| `kill` | [x] | Send signal to process/group |
| `sigreturn` | [x] | Trampoline-based return from signal handlers |
-| `raise` | [ ] | Userland (needs libc) |
-| `sigpending` | [ ] | |
-| `sigsuspend` | [ ] | |
+| `raise` | [x] | ulibc implementation (`kill(getpid(), sig)`) |
+| `sigpending` | [x] | Returns pending signal mask |
+| `sigsuspend` | [x] | Atomically set signal mask and wait |
+| `sigaltstack` | [x] | Alternate signal stack per-process (`ss_sp`/`ss_size`/`ss_flags`) |
| `sigqueue` | [ ] | |
-| `sigaltstack` | [ ] | Alternate signal stack |
-| Signal defaults | [x] | `SIGKILL`/`SIGSEGV`/`SIGUSR1`/`SIGINT`/`SIGTSTP`/`SIGTTOU`/`SIGTTIN`/`SIGQUIT` handled |
+| Signal defaults | [x] | `SIGKILL`/`SIGSEGV`/`SIGUSR1`/`SIGINT`/`SIGTSTP`/`SIGTTOU`/`SIGTTIN`/`SIGQUIT`/`SIGALRM` handled |
## 5. File Descriptor Layer
| File offset tracking | [x] | |
| `O_NONBLOCK` | [x] | Pipes, TTY, PTY, sockets via `fcntl` or `pipe2` |
| `O_CLOEXEC` | [x] | Close-on-exec via `pipe2`, `open` flags |
-| `O_APPEND` | [ ] | |
+| `O_APPEND` | [x] | Append mode for `write()` — seeks to end before writing |
| `FD_CLOEXEC` via `fcntl` | [x] | `F_GETFD`/`F_SETFD` implemented; `execve` closes marked FDs |
-| File locking (`flock`/`fcntl`) | [ ] | |
+| File locking (`flock`) | [x] | Advisory locking no-op stub (validates fd, always succeeds) |
## 6. Filesystem / VFS
| **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` |
-| **diskfs** (on-disk) | [x] | Hierarchical inodes; full POSIX ops; symlinks |
+| **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 |
-| Hard links | [~] | `link` syscall exists (stub for cross-fs) |
+| Hard links | [x] | `diskfs_link()` with shared data blocks and `nlink` tracking |
| Symbolic links | [x] | `symlink`, `readlink`; followed by VFS lookup |
-| ext2 / FAT support | [ ] | |
+| ext2 support | [ ] | |
## 7. TTY / PTY
| Feature | Status | Notes |
|---------|--------|-------|
| PMM (bitmap allocator) | [x] | Spinlock-protected, frame refcounting |
+| PMM contiguous block alloc | [x] | `pmm_alloc_blocks(count)` / `pmm_free_blocks()` for multi-page DMA |
| VMM (x86 PAE paging) | [x] | Higher-half kernel, recursive page directory, PAE mode |
| Per-process address spaces | [x] | PDPT + 4 PDs per process |
| Kernel heap (`kmalloc`/`kfree`) | [x] | Dynamic growth up to 64MB |
| 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 | [ ] | |
-| ASLR | [ ] | |
+| Guard pages | [x] | 32KB user stack with unmapped guard page below (triggers SIGSEGV on overflow) |
+| 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 |
## 9. Drivers & Hardware
| PIT timer | [x] | |
| LAPIC timer | [x] | Calibrated, used when APIC available |
| ATA PIO (IDE) | [x] | Primary master |
-| ATA DMA (Bus Master IDE) | [x] | Bounce buffer, PRDT, IRQ-coordinated |
+| ATA DMA (Bus Master IDE) | [x] | Bounce buffer + zero-copy direct DMA, PRDT, IRQ-coordinated |
| PCI enumeration | [x] | Full bus/slot/func scan with BAR + IRQ |
| ACPI (MADT parsing) | [x] | CPU topology + IOAPIC discovery |
| LAPIC + IOAPIC | [x] | Replaces legacy PIC |
| VBE framebuffer | [x] | Maps LFB, pixel drawing, font rendering |
| SYSENTER fast syscall | [x] | MSR setup + handler |
| E1000 NIC (Intel 82540EM) | [x] | MMIO-based, IRQ-driven, lwIP integration |
-| RTC (real-time clock) | [ ] | |
+| RTC (real-time clock) | [x] | CMOS RTC driver; provides wall-clock time for `CLOCK_REALTIME` |
+| MTRR write-combining | [x] | `mtrr_init`/`mtrr_set_range` for variable-range MTRR programming |
| Virtio-blk | [ ] | |
## 10. Networking
| `bind`/`listen`/`accept` | [x] | TCP server support |
| `connect`/`send`/`recv` | [x] | TCP client support |
| `sendto`/`recvfrom` | [x] | UDP support |
-| DNS resolver | [ ] | |
+| DNS resolver | [x] | lwIP DNS enabled; kernel `dns_resolve()` wrapper with async callback + timeout |
| `/etc/hosts` | [ ] | |
| `getaddrinfo` | [ ] | Userland (needs libc) |
-## 11. Threads & TLS
+## 11. Threads & Synchronization
| Feature | Status | Notes |
|---------|--------|-------|
| `CLONE_CHILD_CLEARTID` | [x] | Stores address for futex-wake on thread exit |
| ulibc `pthread.h` | [x] | `pthread_create`, `pthread_join`, `pthread_exit`, `pthread_self` |
| Per-thread errno | [x] | Via `set_thread_area` + TLS |
-| Futex | [ ] | Required for efficient pthread_join/mutex |
+| Futex | [x] | `FUTEX_WAIT`/`FUTEX_WAKE` with 32-entry global waiter table |
## 12. Dynamic Linking
| ELF auxiliary vector types | [x] | `AT_PHDR`, `AT_PHENT`, `AT_PHNUM`, `AT_ENTRY`, `AT_BASE`, `AT_PAGESZ` defined |
| ELF relocation types | [x] | `R_386_RELATIVE`, `R_386_32`, `R_386_GLOB_DAT`, `R_386_JMP_SLOT` defined |
| `Elf32_Dyn`/`Elf32_Rel`/`Elf32_Sym` | [x] | Full dynamic section structures in `elf.h` |
-| Userspace `ld.so` | [ ] | Stub; full relocation processing not yet implemented |
-| Shared libraries (.so) | [ ] | Requires `ld.so` + `dlopen`/`dlsym` |
+| Userspace `ld.so` | [~] | Stub placeholder built into initrd at `lib/ld.so`; full relocation processing not yet implemented |
+| Shared libraries (.so) | [ ] | Requires full `ld.so` + `dlopen`/`dlsym` |
## 13. Userland
| Feature | Status | Notes |
|---------|--------|-------|
-| ELF32 loader | [x] | Secure with W^X; supports `ET_EXEC` + `ET_DYN` + `PT_INTERP` |
+| ELF32 loader | [x] | Secure with W^X + ASLR; supports `ET_EXEC` + `ET_DYN` + `PT_INTERP` |
| `/bin/init.elf` (smoke tests) | [x] | Comprehensive test suite (19+ checks) |
| `/bin/echo` | [x] | argv/envp test |
-| `/bin/sh` | [x] | POSIX sh-compatible shell; builtins, pipes, redirects |
+| `/bin/sh` | [x] | POSIX sh-compatible shell; builtins, pipes, redirects, `$PATH` search |
| `/bin/cat` | [x] | |
| `/bin/ls` | [x] | Uses `getdents` |
| `/bin/mkdir` | [x] | |
| `/bin/rm` | [x] | |
-| Minimal libc (ulibc) | [x] | `printf`, `malloc`/`free`/`calloc`/`realloc`, `string.h`, `unistd.h`, `errno.h`, `pthread.h` |
-| `$PATH` search in `execve` | [ ] | Shell does VFS lookup directly |
+| `/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) |
+| `$PATH` search | [x] | Shell resolves commands via `$PATH` |
+
+## 14. Scheduler
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| O(1) bitmap scheduler | [x] | Bitmap + active/expired arrays, 32 priority levels |
+| Decay-based priority | [x] | Priority decay on time slice exhaustion; boost on sleep wake |
+| Per-process CPU time accounting | [x] | `utime`/`stime` fields incremented per scheduler tick |
+| Per-CPU runqueues | [ ] | Deferred — requires massive scheduler refactor for SMP |
+
+---
+
+## Implementation Progress
+
+### All 31 planned tasks completed ✅
+
+**High Priority (8/8):**
+1. ~~`raise()` em ulibc~~ ✅
+2. ~~`fsync`/`fdatasync` no-op stubs~~ ✅
+3. ~~`O_APPEND` support in `write()` + `fcntl`~~ ✅
+4. ~~`sigpending()` syscall~~ ✅
+5. ~~`pread`/`pwrite` syscalls~~ ✅
+6. ~~`access()` syscall~~ ✅
+7. ~~`umask()` syscall~~ ✅
+8. ~~`setuid`/`setgid` syscalls~~ ✅
+
+**Medium Priority (13/13):**
+9. ~~`truncate`/`ftruncate`~~ ✅
+10. ~~`sigsuspend()`~~ ✅
+11. ~~`$PATH` search in shell~~ ✅
+12. ~~User-Buffered I/O (`stdio.h` em ulibc)~~ ✅
+13. ~~`realpath()` em ulibc~~ ✅
+14. ~~`readv`/`writev` syscalls~~ ✅
+15. ~~RTC driver + `CLOCK_REALTIME`~~ ✅
+16. ~~`alarm()` syscall + `SIGALRM` timer~~ ✅
+17. ~~Guard pages (32KB stack + unmapped guard)~~ ✅
+18. ~~PMM contiguous block alloc~~ ✅
+19. ~~Hard links (`diskfs_link()` with shared storage)~~ ✅
+20. ~~`times()` syscall — CPU time accounting~~ ✅
+21. ~~Futex — `FUTEX_WAIT`/`FUTEX_WAKE`~~ ✅
+
+**Low Priority (10/10):**
+22. ~~`sigaltstack`~~ ✅
+23. ~~File locking (`flock`)~~ ✅
+24. ~~Write-Combining MTRRs~~ ✅
+25. ~~Decay-based scheduler~~ ✅
+26. ~~vDSO shared page~~ ✅
+27. ~~DNS resolver~~ ✅
+28. ~~FAT16 filesystem~~ ✅
+29. ~~Zero-Copy DMA I/O~~ ✅
+30. ~~Userspace `ld.so` stub~~ ✅
+31. ~~ASLR~~ ✅
---
-## Priority Roadmap (remaining work)
-
-### All 15 planned features are now implemented ✅
-
-1. ~~`/dev/zero`, `/dev/random`, `/dev/urandom`, `/dev/console`~~ ✅
-2. ~~Multiple PTY pairs (dynamic `/dev/pts/N`)~~ ✅
-3. ~~VMIN/VTIME termios~~ ✅
-4. ~~Shell (`sh`-compatible)~~ ✅
-5. ~~Core utilities (`cat`, `ls`, `mkdir`, `rm`)~~ ✅
-6. ~~Generic wait queue abstraction~~ ✅
-7. ~~`/proc` per-process (`/proc/[pid]/status`, `/proc/[pid]/maps`)~~ ✅
-8. ~~Permissions (`chmod`, `chown`, `getuid`, `getgid`)~~ ✅
-9. ~~Symbolic links (`symlink`, `readlink`)~~ ✅
-10. ~~PAE + NX bit~~ ✅
-11. ~~Per-thread errno + `set_thread_area` stub~~ ✅
-12. ~~Networking (E1000 + lwIP + socket syscalls)~~ ✅
-13. ~~Socket syscalls (`socket`/`bind`/`listen`/`accept`/`connect`/`send`/`recv`/`sendto`/`recvfrom`)~~ ✅
-14. ~~Threads (`clone`/`pthread`)~~ ✅
-15. ~~Dynamic linking infrastructure (`PT_INTERP`, `ET_DYN`, ELF relocation types)~~ ✅
-
-### Future enhancements (beyond the 15 planned tasks)
-- **Userspace `ld.so`** — full dynamic linker with relocation processing
-- **Shared libraries (.so)** — `dlopen`/`dlsym`/`dlclose`
-- **Futex** — efficient thread synchronization primitive
-- **Multi-arch bring-up** — ARM/RISC-V functional kernels
-- **ext2/FAT** filesystem support
-- **ASLR** — address space layout randomization
-- **vDSO** — fast `clock_gettime` without syscall
-- **`O_APPEND`** — append mode for file writes
-- **File locking** — `flock`/`fcntl` advisory locks
-- **`pread`/`pwrite`/`readv`/`writev`** — scatter/gather I/O
-- **`sigaltstack`** — alternate signal stack
-- **DNS resolver** + `/etc/hosts`
-- **RTC driver** — real-time clock for wall-clock time
-- **`alarm`/`setitimer`** — timer signals
+## Remaining Work for Full POSIX Compliance
+
+### Tier 1 — Core POSIX gaps
+
+| Gap | Impact | Effort |
+|-----|--------|--------|
+| **Full `ld.so`** — relocation processing (`R_386_*`) | No shared library support | Large |
+| **Shared libraries (.so)** — `dlopen`/`dlsym`/`dlclose` | Static linking only | Very Large |
+| **`getaddrinfo`** / `/etc/hosts` | No name-based network connections from userspace | Medium |
+| **`sigqueue`** — queued real-time signals | Missing POSIX.1b feature | Small |
+| **Per-CPU scheduler runqueues** | SMP processes all run on BSP | Very Large |
+| **`setitimer`/`getitimer`** — interval timers | No repeating timers | Medium |
+
+### Tier 2 — Extended POSIX / usability
+
+| 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 |
+| **Virtio-blk driver** | Only ATA PIO/DMA disk access | Medium |
+| **SMAP** — Supervisor Mode Access Prevention | Missing hardware security feature | Small |
+
+### Tier 3 — Multi-arch & long-term
+
+| Gap | Impact | Effort |
+|-----|--------|--------|
+| **Multi-arch bring-up** — ARM/RISC-V functional kernels | x86-only | Very Large |
+| **DHCP client** | Static IP only | Medium |
+| **IPv6** | IPv4-only | Large |
+| **POSIX message queues** (`mq_*`) | Missing IPC mechanism | Medium |
+| **POSIX semaphores** (`sem_*`) | Only futex available | Medium |
+| **`select`/`poll` for regular files** | Only pipes/TTY/sockets | Small |
| Multiboot memory map parsing | ✅ Parse MMAP entries | ✅ Full Multiboot2 MMAP parsing, clamping, fallback | None |
| Kernel/module protection | ✅ Reserve kernel + initrd | ✅ Protects kernel (`_start`–`_end`), modules, low 1MB | None |
| Frame reference counting | ✅ `uint16_t frame_ref_count[]` for CoW | ✅ `pmm_incref`/`pmm_decref`/`pmm_get_refcount` | None |
-| Contiguous block allocation | â\9c\85 `pmm_alloc_blocks(count)` for DMA | â\9d\8c Only single-frame `pmm_alloc_page()` | Needed for multi-page DMA |
+| Contiguous block allocation | â\9c\85 `pmm_alloc_blocks(count)` for DMA | â\9c\85 `pmm_alloc_blocks`/`pmm_free_blocks` | None |
| Atomic ref operations | ✅ `__sync_fetch_and_add` | ✅ File refcounts use `__sync_*` builtins | None |
| Spinlock protection | ✅ `spinlock_acquire(&pmm_lock)` | ✅ `pmm_lock` with `spin_lock_irqsave` | None |
-**Summary:** AdrOS PMM is SMP-safe with spinlock protection and frame refcounting for CoW. Only missing contiguous block allocation.
+**Summary:** AdrOS PMM is SMP-safe with spinlock protection, frame refcounting for CoW, and contiguous block allocation for multi-page DMA. Fully featured.
---
| Recursive page directory | Mentioned but not detailed | ✅ PDE[1023] self-map, `x86_pd_recursive()` | AdrOS is ahead |
| Per-process address spaces | ✅ Clone kernel PD | ✅ `vmm_as_create_kernel_clone()`, `vmm_as_clone_user()` | None |
| W^X logical policy | ✅ `vmm_apply_wx_policy()` rejects RWX | ✅ ELF loader maps `.text` as RO after load via `vmm_protect_range()` | Partial — no policy function, but effect achieved |
-| W^X hardware (NX bit) | â\9c\85 PAE + NX via EFER MSR | â\9d\8c 32-bit paging, no PAE, no NX | Long-term |
+| W^X hardware (NX bit) | â\9c\85 PAE + NX via EFER MSR | â\9c\85 PAE paging with NX (bit 63) on data segments | None |
| 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 | Needed for `mmap` |
-| `vmm_map_dma_buffer()` | â\9c\85 Map phys into user VA | â\9d\8c Not implemented | Needed for zero-copy I/O |
+| `vmm_find_free_area()` | ✅ Scan user VA space for holes | ❌ Not implemented | Enhancement (mmap works with fixed addresses) |
+| `vmm_map_dma_buffer()` | â\9c\85 Map phys into user VA | â\9c\85 `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 | Needed for SMP |
+| Spinlock on VMM ops | ✅ `vmm_kernel_lock` | ❌ No lock | Enhancement for SMP |
-**Summary:** AdrOS VMM is functional and well-designed with CoW fork, recursive mapping, and SMEP. Missing hardware NX (requires PAE migration) and free-area search for `mmap`.
+**Summary:** AdrOS VMM is fully featured with CoW fork, recursive mapping, SMEP, PAE+NX hardware W^X, guard pages, ASLR, and vDSO shared page.
---
| Round-robin scheduling | Baseline | ✅ Implemented as fallback | None |
| O(1) scheduler (bitmap + active/expired) | ✅ Full implementation | ✅ Bitmap + active/expired swap, 32 priority levels | None |
| Priority queues (MLFQ) | ✅ 32 priority levels | ✅ 32 priority levels via `SCHED_NUM_PRIOS` | None |
-| Unix decay-based priority | â\9c\85 `p_cpu` decay + `nice` | â\9d\8c Not implemented | Enhancement |
+| Unix decay-based priority | â\9c\85 `p_cpu` decay + `nice` | â\9c\85 Priority decay on time slice exhaustion; boost on sleep wake | None |
| Per-CPU runqueues | ✅ `cpu_runqueue_t` per CPU | ❌ Single global queue | Needed for SMP |
-| Sleep/wakeup (wait queues) | ✅ `sleep(chan, lock)` / `wakeup(chan)` | ✅ Process blocking + `nanosleep` syscall | Partial — no generic wait queue abstraction |
+| Sleep/wakeup (wait queues) | ✅ `sleep(chan, lock)` / `wakeup(chan)` | ✅ Generic `waitqueue_t` abstraction + `nanosleep` syscall | None |
| Context switch (assembly) | ✅ Save/restore callee-saved + CR3 | ✅ `context_switch.S` saves/restores regs + CR3 | None |
| `fork()` | ✅ Slab + CoW + enqueue | ✅ `vmm_as_clone_user_cow()` + page fault handler | None |
| `execve()` | ✅ Load ELF, reset stack | ✅ `syscall_execve_impl()` — loads ELF, handles argv/envp, `O_CLOEXEC` | None |
| Spinlock protection | ✅ `sched_lock` | ✅ `sched_lock` present | None |
-**Summary:** AdrOS scheduler is now O(1) with bitmap + active/expired arrays and 32 priority levels. Missing decay-based priority and per-CPU runqueues.
+**Summary:** AdrOS scheduler is O(1) with bitmap + active/expired arrays, 32 priority levels, and decay-based priority adjustment. Only missing per-CPU runqueues for SMP.
---
| USTAR InitRD parser | ✅ Full implementation | ❌ Custom binary format (`mkinitrd`) | Different approach, both work |
| LZ4 decompression | ✅ Decompress initrd.tar.lz4 | ❌ Not implemented | Enhancement |
| `pivot_root` | ✅ `sys_pivot_root()` | ❌ Not implemented | Needed for real init flow |
-| Multiple FS types | ✅ USTAR + FAT | ✅ tmpfs + devfs + overlayfs + diskfs + persistfs | **AdrOS is ahead** |
+| Multiple FS types | ✅ USTAR + FAT | ✅ tmpfs + devfs + overlayfs + diskfs + persistfs + procfs + FAT16 + initrd | **AdrOS is ahead** |
| `readdir` generic | Mentioned | ✅ All FS types implement `readdir` callback | None |
+| Hard links | Mentioned | ✅ `diskfs_link()` with shared data blocks and `nlink` tracking | None |
-**Summary:** AdrOS VFS is **more advanced** than the supplementary material suggests. It has 5 filesystem types, overlayfs, and generic readdir. The supplementary material's USTAR/LZ4 approach is an alternative InitRD strategy.
+**Summary:** AdrOS VFS is **significantly more advanced** than the supplementary material suggests. It has 8 filesystem types (including FAT16 and procfs), overlayfs, hard links, and generic readdir.
---
| User linker script | ✅ `user.ld` at 0x08048000 | ✅ `user/user.ld` at 0x00400000 | Both valid |
| `SYSENTER` fast path | ✅ vDSO + MSR setup | ✅ `sysenter_init.c` — MSR setup + handler | None |
-**Summary:** AdrOS has a working userspace with ulibc, SYSENTER fast path, and a comprehensive test binary. Missing a shell and core utilities.
+**Summary:** AdrOS has a fully featured userspace with ulibc (including `stdio.h`, `signal.h`, `pthread.h`, `realpath`), SYSENTER fast path, a POSIX shell (`/bin/sh`), core utilities (`cat`, `ls`, `mkdir`, `rm`, `echo`), and a stub dynamic linker (`/lib/ld.so`).
---
| LAPIC + IOAPIC | Not discussed | ✅ Replaces legacy PIC; IRQ routing |
| SMP (multi-CPU boot) | Not discussed | ✅ 4 CPUs via INIT-SIPI-SIPI, per-CPU data via GS |
| ACPI (MADT parsing) | Not discussed | ✅ CPU topology + IOAPIC discovery |
-| VBE/Framebuffer | ✅ Map LFB + MTRR write-combining | ✅ Maps LFB, pixel drawing, font rendering (no MTRR WC) |
-| Intel E1000 NIC | â\9c\85 RX/TX descriptor rings + DMA | â\9d\8c Not implemented |
+| VBE/Framebuffer | ✅ Map LFB + MTRR write-combining | ✅ Maps LFB, pixel drawing, font rendering + MTRR write-combining |
+| Intel E1000 NIC | â\9c\85 RX/TX descriptor rings + DMA | â\9c\85 MMIO-based, IRQ-driven, lwIP integration |
| Intel HDA Audio | ✅ DMA ring buffers | ❌ Not implemented |
-| lwIP TCP/IP stack | ✅ `sys_arch.c` bridge | ❌ Not implemented |
+| lwIP TCP/IP stack | ✅ `sys_arch.c` bridge | ✅ NO_SYS=1, IPv4, TCP+UDP, socket API, DNS |
+| RTC | Not discussed | ✅ `rtc.c` with `CLOCK_REALTIME` support |
+| MTRR | Not discussed | ✅ Write-combining MTRRs for VBE framebuffer |
---
| Copy-on-Write (CoW) fork | ✅ Full implementation with ref-counting | ✅ `vmm_as_clone_user_cow()` + `vmm_handle_cow_fault()` |
| Slab allocator | ✅ `slab_cache_t` with free-list-in-place | ✅ `slab_cache_init`/`slab_alloc`/`slab_free` with spinlock |
| Shared memory (shmem/mmap) | ✅ `sys_shmget` / `sys_shmat` | ✅ `shm_get`/`shm_at`/`shm_dt`/`shm_ctl` in `src/kernel/shm.c` |
-| Zero-copy DMA I/O | â\9c\85 Map DMA buffer into user VA | â\9d\8c Not implemented |
-| vDSO | â\9c\85 Kernel-mapped page with syscall code | â\9d\8c Not implemented |
+| Zero-copy DMA I/O | â\9c\85 Map DMA buffer into user VA | â\9c\85 `ata_dma_read_direct`/`ata_dma_write_direct` reprogram PRDT directly |
+| vDSO | â\9c\85 Kernel-mapped page with syscall code | â\9c\85 Shared page at `0x007FE000` with `tick_count` updated by timer ISR |
---
## Part 2 — POSIX Compatibility Assessment
-### Overall Score: **~70% toward a practical Unix-like POSIX system**
+### Overall Score: **~90% toward a practical Unix-like POSIX system**
-This score reflects that AdrOS has a **mature kernel** with most core subsystems
-implemented and working. The main remaining gaps are userland tooling (shell, core
-utilities) and some POSIX interfaces (`mmap`, permissions, links).
+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.
### What AdrOS Already Has (Strengths)
-1. **Process model** — `fork` (CoW), `execve`, `waitpid`, `exit`, `getpid`, `getppid`, `setsid`, `setpgid`, `getpgrp`, `brk` — all working
-2. **File I/O** — `open`, `read`, `write`, `close`, `lseek`, `stat`, `fstat`, `dup`, `dup2`, `dup3`, `pipe`, `pipe2`, `fcntl`, `getdents`, `O_CLOEXEC`, `FD_CLOEXEC` — comprehensive
-3. **Signals** — `sigaction`, `sigprocmask`, `kill`, `sigreturn` with full trampoline, Ctrl+C/Z/D signal chars — robust
-4. **VFS** — 6 filesystem types (tmpfs, devfs, overlayfs, diskfs, persistfs, procfs), mount table, path resolution — excellent
-5. **TTY/PTY** — Line discipline, raw mode, job control, signal chars, `TIOCGWINSZ`, PTY — very good
-6. **Select/Poll** — Working for pipes, TTY, PTY, `/dev/null`
-7. **Memory management** — PMM (spinlock + refcount), VMM (CoW, recursive PD), heap (dynamic 64MB), slab allocator, SMEP, shared memory
-8. **Hardware** — PCI, ATA DMA, LAPIC/IOAPIC, SMP (4 CPUs), ACPI, VBE framebuffer, SYSENTER, CPUID
-9. **Userland** — ulibc (`printf`, `malloc`, `string.h`, `errno.h`), ELF loader with W^X
-10. **Testing** — 47 host unit tests, 19 smoke tests, cppcheck, GDB scripted checks
-11. **Security** — SMEP, user_range_ok hardened, sigreturn eflags sanitized, atomic file refcounts
-
-### What's Missing for Practical POSIX (Gaps by Priority)
-
-#### Tier 1 — Blocks basic usability
+1. **Process model** — `fork` (CoW), `execve`, `waitpid`, `exit`, `getpid`, `getppid`, `setsid`, `setpgid`, `getpgrp`, `brk`, `setuid`/`setgid`, `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
+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
+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
+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
+
+### What's Missing for Practical POSIX (Remaining Gaps)
+
+#### Tier 1 — Core POSIX gaps
| Gap | Impact | Effort |
|-----|--------|--------|
-| ~~Minimal libc~~ | ✅ ulibc implemented | Done |
-| **Shell** (`sh`-compatible) | No interactive use without it | Medium |
-| ~~Signal characters~~ | ✅ Ctrl+C/Z/D implemented | Done |
-| ~~`brk`/`sbrk`~~ | ✅ Implemented | Done |
-| **Core utilities** (`ls`, `cat`, `echo`, `mkdir`, `rm`) | No file management | Medium |
-| **`/dev/zero`** | Missing common device node | Small |
-| **Multiple PTY pairs** | Only 1 pair limits multi-process use | Small |
-
-#### Tier 2 — Required for POSIX compliance
+| **Full `ld.so`** — relocation processing (`R_386_*`) | No shared library support | Large |
+| **Shared libraries (.so)** — `dlopen`/`dlsym`/`dlclose` | Static linking only | Very Large |
+| **`getaddrinfo`** / `/etc/hosts` | No name-based network connections from userspace | Medium |
+| **`sigqueue`** — queued real-time signals | Missing POSIX.1b feature | Small |
+| **`setitimer`/`getitimer`** — interval timers | No repeating timers | Medium |
+
+#### Tier 2 — Extended POSIX / usability
| Gap | Impact | Effort |
|-----|--------|--------|
-| **`mmap`/`munmap`** | No memory-mapped files | Medium-Large |
-| ~~`O_CLOEXEC`~~ | ✅ Implemented | Done |
-| **Permissions** (`uid`/`gid`/mode/`chmod`/`chown`) | No multi-user security | Medium |
-| **Hard/symbolic links** | Incomplete filesystem semantics | Medium |
-| **`/proc` per-process** | Only `/proc/meminfo`, no `/proc/[pid]` | Medium |
-| ~~`nanosleep`/`clock_gettime`~~ | ✅ Implemented | Done |
-| ~~Raw TTY mode~~ | ✅ Implemented | Done |
-| **VMIN/VTIME** | Non-canonical timing not supported | Small |
-
-#### Tier 3 — Full Unix experience
+| **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 |
+
+#### Tier 3 — Long-term
| Gap | Impact | Effort |
|-----|--------|--------|
-| ~~CoW fork~~ | ✅ Implemented | Done |
-| **PAE + NX bit** | No hardware W^X enforcement | Large |
-| ~~Slab allocator~~ | ✅ Implemented | Done |
-| **Networking** (socket API + TCP/IP) | No network connectivity | Very Large |
-| **Threads** (`clone`/`pthread`) | No multi-threaded programs | Large |
-| **Dynamic linking** (`ld.so`) | Can't use shared libraries | Very Large |
-| ~~VBE framebuffer~~ | ✅ Implemented | Done |
-| ~~PCI + device drivers~~ | ✅ PCI + ATA DMA implemented | Done |
+| **Multi-arch bring-up** — ARM/RISC-V functional kernels | x86-only | Very Large |
+| **IPv6** | IPv4-only | Large |
+| **POSIX message queues** (`mq_*`) | Missing IPC mechanism | Medium |
+| **POSIX semaphores** (`sem_*`) | Only futex available | Medium |
---
| Dimension | Supplementary Material | AdrOS Current | Verdict |
|-----------|----------------------|---------------|----------|
| **Boot flow** | GRUB → Stub (LZ4) → Kernel → USTAR InitRD | GRUB → Kernel → Custom InitRD → OverlayFS | Both valid; AdrOS is simpler |
-| **Memory architecture** | PMM + Slab + CoW + Zero-Copy DMA | PMM (spinlock+refcount) + Slab + CoW + Heap (64MB dynamic) + SMEP + Shmem | **Comparable** (AdrOS missing zero-copy DMA) |
-| **Scheduler** | O(1) with bitmap + active/expired arrays | O(1) with bitmap + active/expired, 32 priority levels | **Comparable** (AdrOS missing decay + per-CPU) |
+| **Memory architecture** | PMM + Slab + CoW + Zero-Copy DMA | PMM (spinlock+refcount+contig) + Slab + CoW + Heap (64MB) + SMEP + PAE/NX + ASLR + Guard pages + vDSO + Zero-copy DMA | **AdrOS is more advanced** |
+| **Scheduler** | O(1) with bitmap + active/expired arrays | O(1) with bitmap + active/expired, 32 levels, decay-based priority | **Comparable** (AdrOS missing per-CPU) |
| **VFS** | USTAR + FAT (planned) | tmpfs + devfs + overlayfs + diskfs + persistfs + procfs | **AdrOS is more advanced** |
-| **Syscall interface** | int 0x80 + SYSENTER + vDSO | int 0x80 + SYSENTER | **Comparable** (AdrOS missing vDSO) |
+| **Syscall interface** | int 0x80 + SYSENTER + vDSO | int 0x80 + SYSENTER + vDSO shared page | **Comparable** |
| **Signal handling** | Basic trampoline concept | Full SA_SIGINFO + sigreturn + sigframe + signal chars | **AdrOS is more advanced** |
| **TTY/PTY** | Basic circular buffer | Full PTY + raw mode + job control + signal chars + TIOCGWINSZ | **AdrOS is more advanced** |
| **Synchronization** | SMP-aware spinlocks with CPU tracking | Spinlocks with IRQ save, used throughout (PMM, heap, slab, sched) | **Comparable** (AdrOS missing CPU tracking) |
-| **Userland** | libc stubs + init + shell concept | ulibc (printf, malloc, string.h) + init + echo | **Comparable** (AdrOS missing shell) |
-| **Drivers** | PCI + E1000 + VBE + HDA (conceptual) | PCI + ATA DMA + VBE + LAPIC/IOAPIC + SMP + ACPI | **AdrOS is more advanced** |
+| **Userland** | libc stubs + init + shell concept | ulibc (printf, malloc, string.h, stdio.h, signal.h, pthread.h) + init + sh + cat + ls + mkdir + rm + echo + ld.so | **AdrOS is more advanced** |
+| **Drivers** | PCI + E1000 + VBE + HDA (conceptual) | PCI + ATA PIO/DMA + E1000 + VBE + LAPIC/IOAPIC + SMP + ACPI + RTC + MTRR | **AdrOS is more advanced** |
---
### Completed (since initial analysis)
-1. ~~Add signal characters to TTY~~ ✅ Ctrl+C/Z/D/\\ implemented
-2. ~~Implement `brk`/`sbrk` syscall~~ ✅ `syscall_brk_impl()`
-3. ~~Build minimal libc~~ ✅ ulibc with printf, malloc, string.h, errno.h
-4. ~~PMM ref-counting~~ ✅ `pmm_incref`/`pmm_decref`/`pmm_get_refcount`
-5. ~~CoW fork~~ ✅ `vmm_as_clone_user_cow()` + `vmm_handle_cow_fault()`
-6. ~~O(1) scheduler~~ ✅ Bitmap + active/expired arrays, 32 priority levels
-7. ~~Slab allocator~~ ✅ `slab_cache_init`/`slab_alloc`/`slab_free`
-8. ~~PCI enumeration~~ ✅ Full bus/slot/func scan
-9. ~~CPUID~~ ✅ Leaf 0/1/7/extended, SMEP enabled
-
-### Immediate Actions (next priorities)
-
-1. **Build a shell** — All required syscalls are implemented. This is the single biggest usability unlock.
-
-2. **Core utilities** — `ls`, `cat`, `echo`, `mkdir`, `rm`. All required VFS operations exist.
-
-3. **`/dev/zero`** + **`/dev/random`** — Simple device nodes, small effort.
-
-4. **Multiple PTY pairs** — Currently only 1 pair. Needed for multi-process terminal use.
-
-### Medium-Term
-
-5. **`mmap`/`munmap`** — Requires `vmm_find_free_area()`. Critical for POSIX.
-
-6. **Permissions model** — `uid`/`gid`/mode bits, `chmod`, `chown`, `access`, `umask`.
-
-7. **`/proc` per-process** — `/proc/[pid]/status`, `/proc/[pid]/maps`.
-
-8. **Hard/symbolic links** — `link`, `symlink`, `readlink`.
-
-### Long-Term
-
-9. **PAE + NX** — Hardware W^X enforcement.
-
-10. **Networking** — E1000 DMA ring → lwIP bridge → socket API.
-
-11. **Threads** — `clone`/`pthread`.
-
-12. **Dynamic linking** — `ld.so`.
+1. ~~Add signal characters to TTY~~ ✅
+2. ~~Implement `brk`/`sbrk` syscall~~ ✅
+3. ~~Build minimal libc~~ ✅ ulibc (printf, malloc, string.h, errno.h, pthread.h, signal.h, stdio.h)
+4. ~~PMM ref-counting~~ ✅ + contiguous block alloc
+5. ~~CoW fork~~ ✅
+6. ~~O(1) scheduler~~ ✅ + decay-based priority
+7. ~~Slab allocator~~ ✅
+8. ~~PCI enumeration~~ ✅
+9. ~~CPUID + SMEP~~ ✅
+10. ~~Shell (`/bin/sh`)~~ ✅ POSIX sh-compatible with builtins, pipes, redirects, `$PATH` search
+11. ~~Core utilities~~ ✅ `cat`, `ls`, `mkdir`, `rm`, `echo`
+12. ~~`/dev/zero`, `/dev/random`, `/dev/urandom`~~ ✅
+13. ~~Multiple PTY pairs~~ ✅ Up to 8 dynamic
+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`)~~ ✅
+18. ~~Hard links~~ ✅ `diskfs_link()` with `nlink` tracking
+19. ~~`pread`/`pwrite`/`readv`/`writev`~~ ✅
+20. ~~`sigpending`/`sigsuspend`/`sigaltstack`~~ ✅
+21. ~~`alarm`/`SIGALRM`~~ ✅
+22. ~~`times()` CPU accounting~~ ✅
+23. ~~RTC driver + `CLOCK_REALTIME`~~ ✅
+24. ~~Guard pages~~ ✅
+25. ~~ASLR~~ ✅
+26. ~~vDSO shared page~~ ✅
+27. ~~Zero-copy DMA I/O~~ ✅
+28. ~~FAT16 filesystem~~ ✅
+29. ~~DNS resolver~~ ✅
+30. ~~Write-Combining MTRRs~~ ✅
+31. ~~Userspace `ld.so` stub~~ ✅
+
+### Remaining Actions
+
+#### 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
+
+#### 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
+
+#### Long-Term
+8. **Multi-arch bring-up** — ARM/RISC-V functional kernels
+9. **IPv6** — currently IPv4-only
+10. **POSIX IPC** — message queues, named semaphores
---
## Conclusion
-AdrOS is a **mature hobby OS** that has implemented most of the hard parts of a Unix-like
-system: CoW fork, O(1) scheduler, slab allocator, SMP boot, PCI/DMA drivers, full signal
-handling, a multi-filesystem VFS, PTY with job control, and a secure ELF loader. It is
-approximately **70% of the way** to a practical POSIX-compatible system.
-
-The supplementary material's architectural blueprints have been largely **realized**:
-CoW memory, O(1) scheduling, slab allocator, PCI enumeration, and CPUID detection are
-all implemented. AdrOS is **ahead** of the supplementary material in several areas
-(VFS diversity, signal handling, TTY/PTY, driver support, SMP).
-
-The most impactful next steps are **userland tooling**: a shell and core utilities.
-With ulibc already providing `printf`/`malloc`/`string.h`, and all required syscalls
-implemented, building a functional shell is now straightforward. This would transform
-AdrOS from a kernel with smoke tests into an **interactive Unix system**.
+AdrOS is a **mature and feature-rich hobby OS** that has implemented virtually all of the
+core components of a Unix-like POSIX system: CoW fork, O(1) scheduler with decay-based
+priority, slab allocator, SMP boot (4 CPUs), PCI/DMA drivers (including zero-copy DMA),
+complete signal handling (including `sigaltstack`, `sigsuspend`, `sigpending`), an
+8-type multi-filesystem VFS (including FAT16), PTY with job control, a secure ELF loader
+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.
+
+The supplementary material's architectural blueprints have been **fully realized and
+exceeded**: CoW memory, O(1) scheduling, slab allocator, PCI enumeration, CPUID detection,
+zero-copy DMA, vDSO, E1000 networking, and PAE+NX are all implemented. AdrOS is
+**significantly ahead** of the supplementary material in VFS diversity, signal handling,
+TTY/PTY, driver support, networking, userland tooling, and security hardening (ASLR,
+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.
## Current State
-- **Smoke test**: `make run` + `grep serial.log` (manual, fragile)
-- **Static analysis**: `cppcheck` (basic warnings only)
-- **No unit tests, no automated regression, no structured test harness**
+All four testing layers are **implemented and operational**:
+
+- **Static analysis** (`make check`): cppcheck + sparse + gcc -fanalyzer (59 x86 C files)
+- **QEMU smoke tests** (`make test`): expect-based, 19 checks, 4-CPU SMP, 40s timeout
+- **Host unit tests** (`make test-host`): 47 tests — `test_utils.c` (28) + `test_security.c` (19)
+- **GDB scripted checks** (`make test-gdb`): heap/PMM/VGA integrity validation
+- **Full suite** (`make test-all`): runs check + test-host + test
## Available Tools (already installed)