]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
docs: update README, BUILD_GUIDE, and POSIX_ROADMAP to reflect current state
authorTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 02:16:07 +0000 (23:16 -0300)
committerTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 02:16:07 +0000 (23:16 -0300)
BUILD_GUIDE.md
README.md
docs/POSIX_ROADMAP.md

index 6008f82ffa6e6ee7476a1d2412339fbff0f60ffd..4fa08201c0d33d7626eaf46dbcfd3878b6dc3fe8 100644 (file)
@@ -2,6 +2,8 @@
 
 This guide explains how to build and run AdrOS on your local machine (Linux/WSL).
 
+AdrOS is a Unix-like, POSIX-compatible OS kernel. See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for the full compatibility checklist.
+
 ## 1. Dependencies
 
 You will need:
@@ -9,14 +11,15 @@ You will need:
 - `qemu-system-*` (emulators)
 - `xorriso` (to create bootable ISOs)
 - `grub-pc-bin` and `grub-common` (x86 bootloader)
-- Cross-compilers for ARM/RISC-V
+- Cross-compilers for ARM/RISC-V (optional, for non-x86 targets)
+- `cppcheck` (optional, for static analysis)
 
 ### On Ubuntu/Debian:
 ```bash
 sudo apt update
 sudo apt install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo \
     qemu-system-x86 qemu-system-arm qemu-system-misc \
-    grub-common grub-pc-bin xorriso mtools \
+    grub-common grub-pc-bin xorriso mtools cppcheck \
     gcc-aarch64-linux-gnu gcc-riscv64-linux-gnu
 ```
 
@@ -51,7 +54,10 @@ make ARCH=x86 run
 
 Persistent storage note:
 - The x86 QEMU run target attaches a `disk.img` file as an IDE drive (primary master).
-- `/persist` is mounted from this disk and is used by userspace smoke tests (e.g. `/persist/counter`).
+- The kernel mounts two filesystems from this disk:
+  - `/persist` — minimal persistence filesystem (e.g. `/persist/counter`)
+  - `/disk` — hierarchical inode-based filesystem (diskfs) supporting `mkdir`, `unlink`, `rmdir`, `rename`, `getdents`, etc.
+- If `disk.img` does not exist, it is created automatically by the Makefile.
 
 If you are iterating on kernel changes and want to avoid hanging runs, you can wrap it with a timeout:
 ```bash
@@ -64,7 +70,27 @@ Generated outputs/artifacts:
 
 Syscall return convention note:
 - The kernel follows a Linux-style convention: syscalls return `0`/positive values on success, and `-errno` (negative) on failure.
-- A libc-style `errno` variable (per-thread) is not implemented yet.
+- Userland (`user/init.c`) uses a `__syscall_fix()` helper that converts negative returns to `-1` and sets a global `errno`.
+- A full libc-style per-thread `errno` is not yet implemented.
+
+### Userland smoke tests
+The init program (`/bin/init.elf`) runs a comprehensive suite of smoke tests on boot, covering:
+- File I/O (`open`, `read`, `write`, `close`, `lseek`, `stat`, `fstat`)
+- Overlay copy-up, `dup2`, `pipe`, `select`, `poll`
+- TTY/ioctl, job control (`SIGTTIN`/`SIGTTOU`)
+- PTY (`/dev/ptmx` + `/dev/pts/0`)
+- Signals (`sigaction`, `kill`, `sigreturn`)
+- Session/process groups (`setsid`, `setpgid`, `getpgrp`)
+- `isatty`, `O_NONBLOCK` (pipes + PTY), `fcntl`
+- `pipe2`/`dup3` with flags
+- `chdir`/`getcwd` with relative path resolution
+- `openat`/`fstatat`/`unlinkat` (`AT_FDCWD`)
+- `rename`, `rmdir`
+- `getdents` across multiple FS types (diskfs, devfs, tmpfs)
+- `fork` (100 children), `waitpid` (`WNOHANG`), `execve`
+- `SIGSEGV` handler
+
+All tests print `[init] ... OK` on success. Any failure calls `sys_exit(1)`.
 
 Static analysis helper:
 ```bash
