Skip to content

Commit 08c2009

Browse files
committed
feat(fs): add FAT32 filesystem, FD table, and file I/O syscalls (v0.0.6)
Phase 4 implementation: - FAT32 driver (fs/ crate): BPB parsing, cluster chain traversal/allocation, directory entry creation (8.3 + LFN), file read/write via VirtIO block - VFS path resolution: lookup_path(), set_root(), global VFS_ROOT - File descriptor table (kernel/src/fd.rs): global BTreeMap<(task_id, fd), OpenFile> with open/close/seek operations, fds 0-2 reserved - New syscalls: SYS_OPEN(2), SYS_CLOSE(3), SYS_SEEK(8) - Extended SYS_READ/SYS_WRITE for fd >= 3 (file I/O) - Userspace wrappers: serix_open(), serix_close(), serix_seek() in ulib - Boot logs mirrored to framebuffer for bare-metal visibility - VirtIO read_sector changed to polled completion (fixes hang on second I/O) - Files created by Serix visible on Linux via mount -o loop disk.img - Documentation: crate READMEs (fs, vfs, drivers, ipc), updated ROADMAP, KERNEL_API, ARCHITECTURE, kernel README, project README
1 parent aa414e4 commit 08c2009

32 files changed

+2683
-157
lines changed

CLAUDE.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Serix is a hybrid-kernel x86_64 operating system written in Rust (`#![no_std]`, nightly toolchain). It boots via the Limine v10.x bootloader and uses capability-based security. Currently at v0.0.6, Phase 4 development (FAT32 filesystem).
8+
9+
## Build Commands
10+
11+
```bash
12+
cargo build --release # Build kernel only
13+
cargo build -p <crate> --release # Build a specific crate
14+
make init # Build userspace init binary (required before iso)
15+
make iso # Build bootable ISO (kernel + init + Limine)
16+
make run # Build everything and run in QEMU
17+
make clean && cargo clean # Remove all build artifacts
18+
cargo fmt # Format (tabs, 100-char width)
19+
cargo clippy # Lint
20+
```
21+
22+
No automated test suite exists. Validate by booting in QEMU (`make run`) and checking serial output + framebuffer.
23+
24+
**QEMU debug flags**: `qemu-system-x86_64 ... -d int,cpu_reset -no-reboot` to catch triple faults.
25+
26+
## Architecture
27+
28+
### Workspace Structure
29+
30+
Cargo workspace with 16 member crates. `.cargo/config.toml` sets `x86_64-unknown-none` as default target and enables `build-std` — no `--target` flag needed.
31+
32+
Key crates: `kernel/` (entry, GDT, syscalls), `memory/` (paging, heap, frame allocator), `hal/` (serial, CPU, I/O ports), `apic/` (LAPIC, I/O APIC, timer), `idt/` (exception handlers), `graphics/` (framebuffer console), `task/` (async executor, scheduler), `capability/` (security), `drivers/` (VirtIO, PCI), `vfs/` (ramdisk), `ipc/` (port-based messaging), `loader/` (ELF loader), `ulib/` (userspace syscall wrappers), `keyboard/` (PS/2 driver).
33+
34+
Internal crate dependencies use `{ path = "../crate_name" }`.
35+
36+
### Memory Layout
37+
38+
- **HHDM**: All physical RAM mapped at `0xFFFF_8000_0000_0000` — always use `HHDM_REQ.get_response()` for offset, never hardcode
39+
- **Kernel heap**: `0xFFFF_8000_4444_0000` (1 MB, configured in `memory/src/heap.rs`)
40+
- **Userspace**: Lower half, entry at `0x200000` (via `user.ld` linker script)
41+
42+
### Boot Flow (kernel/src/main.rs `_start`)
43+
44+
Serial init → disable PIC/enable APIC → load IDT → enable interrupts/start LAPIC timer → process Limine responses → init page tables from CR3 → init heap → init graphics → init VFS → load init binary → idle loop.
45+
46+
**Critical ordering**: heap must exist before any allocations; IDT must be loaded before enabling interrupts.
47+
48+
### Interrupt Vectors
49+
50+
0-31: CPU exceptions, 32: PIT (disabled), 33: PS/2 keyboard, 49: LAPIC timer (~625 Hz). All handlers must signal EOI to APIC.
51+
52+
### Syscall Interface
53+
54+
Linux-style ABI via `SYSCALL`/`SYSRET`. RAX=number, RDI/RSI/RDX/R10/R8/R9=args. Dispatch in `kernel/src/syscall.rs`, wrappers in `ulib/src/lib.rs`. Syscalls: READ(0), WRITE(1), SEND(20), RECV(21), YIELD(24), EXIT(60).
55+
56+
### Task/Scheduler Model
57+
58+
`TaskCB` stores state + stack pointer. `Scheduler` with `RunQueue` (round-robin). `AsyncTask` with `Future` trait. Context switch via assembly in `task/` crate (callee-saved GPRs + CR3 swap).
59+
60+
## Code Conventions
61+
62+
- **Tabs, not spaces** (`hard_tabs = true`, `tab_spaces = 8`, `max_width = 100`)
63+
- **C-style block comments** for function headers: `/* function_name - description */`
64+
- **Global state pattern**: `static INSTANCE: Once<Mutex<Type>> = Once::new()`
65+
- **Debug output**: `serial_println!` (kernel), `fb_println!` (framebuffer)
66+
- **Address types**: Use `x86_64::PhysAddr` and `x86_64::VirtAddr`, not raw integers
67+
- **Syscall naming**: prefix with `serix_` (e.g., `serix_write`)
68+
- **Handler naming**: suffix with `_handler` (e.g., `timer_interrupt_handler`)
69+
- **Commit format**: `<type>(<scope>): <subject>` — types: feat/fix/docs/style/refactor/perf/test/build/ci/chore, scopes: crate names
70+
71+
## Documentation
72+
73+
Each subsystem crate has its own `README.md`. Technical docs in `docs/` cover: `ARCHITECTURE.md`, `BOOT_PROCESS.md`, `MEMORY_LAYOUT.md`, `INTERRUPT_HANDLING.md`, `KERNEL_API.md`, `GRAPHICS_API.md`, `HAL_API.md`, `ROADMAP.md`.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ members = ["kernel",
1313
"drivers",
1414
"vfs",
1515
"ipc"
16-
, "loader", "ulib"]
16+
, "loader", "ulib", "fs"]
1717

