From c4882e415e7b38df194eb0be04e7c985eafe9d9a Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Mon, 9 Feb 2026 23:16:07 -0300 Subject: [PATCH] docs: update README, BUILD_GUIDE, and POSIX_ROADMAP to reflect current state --- BUILD_GUIDE.md | 34 +++- README.md | 101 +++++----- docs/POSIX_ROADMAP.md | 417 ++++++++++++++++++++++-------------------- 3 files changed, 305 insertions(+), 247 deletions(-) diff --git a/BUILD_GUIDE.md b/BUILD_GUIDE.md index 6008f82..4fa0820 100644 --- a/BUILD_GUIDE.md +++ b/BUILD_GUIDE.md @@ -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 diff --git a/README.md b/README.md index 5c35a93..695743b 100644 --- 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) diff --git a/docs/POSIX_ROADMAP.md b/docs/POSIX_ROADMAP.md index fd2263a..35aa312 100644 --- a/docs/POSIX_ROADMAP.md +++ b/docs/POSIX_ROADMAP.md @@ -1,217 +1,232 @@ # 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 -- 2.43.0