index 5c35a938495a1149241b3a56c15c2b71949d3385..695743bef79712006b047b3ee124fbd6f004222a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # AdrOS
 
 ## Overview
-AdrOS is a multi-architecture operating system developed for research and academic purposes. The goal is to build a secure, monolithic kernel from scratch, eventually serving as a platform for security testing and exploit development.
+AdrOS is a Unix-like, POSIX-compatible, multi-architecture operating system developed for research and academic purposes. The goal is to build a secure, monolithic kernel from scratch, eventually serving as a platform for security testing and exploit development.
 
 ## Architectures Targeted
 - **x86** (32-bit & 64-bit)
@@ -42,18 +42,17 @@ AdrOS is a multi-architecture operating system developed for research and academ
   - InitRD-backed filesystem node tree (`fs_node_t` + `finddir`)
   - Absolute path lookup (`vfs_lookup("/bin/init.elf")`)
   - Mount table support (`vfs_mount`) + `tmpfs` and `overlayfs`
-- **File descriptors + syscalls (x86)**
-  - `int 0x80` syscall gate
-  - `SYSCALL_WRITE`, `SYSCALL_EXIT`, `SYSCALL_GETPID`, `SYSCALL_GETPPID`, `SYSCALL_OPEN`, `SYSCALL_READ`, `SYSCALL_CLOSE`
-  - `SYSCALL_LSEEK`, `SYSCALL_STAT`, `SYSCALL_FSTAT`
-  - `SYSCALL_DUP`, `SYSCALL_DUP2`, `SYSCALL_PIPE`
-  - `SYSCALL_FORK`, `SYSCALL_EXECVE` (with minimal argv/envp stack setup)
-  - `SYSCALL_SELECT`, `SYSCALL_POLL`
-  - `SYSCALL_SIGACTION`, `SYSCALL_SIGPROCMASK`, `SYSCALL_KILL`
-  - `SYSCALL_SETSID`, `SYSCALL_SETPGID`, `SYSCALL_GETPGRP`
-  - Per-process fd table (starting at fd=3)
+- **Syscalls (x86, `int 0x80`)**
+  - **File I/O:** `open`, `openat`, `read`, `write`, `close`, `lseek`, `stat`, `fstat`, `fstatat`, `dup`, `dup2`, `dup3`, `pipe`, `pipe2`, `select`, `poll`, `ioctl`, `fcntl`
+  - **Directory ops:** `mkdir`, `rmdir`, `unlink`, `unlinkat`, `rename`, `getdents`, `chdir`, `getcwd`
+  - **Process:** `fork`, `execve`, `exit`, `waitpid` (incl. `WNOHANG`), `getpid`, `getppid`, `setsid`, `setpgid`, `getpgrp`
+  - **Signals:** `sigaction`, `sigprocmask`, `kill`, `sigreturn` (trampoline-based return path)
+  - **Modern POSIX:** `openat`/`fstatat`/`unlinkat` (`AT_FDCWD`), `dup3`, `pipe2` (with `O_NONBLOCK` flags)
+  - Per-process fd table with refcounted file objects
+  - Per-process current working directory (`cwd`) with relative path resolution
+  - Non-blocking I/O (`O_NONBLOCK`) on pipes, TTY, and PTY via `fcntl`
   - Centralized user-pointer access API (`user_range_ok`, `copy_from_user`, `copy_to_user`)
-  - Ring3 init program (`/bin/init.elf`) exercising IO + process + exec smoke tests
+  - Ring3 init program (`/bin/init.elf`) with comprehensive smoke tests
   - Error returns use negative errno codes (Linux-style)
 - **TTY (canonical line discipline)**
   - Keyboard -> TTY input path
@@ -64,12 +63,21 @@ AdrOS is a multi-architecture operating system developed for research and academ
   - Minimal termios/ioctl support (`TCGETS`, `TCSETS`, `TIOCGPGRP`, `TIOCSPGRP`)
   - Basic job control enforcement (`SIGTTIN`/`SIGTTOU` when background pgrp touches the controlling TTY)
 - **Devices (devfs)**