1818
[profile.release]
1919
panic = "abort"

Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LIMINE_DIR = limine
66
LIMINE_BRANCH = v10.x-binary
77
LIMINE_URL = https://github.com/limine-bootloader/limine.git
88

9-
.PHONY: all run iso clean limine kernel
9+
.PHONY: all run iso disk clean limine kernel
1010

1111
all: iso
1212

@@ -48,7 +48,16 @@ iso: init $(ISO_ROOT)/boot/kernel $(ISO_ROOT)/boot/limine-bios.sys $(ISO_ROOT)/b
4848
$(ISO_ROOT) -o $(ISO)
4949
./limine/limine bios-install $(ISO)
5050

51-
run: iso
51+
disk:
52+
@if [ ! -f disk.img ] || [ "$$(file disk.img | grep -c FAT)" -eq 0 ]; then \
53+
dd if=/dev/zero of=disk.img bs=1M count=32 2>/dev/null; \
54+
mkfs.vfat -F 32 -n SERIX disk.img; \
55+
echo "Formatted disk.img as FAT32 (SERIX)"; \
56+
else \
57+
echo "disk.img already FAT32, skipping format"; \
58+
fi
59+
60+
run: iso disk
5261
qemu-system-x86_64 -cdrom $(ISO) -m 4G -serial stdio \
5362
-drive file=disk.img,if=none,format=raw,id=x0 \
5463
-device virtio-blk-pci,drive=x0,disable-legacy=on,disable-modern=off

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ preemptive scheduling.
77

