Skip to content

Filesystem

kazah-png edited this page Jul 26, 2026 · 10 revisions

Filesystem

A POSIX-like VFS over four backends: a ramdisk loaded from the initramfs, a read/write EXT2 disk mounted at /mnt, the generated /proc pseudo-filesystem, and /dev special files. All four are reached through the same open/read/write/getdents calls — there are no side-channel syscalls.

See also: Architecture, Drivers, Syscalls, Shell, GUI Subsystem

VFS (vfs.c)

One unified namespace over a pool of 256 nodes (MAX_INODES), plus a free-list for the transient nodes that back mounted files. Paths resolve relative to the calling process's working directory, with . and .. normalised.

Function Purpose
vfs_open / read / write / close File I/O
vfs_pread / vfs_pwrite Offset-aware I/O — the per-fd offset tracker and mmap use these
vfs_readdir Directory listing across ramdisk, EXT2 and /proc
vfs_mkdir / vfs_unlink / vfs_rename Namespace mutation
vfs_chdir / vfs_getcwd Navigation; returns a full absolute path
vfs_isdir Directory test
vfs_mount / vfs_find_mount The 16-entry mount table

Working directories are per-process. Each process carries its own cwd, inherited across fork and kept across execve. Each GUI terminal window tracks its own; the kernel shell keeps a single global one.

Concurrency

The node pool, the free-list and the mount table each sit behind a spinlock, and the EXT2 driver has one of its own. This is not theoretical: the EXT2 driver uses a single global scratch buffer for the duration of an operation, so two cores inside it at once would corrupt each other's block reads.

One subtlety if you work on this code: a VFS fd is a node pointer, so the pool must track who holds one — a node cannot be recycled while an fd still names it.

Ramdisk

The default filesystem, built at boot from the initramfs:

/
├── bin/  etc/  mnt/  proc/  root/  tmp/  usr/  var/
├── dev/          null  zero  random  urandom
├── home/
│   └── <user>/   created at first login, seeded with starter content
└── *.elf         the userspace programs

Initramfs (initramfs.c)

A CPIO newc archive (magic 070701) embedded in the kernel as a C byte array in initramfs_data.h, generated by tools/mkinitramfs.py. At boot it is unpacked into the ramdisk in one pass. See Building for how to regenerate it.

/dev special files

Real VFS nodes carrying a dev_type field. vfs_pread/vfs_pwrite intercept on that field, so no new syscalls were needed and ordinary tools work unchanged — ls /dev, cat, and shell redirection all behave.

Node Read Write
/dev/null EOF (0 bytes) Discarded
/dev/zero Endless null bytes Discarded
/dev/random Pseudo-random bytes from a lazily-seeded xorshift64 PRNG Discarded
/dev/urandom Alias of /dev/random Discarded

These are not the kernel's cryptographic RNG. TLS and ephemeral key generation use csprng_bytes() — HMAC_DRBG-SHA256 seeded from RDSEED/RDRAND. See Cryptography and TLS.

/proc pseudo-filesystem

Generated nodes whose contents are synthesized on read by proc_generate() — nothing is stored. proc_sync() reconciles the per-pid directories with the live process table and is called from vfs_open and vfs_isdir, so cat /proc/<pid>/status always sees a current view.

System-wide

Path Contents
/proc/version Kernel banner
/proc/meminfo MemTotal / MemUsed / MemFree
/proc/uptime tick_count converted to seconds
/proc/cpuinfo CPU identification

Per-process

Path Contents
/proc/<pid>/status Name, Pid, PPid, State
/proc/<pid>/cmdline Full command line including argv
/proc/<pid>/maps Mapped memory regions with their address ranges

Process names are real, set by proc_set_comm() — a process shows as init, not elf.

Two ring-3 tools read nothing but these files: free (from /proc/meminfo) and pmap [pid] (from /proc/<pid>/maps).

EXT2 (ext2.c)

A read/write EXT2 driver over ATA PIO, auto-mounted at /mnt when a disk is present.

  • Superblock, block groups, inode tables, directory entries
  • Inode and block allocation, directory creation, file writes, unlink
  • Fd-based file I/O flushed to disk on close — persistent across reboots
  • Fd-based readdir, so the GUI file manager can browse and edit the disk
  • A write-through sector cache — it accelerates reads and cannot corrupt the disk, because every write still reaches the platter

The write path is verified against e2fsck, not against itself. That distinction matters: a driver that reads back what it wrote can be self-consistently wrong.

df reports usage of the mounted filesystem.

How a mount is reached

vfs_open detects a path under a mount point via vfs_find_mount and returns a transient mount-backed node preloaded from the filesystem. vfs_write/vfs_pwrite flush the whole node back; vfs_close frees it. Opening a directory probes readdir — the EXT2 driver returns −1 for non-directories — and loads every entry once, which vfs_readdir then serves by index. The node free-list exists precisely so these per-open nodes do not exhaust the pool.

What lives on the disk

The EXT2 image (ext2-test.img under QEMU) holds:

Path (as seen from NyxOS) Purpose
/etc/passwd User accounts — see Security
/mnt/doom1.wad The DOOM shareware WAD
anything you write under /mnt Persists across reboots

Tools

Kernel shell: ls cd pwd cat touch mkdir rm cp mv write head tail grep sort wc find tree diff df mount open

Ring 3: ls cat touch mkdir rm cp mv head tail grep sort find wc stat less more edit

See Shell for the full reference.

See also

External resources

Clone this wiki locally