-  - `/dev` mount
-  - `/dev/null`
-  - `/dev/tty`
-- **Persistent storage (x86 / QEMU)**
+  - `/dev` mount with `readdir` support
+  - `/dev/null`, `/dev/tty`
+  - `/dev/ptmx` + `/dev/pts/0` (pseudo-terminal)
+- **PTY subsystem**
+  - PTY master/slave pair (`/dev/ptmx` + `/dev/pts/0`)
+  - Non-blocking I/O support
+  - Used by userland smoke tests
+- **On-disk filesystem (diskfs)**
   - ATA PIO driver (primary master IDE)
-  - Minimal on-disk persistence filesystem mounted at `/persist` (single `counter` file used by smoke tests)
+  - Hierarchical inode-based filesystem mounted at `/disk`
+  - Supports: `open` (create/truncate), `read`, `write`, `stat`, `mkdir`, `unlink`, `rmdir`, `rename`, `getdents`
+  - Persistence filesystem mounted at `/persist` (smoke tests)
+- **Generic `readdir`/`getdents` across all VFS**
+  - Works on diskfs, tmpfs, devfs, and overlayfs
+  - Unified `struct vfs_dirent` format
 - **W^X (Option 1) for user ELFs (x86)**
   - User segments are mapped RW during load, then write permissions are dropped for non-writable segments
   - This provides "text is read-only" hardening without requiring NX/PAE
@@ -86,34 +94,43 @@ QEMU debug helpers:
 - `make ARCH=x86 run QEMU_DEBUG=1 QEMU_INT=1`
 
 ## TODO
+
+See [POSIX_ROADMAP.md](docs/POSIX_ROADMAP.md) for a detailed checklist.
+
+- **Syscalls / POSIX gaps**
+  - `brk`/`sbrk` (heap management)
+  - `mmap`/`munmap` (memory-mapped I/O)
+  - `access`, `chmod`, `chown`, `umask` (permissions)
+  - `link`, `symlink`, `readlink` (hard/symbolic links)
+  - `truncate`/`ftruncate`
+  - `socket`/`bind`/`listen`/`accept`/`connect`/`send`/`recv` (networking)
+  - Userspace `errno` variable + libc-style wrappers
+- **Filesystem**
+  - Permissions/ownership (`uid/gid`, mode bits)
+  - `/proc` filesystem
+  - Real on-disk FS (ext2/FAT) as alternative to diskfs
+- **TTY / terminal**
+  - Full termios flags (raw mode, VMIN/VTIME, signal chars)
+  - Multiple PTY pairs
+- **Virtual memory hardening**
+  - PAE + NX enforcement (execute disable for data/stack)
+  - Guard pages, ASLR
 - **Multi-architecture kernel bring-up**
   - Implement VMM/interrupts/scheduler for ARM/RISC-V/MIPS
-  - Standardize arch entrypoint behavior (`arch_early_setup`) across architectures
-- **Userspace / POSIX process model**
-  - `brk`/`sbrk`
-  - Signal return ABI (`sigreturn`) and default actions for more signals (current support is minimal)
-- **Syscalls / ABI**
-  - `getcwd`, `chdir`
-  - Userspace `errno` variable + libc-style wrappers (`-1` return + `errno` set)
-- **Virtual memory hardening**
-  - Option 2: PAE + NX enforcement (execute disable for data/stack)
-  - Guard pages, and tighter user/kernel separation checks
-- **Filesystem**
-  - Expand persisted storage beyond the current minimal `/persist` filesystem
-  - Permissions/ownership (`uid/gid`, mode bits) and `umask`
-  - Special files: block devices, `/proc`
-  - Real on-disk fs (ext2/fat)
-- **TTY / PTY**
-  - Termios-like mode flags (canonical/raw, echo, erase, intr)
-  - Sessions / process groups / controlling terminal
-  - PTYs for userland shells
+- **Userland**
+  - Minimal libc (`printf`, `malloc`, `string.h`, etc.)
+  - Shell (sh-compatible)
+  - Core utilities (`ls`, `cat`, `cp`, `mv`, `rm`, `echo`, `mkdir`)
 - **Observability & tooling**