88
## Status
99

10-
Current release: v0.0.5
10+
Current release: v0.0.6
1111

1212
The kernel successfully boots to a graphical console, initializes core
1313
subsystems (APIC, IDT, heap, VFS), loads and executes a userspace init
@@ -33,8 +33,13 @@ Alt text: "Terminal recording showing QEMU boot of Serix kernel with serial cons
3333
- Framebuffer graphics with text console
3434
- VFS with ramdisk support
3535
- ELF loader for userspace binaries
36-
- Basic syscalls: write, read, exit, yield
36+
- Syscalls: read, write, open, close, seek, exit, yield, send, recv, recv_block
3737
- Async task executor with cooperative scheduling
38+
- FAT32 filesystem with file create/read/write (Linux-compatible disk image)
39+
- VirtIO block device driver with PCI enumeration
40+
- Preemptive scheduling with LAPIC timer at ~625 Hz
41+
- IPC port-based message passing with blocking receive
42+
- File descriptor table with open/close/seek syscalls
3843

3944
## Building
4045

@@ -101,12 +106,14 @@ Alt text: "Terminal recording showing keyboard input test - typing characters on
101106
ipc/ Inter-process communication
102107
loader/ ELF userspace binary loader
103108
ulib/ Userspace library with syscall wrappers
109+
fs/ FAT32 filesystem driver
110+
keyboard/ PS/2 keyboard driver
104111
util/ Utility functions (panic handler, etc.)
105112
docs/ Technical documentation
106113
limine/ Limine bootloader (git submodule)
107114
```
108115

109-
**Module Documentation**: [kernel](kernel/README.md) | [memory](memory/README.md) | [hal](hal/README.md) | [apic](apic/README.md) | [idt](idt/README.md) | [graphics](graphics/README.md) | [task](task/README.md) | [util](util/README.md) | [keyboard](keyboard/README.md)
116+
**Module Documentation**: [kernel](kernel/README.md) | [memory](memory/README.md) | [hal](hal/README.md) | [apic](apic/README.md) | [idt](idt/README.md) | [graphics](graphics/README.md) | [task](task/README.md) | [util](util/README.md) | [keyboard](keyboard/README.md) | [vfs](vfs/README.md) | [ipc](ipc/README.md) | [drivers](drivers/README.md) | [fs](fs/README.md)
110117

111118
## Documentation
112119

@@ -130,7 +137,7 @@ Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for:
130137
- Build and test procedures
131138
- Commit message format
132139
- Pull request process
133-
- Areas needing work (see [Phase 3 of roadmap](docs/ROADMAP.md#phase-3-hardware-integration-in-progress))
140+
- Areas needing work (see [Phase 4 of roadmap](docs/ROADMAP.md))
134141

135142
Bug reports and feature requests should use GitHub issue templates in
136143
[.github/ISSUE_TEMPLATE/](.github/ISSUE_TEMPLATE/).

docs/ARCHITECTURE.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Serix Kernel Architecture
22

3-
> **Target ISA:** x86_64 (AMD64) · **Privilege Model:** Ring 0 / Ring 3 Hybrid · **Current Release:** v0.0.5
3+
> **Target ISA:** x86_64 (AMD64) · **Privilege Model:** Ring 0 / Ring 3 Hybrid · **Current Release:** v0.0.6
44
55
## Table of Contents
66

@@ -44,6 +44,7 @@ These modules execute in supervisor mode with direct access to CR3, MSRs, and MM
4444
| **Interrupt Dispatcher** | `idt/`, `apic/` | IDT vectors, LAPIC/I/O APIC programming, EOI signaling |
4545
| **Capability Store** | `capability/` | `BTreeMap`-backed capability validation on every syscall/IPC boundary |
4646
| **Syscall Entry** | `kernel/` | `SYSCALL`/`SYSRET` trampoline; MSR configuration (`LSTAR`, `STAR`, `SFMASK`, `EFER.SCE`) |
47+
| **FAT32 Filesystem** | `fs/` | Synchronous sector I/O via VirtIO-blk; cluster chain operations must be atomic |
4748

4849
### 2.2 Ring 3 — Userspace Server Processes
4950

@@ -53,7 +54,7 @@ These subsystems run as isolated processes in their own address spaces. Faults i
5354
|---|---|---|
5455
| **Ext4 Filesystem Daemon** | Synchronous IPC | Parses extent trees, manages journal, serves VFS `read`/`write` dispatches |
5556
| **Network Stack** | Zero-copy shared buffers | TCP/IP processing on VirtIO-net ring buffers mapped into application address space |
56-
| **Block Driver (VirtIO-blk)** | Asynchronous IPC | Submits I/O descriptors to VirtIO virtqueues; interrupt-driven completion |
57+
| **Block Driver (VirtIO-blk)** | Polled I/O | Currently Ring 0; submits I/O descriptors to VirtIO virtqueues; polled completion |
5758
| **USB/Input Driver (XHCI)** | Asynchronous IPC | Manages XHCI host controller rings; delivers HID events via IPC ports |
5859
| **Display Server (GOP)** | Shared framebuffer | Composites client surfaces onto UEFI GOP linear framebuffer |
5960
| **POSIX-to-Capability Bridge** | Synchronous IPC | Translates `UID`/`GID`/`mode` DAC checks into `CapabilityHandle` tickets |
@@ -157,6 +158,7 @@ The LES enables execution of unmodified Linux ELF binaries by translating Linux
157158
- **Messages:** Fixed 128-byte payload (`Message { sender_id, id, len, data: [u8; 128] }`).
158159
- **IPC Space:** A global `BTreeMap<PortId, Port>` registry (`IPC_GLOBAL`) for port lookup.
159160
- **Operations:** `send(port_id, msg)` enqueues; `receive(port_id)` dequeues (currently non-blocking; blocking semantics planned via scheduler integration).
161+
- **Blocking Receive:** `receive_blocking()` suspends the calling task (sets `TaskState::Blocked`) until a message arrives; `send()` wakes the first blocked receiver.
160162

161163
### 5.2 IPC Fastpath
162164

@@ -315,6 +317,7 @@ serix/
315317
├── capability/ # CapabilityStore, CapabilityHandle, grant/revoke/validate
316318
├── ipc/ # Port-based IPC, Message, IpcSpace, fastpath
317319
├── vfs/ # INode trait, RamFile, RamDir, mount table, page cache
320+
├── fs/ # FAT32 filesystem driver (BPB, cluster chains, directory entries, file I/O)
318321
├── loader/ # ELF64 parser, PT_LOAD/PT_INTERP, auxv construction
319322
├── drivers/ # PCI enumeration, VirtIO-blk, ConsoleDevice
320323
├── keyboard/ # PS/2 scancode translation, key event queue

docs/BOOT_PROCESS.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ Serix configuration
185185
186186
TIMEOUT=3
187187
188-
:Serix OS v0.0.5
188+
:Serix OS v0.0.6
189189
190190
```
191191

@@ -421,7 +421,7 @@ Serial output
421421
422422
```
423423

424-
Serix Kernel v0.0.5 Starting...
424+
Serix Kernel v0.0.6 Starting...
425425
Serial console initialized
426426

427427
```
@@ -776,7 +776,7 @@ Test output
776776

777777
```
778778
779-
graphics::fb_println!("Welcome to Serix OS v0.0.5!");
779+
graphics::fb_println!("Welcome to Serix OS v0.0.6!");
780780
graphics::fb_println!("Framebuffer: {}x{}", fb.width(), fb.height());
781781
graphics::fb_println!("Memory: {} MB usable", total_mb);
782782
@@ -927,7 +927,7 @@ Serial console output
927927

928928
```
929929
930-
Serix Kernel v0.0.5 Starting...
930+
Serix Kernel v0.0.6 Starting...
931931
Serial console initialized
932932
Legacy PIC disabled
933933
APIC enabled
@@ -940,7 +940,7 @@ Framebuffer display:
940940

941941
- Blue screen background
942942
- Memory map bars at bottom (colored)
943-
- Text: "Welcome to Serix OS v0.0.5!"
943+
- Text: "Welcome to Serix OS v0.0.6!"
944944
- Text: System information (memory, framebuffer resolution)
945945

946946
Interrupt functionality:

docs/GRAPHICS_API.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ This document describes the graphics driver implementation, programming
1515
interfaces, and usage guidelines. It follows Linux kernel documentation
1616
conventions and is organized for kernel developers.
1717

18-
## Status (v0.0.5)
18+
## Status (v0.0.6)
1919

2020
Working Features:
2121

@@ -1375,7 +1375,7 @@ graphics::console::init_console(
13751375
);
13761376

13771377
// Simple text output:
1378-
fb_println!("Serix Kernel v0.0.5");
1378+
fb_println!("Serix Kernel v0.0.6");
13791379
fb_println!("Memory: {} MB", total_memory / 1024 / 1024);
13801380
fb_println!();
13811381

docs/HAL_API.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ devices while maintaining zero-cost performance characteristics.
3030
- Minimal Unsafe Surface - Unsafe operations clearly marked and isolated
3131
- Direct Hardware Control - No buffering or indirection layers
3232

33-
## 1.2 Current Features (v0.0.5)
33+
## 1.2 Current Features (v0.0.6)
3434

3535
Serial Console (WORKING)
3636

@@ -524,7 +524,7 @@ Detects number of CPUs, cores, and threads in the system using CPUID and ACPI
524524
tables. Currently this module is a stub returning 1 CPU.
525525

526526

527-
## 6.1 Current Implementation (v0.0.5)
527+
## 6.1 Current Implementation (v0.0.6)
528528

529529
Function
530530

docs/INTERRUPT_HANDLING.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Interrupt Descriptor Table (IDT) and Advanced Programmable Interrupt Controller
1111
(APIC). This document describes the complete interrupt handling mechanism from
1212
hardware signal to software handler execution.
1313

14-
## Current Status (v0.0.5)
14+
## Current Status (v0.0.6)
1515

1616
Working features
1717

@@ -40,7 +40,7 @@ Legacy PIC Disabled, not used Ports 0x20/0x21, 0xA0/0xA1
4040

4141
## Interrupt Vector Allocation
4242

43-
Current vector assignments in v0.0.5
43+
Current vector assignments in v0.0.6
4444

4545
```
4646
@@ -471,7 +471,7 @@ fault.
471471

472472
## Keyboard Interrupt (Vector 33)
473473

474-
Status: **WORKING IN v0.0.5**
474+
Status: **WORKING IN v0.0.6**
475475

476476
Implementation in idt/src/lib.rs
477477

@@ -488,7 +488,7 @@ Implementation in idt/src/lib.rs
488488

489489
## Timer Interrupt (Vector 49)
490490

491-
Status: **WORKING IN v0.0.5** (~625 Hz)
491+
Status: **WORKING IN v0.0.6** (~625 Hz)
492492

493493
Implementation in apic/src/timer.rs
494494

@@ -516,7 +516,7 @@ Complete routing from hardware IRQ to handler
516516

517517
## I/O APIC Redirection Table
518518

519-
Current configuration in v0.0.5
519+
Current configuration in v0.0.6
520520

521521
```
522522
@@ -728,7 +728,7 @@ I/O APIC Redirection Dump
728728
729729
## Interrupt Vector Summary
730730
731-
Active vectors in v0.0.5
731+
Active vectors in v0.0.6
732732
733733
```
734734

0 commit comments

Comments
 (0)