-  - Better memory stats (`mem` shell command)
-  - Debug facilities (panic backtraces, symbolization, structured logs)
-  - CI-ish targets: `cppcheck`, `scan-build`, `mkinitrd-asan`
+  - Panic backtraces, symbolization
+  - CI pipeline with `cppcheck`, `scan-build`
 
 ## Directory Structure
-- `src/kernel/` - Architecture-independent kernel code
-- `src/arch/` - Architecture-specific code (boot, context switch, interrupts)
-- `src/drivers/` - Device drivers
+- `src/kernel/` - Architecture-independent kernel code (VFS, syscalls, scheduler, tmpfs, diskfs, devfs, overlayfs, PTY, TTY)
+- `src/arch/` - Architecture-specific code (boot, context switch, interrupts, VMM)
+- `src/hal/` - Hardware abstraction layer (CPU, keyboard, timer, UART, video)
+- `src/drivers/` - Device drivers (ATA, initrd, keyboard, timer, UART, VGA)
+- `src/mm/` - Memory management (PMM, heap)
 - `include/` - Header files
+- `user/` - Userland programs (`init.c`, `echo.c`)
+- `docs/` - Documentation (POSIX roadmap)
index fd2263a8610b420ecd29209a52433490685173dc..35aa312ec15204e3a54eab84d11f9526529d11d6 100644 (file)
 # AdrOS POSIX Roadmap (Checklist)
 
-This document tracks **what is already implemented** versus **what is missing** to reach a practical Unix-like system with increasing POSIX compatibility.
+This document tracks **what is already implemented** versus **what is missing** to reach a practical Unix-like system with full POSIX compatibility.
 
 Notes:
 - This is intentionally pragmatic: items are ordered to unlock userland capabilities quickly.
 - Checkboxes reflect the current state of the `master` branch.
 
 ## Status Legend
-- `[x]` implemented (works end-to-end)
+- `[x]` implemented (works end-to-end, smoke-tested)
 - `[~]` partial (exists but incomplete/limited)
 - `[ ]` not implemented
 
 ---
 
-## 0) Current Baseline (Already in tree)
-
-### Boot / platform / core kernel
-- [x] x86 (i386) boot via GRUB2 Multiboot2
-- [x] Higher-half kernel mapping
-- [x] IDT + IRQ enable
-- [x] Basic scheduler / kernel threads
-- [x] Timer tick
-- [x] Kernel heap (`kmalloc`/`kfree`)
-- [~] Multi-arch stubs (ARM/RISC-V/MIPS) (not functionally brought up)
-
-### InitRD + filesystem basics
-- [x] InitRD format: TAR/USTAR
-- [x] InitRD directory tree support
-- [x] `fs_node_t` abstraction with `read/finddir` for InitRD nodes
-- [x] `vfs_lookup()` absolute path resolver
-- [x] VFS mount table support (`vfs_mount`)
-- [x] Writable filesystem support (`tmpfs`)
-- [x] `overlayfs` (copy-up overlay for root)
-
-### Userspace bring-up
-- [x] ELF32 userspace loader from VFS (`/bin/init.elf`)
-- [~] Process model is minimal, but Unix-like primitives exist (fork/exec/wait)
-- [x] `int 0x80` syscall entry (x86)
-
-### Syscalls (current)
-- [x] `write(fd=1/2)`
-- [x] `exit()` (closes FDs, marks zombie, notifies parent)
-- [~] `getpid()` (minimal)
-- [x] `open()` (read-only)
-- [x] `read()` (files + stdin)
-- [x] `close()`
-- [x] `waitpid()`
-- [x] `waitpid(..., WNOHANG)`
-- [x] `lseek()`
-- [x] `stat()` / `fstat()`
-- [x] `dup()` / `dup2()`
-- [x] `pipe()`
-- [x] `fork()`
-- [~] `execve()` (loads ELF from InitRD; minimal argv/envp)
-- [x] `getppid()`
-- [x] `select()` / `poll()` (minimal)
-- [~] Basic signals (`sigaction`, `sigprocmask`, `kill`) (delivery model is minimal)
-- [x] `sigreturn()` trampoline (userspace return path for signal handlers)
-- [x] `setsid()` / `setpgid()` / `getpgrp()` (minimal)
-
-### FD layer
-- [x] Per-process fd table (fd allocation starts at 3)
-- [x] File read offset tracking
-- [x] `dup/dup2` with refcounted file objects
-- [x] `pipe()` with in-kernel ring buffer endpoints
-- [x] `lseek()`
-
-### TTY
-- [x] TTY canonical input (line-buffered until `\n`)
-- [x] Echo + backspace handling
-- [x] Blocking reads (process `BLOCKED`) + wait queue (multiple waiters)
-- [x] `fd=0` wired to `tty_read`, `fd=1/2` wired to `tty_write`
-- [~] Termios-like configuration (minimal: `TCGETS`/`TCSETS`)
-- [~] Sessions / process groups / controlling terminal (minimal: `TIOCGPGRP`/`TIOCSPGRP` + job control checks)
-- [ ] PTY
-
-### Persistence (x86 / QEMU)
-- [x] ATA PIO driver (primary master IDE)
-- [x] Minimal on-disk persistence filesystem mounted at `/persist`
+## 1. Syscalls — File I/O
+
+| Syscall | Status | Notes |
+|---------|--------|-------|
+| `open` | [x] | Supports `O_CREAT`, `O_TRUNC`; works on diskfs, devfs, tmpfs, overlayfs |
+| `openat` | [x] | `AT_FDCWD` supported; other dirfd values return `ENOSYS` |
+| `read` | [x] | Files, pipes, TTY, PTY; `O_NONBLOCK` returns `EAGAIN` |
+| `write` | [x] | Files, pipes, TTY, PTY; `O_NONBLOCK` returns `EAGAIN` |
+| `close` | [x] | Refcounted file objects |
+| `lseek` | [x] | `SEEK_SET`, `SEEK_CUR`, `SEEK_END` |
+| `stat` | [x] | Minimal `struct stat` (mode/type/size/inode) |
+| `fstat` | [x] | |
+| `fstatat` | [x] | `AT_FDCWD` supported |
+| `dup` | [x] | |
+| `dup2` | [x] | |
+| `dup3` | [x] | Flags parameter (currently only `flags=0` accepted) |
+| `pipe` | [x] | In-kernel ring buffer |
+| `pipe2` | [x] | Supports `O_NONBLOCK` flag |
+| `select` | [x] | Minimal (pipes, TTY) |
+| `poll` | [x] | Minimal (pipes, TTY, `/dev/null`) |
+| `ioctl` | [x] | `TCGETS`, `TCSETS`, `TIOCGPGRP`, `TIOCSPGRP` |
+| `fcntl` | [x] | `F_GETFL`, `F_SETFL` (for `O_NONBLOCK`) |
+| `getdents` | [x] | Generic across all VFS (diskfs, tmpfs, devfs, overlayfs) |
+| `pread`/`pwrite` | [ ] | |
+| `readv`/`writev` | [ ] | |
+| `truncate`/`ftruncate` | [ ] | |
+| `fsync`/`fdatasync` | [ ] | |
+
+## 2. Syscalls — Directory & Path Operations
+
+| Syscall | Status | Notes |
+|---------|--------|-------|
+| `mkdir` | [x] | diskfs |
+| `rmdir` | [x] | diskfs; checks directory is empty (`ENOTEMPTY`) |
+| `unlink` | [x] | diskfs; returns `EISDIR` for directories |
+| `unlinkat` | [x] | `AT_FDCWD` supported |
+| `rename` | [x] | diskfs; handles same-type overwrite |
+| `chdir` | [x] | Per-process `cwd` |
+| `getcwd` | [x] | |
+| `link` | [ ] | Hard links |
+| `symlink` | [ ] | Symbolic links |
+| `readlink` | [ ] | |
+| `access` | [ ] | Permission checks |
+| `umask` | [ ] | |
+| `realpath` | [ ] | Userland (needs libc) |
+
+## 3. Syscalls — Process Management
+
+| Syscall | Status | Notes |
+|---------|--------|-------|
+| `fork` | [x] | Full COW not implemented; copies address space |
+| `execve` | [~] | Loads ELF from VFS; minimal argv/envp; no `$PATH` search |
+| `exit` / `_exit` | [x] | Closes FDs, marks zombie, notifies parent |
+| `waitpid` | [x] | `-1` (any child), specific pid, `WNOHANG` |
+| `getpid` | [x] | |
+| `getppid` | [x] | |
+| `setsid` | [x] | |
+| `setpgid` | [x] | |
+| `getpgrp` | [x] | |
+| `getuid`/`getgid`/`geteuid`/`getegid` | [ ] | No user/group model yet |
+| `setuid`/`setgid` | [ ] | |
+| `brk`/`sbrk` | [ ] | Heap management |
+| `mmap`/`munmap` | [ ] | Memory-mapped I/O |
+| `clone` | [ ] | Thread creation |
+| `nanosleep`/`sleep` | [ ] | |
+| `alarm` | [ ] | |
+| `times`/`getrusage` | [ ] | |
+
+## 4. Syscalls — Signals
+
+| Syscall | Status | Notes |
+|---------|--------|-------|
+| `sigaction` | [x] | Installs handlers; `sa_flags` minimal |
+| `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` | [ ] | |
+| `sigqueue` | [ ] | |
+| `sigaltstack` | [ ] | Alternate signal stack |
+| Signal defaults | [~] | `SIGKILL`/`SIGSEGV`/`SIGUSR1` handled; many signals missing default actions |
+
+## 5. File Descriptor Layer
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| Per-process fd table | [x] | Up to `PROCESS_MAX_FILES` entries |
+| Refcounted file objects | [x] | Shared across `dup`/`fork` |
+| File offset tracking | [x] | |
+| `O_NONBLOCK` | [x] | Pipes, TTY, PTY via `fcntl` or `pipe2` |
+| `O_CLOEXEC` | [ ] | Close-on-exec flag |
+| `O_APPEND` | [ ] | |
+| `FD_CLOEXEC` via `fcntl` | [ ] | |
+| File locking (`flock`/`fcntl`) | [ ] | |
+
+## 6. Filesystem / VFS
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| VFS mount table | [x] | Up to 8 mounts |
+| `vfs_lookup` path resolution | [x] | Absolute + relative (via `cwd`) |
+| `fs_node_t` with `read`/`write`/`finddir`/`readdir` | [x] | |
+| `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/tty`, `/dev/ptmx`, `/dev/pts/0`; `readdir` |
+| **diskfs** (on-disk) | [x] | Hierarchical inodes; `open`/`read`/`write`/`stat`/`mkdir`/`unlink`/`rmdir`/`rename`/`getdents` |
+| **persistfs** | [x] | Minimal persistence at `/persist` |
+| Permissions (`uid`/`gid`/mode) | [ ] | No permission model |
+| Hard links | [ ] | |
+| Symbolic links | [ ] | |
+| `/proc` filesystem | [ ] | |
+| ext2 / FAT support | [ ] | |
+
+## 7. TTY / PTY
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| Canonical input (line-buffered) | [x] | |
+| Echo + backspace | [x] | |
+| Blocking reads + wait queue | [x] | |
+| `TCGETS`/`TCSETS` | [x] | Minimal termios |
+| `TIOCGPGRP`/`TIOCSPGRP` | [x] | |
+| Job control (`SIGTTIN`/`SIGTTOU`) | [x] | Background pgrp enforcement |
+| `isatty` (via `ioctl TCGETS`) | [x] | |
+| PTY master/slave | [x] | `/dev/ptmx` + `/dev/pts/0` |
+| Non-blocking PTY I/O | [x] | |
+| Raw mode (non-canonical) | [ ] | |
+| VMIN/VTIME | [ ] | |
+| Signal characters (Ctrl+C → `SIGINT`, etc.) | [ ] | |
+| Multiple PTY pairs | [ ] | Only 1 pair currently |
+| Window size (`TIOCGWINSZ`/`TIOCSWINSZ`) | [ ] | |
+
+## 8. Memory Management
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| PMM (bitmap allocator) | [x] | |
+| VMM (x86 paging) | [x] | Higher-half kernel |
+| Per-process address spaces | [x] | Page directory per process |
+| Kernel heap (`kmalloc`/`kfree`) | [x] | 10MB heap |
+| W^X for user ELFs | [x] | Text segments read-only after load |
+| `brk`/`sbrk` | [ ] | |
+| `mmap`/`munmap` | [ ] | |
+| Copy-on-write (COW) fork | [ ] | Currently full-copy |
+| PAE + NX bit | [ ] | |
+| Guard pages | [ ] | |
+| ASLR | [ ] | |
+
+## 9. Drivers & Hardware
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| UART serial console | [x] | |
+| VGA text console (x86) | [x] | |
+| PS/2 keyboard | [x] | |
+| PIT timer | [x] | |
+| ATA PIO (IDE) | [x] | Primary master |
+| RTC (real-time clock) | [ ] | |
+| PCI enumeration | [ ] | |
+| Framebuffer / VESA | [ ] | |
+| Network (e1000/virtio-net) | [ ] | |
+| Virtio-blk | [ ] | |
+
+## 10. Userland
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| ELF32 loader | [x] | |
+| `/bin/init.elf` (smoke tests) | [x] | Comprehensive test suite |
+| `/bin/echo.elf` | [x] | Minimal argv/envp test |
+| Minimal libc | [ ] | No libc; userland uses raw syscall wrappers |
+| Shell (`sh`) | [ ] | |
+| Core utilities (`ls`, `cat`, `cp`, `mv`, `rm`, `mkdir`) | [ ] | |
+| Dynamic linking | [ ] | |
+| `$PATH` search in `execve` | [ ] | |
+
+## 11. Networking (future)
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `socket` | [ ] | |
+| `bind`/`listen`/`accept` | [ ] | |
+| `connect`/`send`/`recv` | [ ] | |
+| TCP/IP stack | [ ] | |
+| UDP | [ ] | |
+| DNS resolver | [ ] | |
+| `/etc/hosts` | [ ] | |
+| `getaddrinfo` | [ ] | Userland (needs libc) |
 
 ---
 
-## 1) Milestone A1 — Process lifecycle: `waitpid` + cleanup on `exit`
-
-Goal: make process termination and waiting work reliably; unblock shells and service managers.
-
-### Kernel process lifecycle
-- [x] Introduce parent/child relationship tracking
-- [x] Track exit status per process
-- [x] Transition to `PROCESS_ZOMBIE` on exit
-- [x] Reap zombie processes and free resources
-
-### `exit()` cleanup
-- [x] Close all open file descriptors for the process
-- [x] Release process memory resources (kernel stack + user addr_space when reaped)
-- [~] Remove process from run queues safely (best-effort; continues improving)
-
-### `waitpid()` syscall
-- [x] Add syscall number + userland wrapper
-- [x] `waitpid(-1, ...)` wait for any child
-- [x] `waitpid(pid, ...)` wait for specific child
-- [x] Non-blocking mode (optional early): `WNOHANG`
-- [~] Return semantics consistent with POSIX (pid on success, -1 on error)
-
-### Tests
-- [x] Userspace test: parent forks children, children exit, parent waits, validates status
-- [ ] Regression: ensure keyboard/TTY still works
-
----
-
-## 2) Milestone A2 — Address spaces per process
-
-Goal: move from a shared address space to per-process virtual memory, required for real isolation and POSIX process semantics.
-
-### Core VM changes
-- [x] Per-process page directory / page tables
-- [x] Context switch also switches address space
-- [x] Kernel mapped in all address spaces
-- [~] User/kernel separation rules enforced (uaccess checks + no user mappings in kernel range)
-
-### Syscall/uaccess hardening
-- [~] Ensure `user_range_ok` is robust across per-process mappings
-- [x] `copy_to_user` requires writable user mappings (x86)
-- [ ] Page-fault handling for invalid user pointers (deliver `SIGSEGV` later)
-
-### Userspace loader
-- [x] ELF loader targets the new process address space
-- [x] User stack per process
-
-### Tests
-- [x] Smoke: boot + run `/bin/init.elf`
-- [ ] Two-process test: verify isolation (write to memory in one does not affect other)
-
----
-
-## 3) Milestone B1 — POSIX-ish file API basics (`lseek`, `stat/fstat`)
-
-Goal: unlock standard libc-style IO patterns.
-
-### Syscalls
-- [x] `lseek(fd, off, whence)`
-- [x] `stat(path, struct stat*)`
-- [x] `fstat(fd, struct stat*)`
-
-### Kernel data model
-- [x] Define minimal `struct stat` ABI (mode/type/size/inode)
-- [x] Map InitRD node metadata to `stat`
-
-### Error model
-- [x] Negative errno returns in kernel/syscalls (`-errno`)
-- [ ] Userspace `errno` + libc-style wrappers (`-1` + `errno`)
-
-### Tests
-- [x] Userspace test: open -> fstat -> read -> lseek -> read
-
----
-
-## 4) Milestone C1 — Mounts + `tmpfs` (writable)
-
-Goal: get a writable filesystem (even if volatile) and a real VFS layout.
-
-### VFS mounts
-- [x] Mount table support
-- [x] `vfs_lookup` resolves across mounts
-- [ ] Mount InitRD at `/` or at `/initrd` (decision)
-
-### `tmpfs`
-- [x] In-memory inode/dentry model
-- [~] Create/unlink (limited)
-- [x] Read/write
-- [x] Directories
-
-### Devices (minimum Unix feel)
-- [x] `/dev` mount
-- [x] `/dev/tty`
-- [x] `/dev/null`
-
-### Tests
-- [x] Userspace test: create file in tmpfs, write, read back
-
----
-
-## 5) Later milestones (in progress)
-
-### Process / POSIX expansion
-- [x] `fork()`
-- [~] `execve()`
-- [x] `getppid()`
-- [~] Signals + basic job control (`SIGTTIN`/`SIGTTOU` for background TTY I/O)
-
-#### Signals (details)
-- [x] `sigreturn()` syscall + userspace trampoline return path
-- [x] Userspace smoke test: signal handler returns correctly (see `user/init.c`)
-
-### Pipes + IO multiplexing
-- [x] `pipe()`
-- [x] `dup/dup2`
-- [x] `select/poll`
-
-### TTY advanced
-- [ ] termios flags (canonical/raw/echo)
-- [~] controlling terminal, sessions, pgrp (minimal)
-- [ ] PTY for userland shells
-
----
-
-## 6) Milestone D1 — Persistent storage (minimal on-disk)
-
-Goal: have at least one end-to-end persisted storage path for smoke tests and future filesystems.
-
-### Block device
-- [x] ATA PIO (primary master IDE)
-
-### Filesystem
-- [x] Minimal persisted filesystem mounted at `/persist`
-- [ ] General-purpose on-disk FS (directories, allocation, metadata)
+## Priority Roadmap (next steps)
+
+### Near-term (unlock a usable shell)
+1. **Minimal libc** — `printf`, `malloc`/`free`, `string.h`, `stdio.h` wrappers
+2. **Shell** — `sh`-compatible; needs `fork`+`execve`+`waitpid`+`pipe`+`dup2`+`chdir` (all implemented)
+3. **Core utilities** — `ls` (uses `getdents`), `cat`, `echo`, `mkdir`, `rm`, `mv`, `cp`
+4. **Signal characters** — Ctrl+C → `SIGINT`, Ctrl+Z → `SIGTSTP`, Ctrl+D → EOF
+5. **Raw TTY mode** — needed for interactive editors and proper shell line editing
+
+### Medium-term (real POSIX compliance)
+6. **`brk`/`sbrk`** — userland heap
+7. **`mmap`/`munmap`** — memory-mapped files, shared memory
+8. **Permissions** — `uid`/`gid`, mode bits, `chmod`, `chown`, `access`, `umask`
+9. **`O_CLOEXEC`** — close-on-exec for fd hygiene
+10. **`/proc`** — process information filesystem
+11. **Hard/symbolic links** — `link`, `symlink`, `readlink`
+
+### Long-term (full Unix experience)
+12. **Networking** — socket API, TCP/IP stack
+13. **Multi-arch bring-up** — ARM/RISC-V functional kernels
+14. **COW fork + demand paging**
+15. **Threads** (`clone`/`pthread`)
+16. **Dynamic linking** (`ld.so`)
+17. **ext2/FAT** filesystem support