|
1 | | -## MorpheusX |
| 1 | +# MorpheusX |
2 | 2 |
|
3 | 3 | [](https://github.com/Poprdi/morpheusx/actions/workflows/ci.yml) |
4 | 4 | [](https://github.com/Poprdi/morpheusx/actions/workflows/uefi-build.yml) |
5 | 5 | [](https://github.com/Poprdi/morpheusx/actions/workflows/audit.yml) |
6 | | -[](https://poprdi.github.io/morpheusx/) |
| 6 | +[](LICENSE-GPL-3.0) |
7 | 7 |
|
| 8 | +A bare-metal x86-64 exokernel written entirely in Rust. MorpheusX boots from UEFI firmware, calls `ExitBootServices`, and from that moment forward — no OS underneath, no runtime services, no safety net. Just raw hardware, a buddy allocator, and a scheduler running at 100 Hz. |
8 | 9 |
|
9 | | -MorpheusX is a UEFI boot and hardware exokernel-like runtime that loads Linux kernels directly from firmware space, treats distributions as disposable layers, and aims to keep userland state persisten[...] |
| 10 | +This isn't a toy. It boots, runs user processes, switches context, manages its own page tables, speaks to block hardware through AHCI and VirtIO drivers, and stores files in a log-structured crash-safe filesystem of its own design. The syscall interface has 75 entries. The shell accepts commands. The task manager shows you live CPU ticks per process. |
| 11 | + |
| 12 | +It's also early. Come help build it. |
10 | 13 |
|
11 | 14 | --- |
12 | 15 |
|
13 | | -### Features |
| 16 | +## What's Inside |
14 | 17 |
|
15 | | -- Boots Linux kernels from the EFI system partition with custom GPT and FAT32 handling. |
16 | | -- Provides a boot-time TUI for selecting images and guiding installs. |
17 | | -- Includes a bare-metal network stack (operating after ExitBootServices) for downloading ISOs and updates. (Work in progress) |
18 | | -- **Implements a self-persisting runtime**: The in-memory, relocated PE loader can clone itself, reverse its own relocations, and reconstruct a fully bootable on-disk binary—enabling live regeneratio[...] |
19 | | -- Contains the **full** iso9660-rs implementation: A pure no_std, Rust ISO9660 and El Torito parser/reader, written for MorpheusX and developed in this repository; enables direct extraction and booting[...] |
20 | | -- Implements a custom, standalone FAT32 filesystem library: Written from scratch for this project (no_std, Rust), enabling direct parsing, allocation, and manipulation of FAT32 volumes and boot records[...] |
| 18 | +### Hardware Init (`hwinit/`) |
21 | 19 |
|
22 | | ---- |
| 20 | +Eleven initialization phases that transform raw x86-64 hardware into a sane execution environment — all after UEFI has been dismissed: |
23 | 21 |
|
24 | | -### Building |
| 22 | +1. Physical memory ownership — parse the UEFI memory map, punch holes around live page tables, hand everything to a binary buddy allocator |
| 23 | +2. CPU state — install our own GDT/TSS, load our IDT, set up IST stacks for double faults |
| 24 | +3. Interrupt routing — remap the 8259 PIC so IRQs don't collide with CPU exceptions |
| 25 | +4. Heap — 4 MB initial slab backed by the buddy allocator, with overflow support |
| 26 | +5. TSC calibration — PIT-based, no UEFI timer services required |
| 27 | +6. DMA region — 2 MB pre-allocated below 4 GB, identity-mapped |
| 28 | +7. PCI discovery — bus/device/function scan, BAR decode, bus mastering enable |
| 29 | +8. Paging — adopt UEFI's page tables, clear CR0.WP so we can modify them, build per-process PML4s from there |
| 30 | +9. Scheduler — 64-slot static process table, round-robin preemptive, no heap in the hot path |
| 31 | +10. Syscall interface — `SYSCALL`/`SYSRET` trampoline written in ASM, dispatches 75 syscalls |
| 32 | +11. Root filesystem — mount HelixFS on the block device and hand `/` to userspace |
25 | 33 |
|
26 | | -Prerequisites: Rust 1.75+ with `rustup`, target `x86_64-unknown-uefi`, and a nightly or stable toolchain that supports `no_std` UEFI builds. |
| 34 | +### Memory (`hwinit/src/memory.rs`) |
27 | 35 |
|
28 | | -```bash |
29 | | -rustup target add x86_64-unknown-uefi |
30 | | -cargo build --release --target x86_64-unknown-uefi |
31 | | -``` |
| 36 | +Binary buddy allocator over the full physical address space. No per-page descriptor array, no bitmap. Free-list nodes live inside the free pages themselves (intrusive list). The entire allocator struct is ~13 KiB in BSS. `MAX_ORDER = 26` means a maximum single contiguous allocation of 256 GiB — bump one constant to reach 1 TiB. |
32 | 37 |
|
33 | | -*Or you just use the `/setup-dev.sh` shell utility* |
| 38 | +### Scheduler + Processes (`hwinit/src/process/`) |
34 | 39 |
|
35 | | -It offers diverse preconfigured worflows. To see them just use: |
| 40 | +Fixed-size `[Option<Process>; 64]` static array — zero heap allocation in the scheduler path. PID 0 is the kernel/desktop event loop and never sleeps indefinitely. User processes get their own PML4, a 32 KiB kernel stack, a VMA table, a file descriptor table, and a CWD. Context switches happen in assembly (`context_switch.s`) via the PIT timer ISR. |
36 | 41 |
|
37 | | -```bash |
38 | | -./setup-dev.sh -h |
39 | | -``` |
| 42 | +POSIX-lite signals: SIGINT, SIGKILL, SIGSEGV, SIGTERM, SIGCHLD, SIGSTOP, SIGCONT — delivered before the next process resume. |
40 | 43 |
|
41 | | -Or if you want to automatically setup the whole environment, build and run qemu just use: |
| 44 | +### Syscall Interface (`hwinit/src/syscall/`) |
42 | 45 |
|
43 | | -```bash |
44 | | -./setup-dev.sh |
45 | | -``` |
| 46 | +75 syscalls covering: |
| 47 | + |
| 48 | +| Category | Calls | |
| 49 | +|---|---| |
| 50 | +| Process | `exit`, `getpid`, `getppid`, `kill`, `wait`, `sleep`, `yield`, `spawn`, `ps`, `sigaction`, `setpriority`, `getpriority` | |
| 51 | +| Memory | `alloc`, `free`, `mmap`, `munmap`, `mprotect`, `shm_grant`, `map_phys`, `virt_to_phys`, `dma_alloc`, `dma_free` | |
| 52 | +| Filesystem | `open`, `close`, `read`, `write`, `seek`, `stat`, `readdir`, `mkdir`, `unlink`, `rename`, `truncate`, `sync`, `snapshot`, `versions` | |
| 53 | +| Network | `nic_info`, `nic_tx`, `nic_rx`, `nic_link`, `nic_mac`, `nic_refill`, `nic_ctrl`, `net`, `dns`, `net_cfg`, `net_poll` | |
| 54 | +| Hardware | `port_in`, `port_out`, `pci_cfg_read`, `pci_cfg_write`, `irq_attach`, `irq_ack`, `cache_flush`, `cpuid`, `rdtsc`, `fb_info`, `fb_map` | |
| 55 | +| Misc | `clock`, `sysinfo`, `getcwd`, `chdir`, `dup`, `poll`, `ioctl`, `mount`, `umount`, `syslog`, `boot_log`, `memmap`, `pe_info`, `persist_*` | |
| 56 | + |
| 57 | +Every syscall validates user-supplied pointers against the canonical address split (`0x0000_8000_0000_0000`) before touching them. |
| 58 | + |
| 59 | +### HelixFS (`helix/`) |
| 60 | + |
| 61 | +A log-structured, append-only, crash-safe filesystem built from scratch: |
| 62 | + |
| 63 | +- **Dual superblock** — two alternating copies, recovery picks the higher committed LSN with a valid CRC |
| 64 | +- **Log append-only** — every write is a versioned LSN record; crash recovery scans forward from the last valid checkpoint and stops at the first bad CRC |
| 65 | +- **Per-inode versioning** — every write to a file creates a new log record, enabling time-travel reads |
| 66 | +- **Checkpoint-guarded B-tree index** — the namespace index exists in RAM between checkpoints and is only flushed to disk as part of a checkpoint log record |
| 67 | +- **CRC32C** on every record; **CRC64** content deduplication fingerprinting on write payloads |
| 68 | +- AHCI and VirtIO block drivers |
46 | 69 |
|
47 | | -The bootable binary is produced at `target/x86_64-unknown-uefi/release/morpheus-bootloader.efi`. |
| 70 | +The VFS layer exposes open/close/read/write/seek/stat/readdir/mkdir/unlink/rename/sync to both the kernel and userspace through the syscall table. |
| 71 | + |
| 72 | +### Network (`network/`) |
| 73 | + |
| 74 | +A bare-metal network stack that runs entirely after `ExitBootServices`: |
| 75 | + |
| 76 | +- **VirtIO NIC** and **Intel e1000e** drivers — full brutal reset on init (no UEFI state assumptions), TX/RX ring management, MAC, link status, promisc mode, VLAN, checksum offload controls |
| 77 | +- **VirtIO block** driver for disk I/O during download |
| 78 | +- **DHCP → DNS → TCP → HTTP** state machine pipeline for downloading ISOs and images at boot |
| 79 | +- NIC operations are bridged to the kernel via a function-pointer table (`NicOps`) so `hwinit` stays driver-agnostic |
| 80 | + |
| 81 | +### Display + TUI (`display/`, `bootloader/src/tui/`) |
| 82 | + |
| 83 | +- Framebuffer backend (RGBX / BGRX), 8×16 bitmap font, pixel ops in hand-written x86-64 assembly |
| 84 | +- `TextConsole` with scrolling — all boot log output mirrors live to the screen from phase 1 onward |
| 85 | +- Desktop event loop with a window manager, a command shell, and built-in apps: |
| 86 | + - **Storage Manager** — browse and manage HelixFS volumes |
| 87 | + - **Task Manager** — live process table, CPU ticks, memory pages, priorities |
| 88 | + - **Rain** screensaver because why not |
| 89 | + |
| 90 | +### Crash Handling |
| 91 | + |
| 92 | +Every CPU exception (vectors 0–21) produces a rich `CrashInfo` struct — all 15 general-purpose registers, CR2/CR3, the faulting process name and PID, user/kernel mode flag, a best-effort RBP frame chain backtrace (up to 16 frames), and a human-readable one-line explanation of what went wrong ("Attempted to write to unmapped memory at 0x..."). This drives a full-screen BSoD rendered directly to the framebuffer with no allocation. |
| 93 | + |
| 94 | +### SDK (`libmorpheus/`) |
| 95 | + |
| 96 | +A `no_std` userspace syscall wrapper library. Covers process management, filesystem I/O, memory mapping, networking, hardware access, persistence, and timing — enough to write real MorpheusX applications without touching raw `syscall` instructions. |
| 97 | + |
| 98 | +### `iso9660` (standalone crate) |
| 99 | + |
| 100 | +A pure `no_std` Rust ISO 9660 and El Torito parser, developed in this repository and published separately. Used by MorpheusX to extract and boot from disc images. |
48 | 101 |
|
49 | 102 | --- |
50 | 103 |
|
51 | | -### Running in QEMU |
| 104 | +## Building |
| 105 | + |
| 106 | +```bash |
| 107 | +./setup-dev.sh -f # One-time environment setup (installs toolchain, QEMU, OVMF) |
| 108 | +./setup-dev.sh -h # Show all available workflows |
| 109 | +./setup-dev.sh run # Build and boot in QEMU |
| 110 | +``` |
52 | 111 |
|
53 | | -Use the provided scripts (requires QEMU and OVMF): |
| 112 | +Or manually: |
54 | 113 |
|
55 | 114 | ```bash |
56 | | -./setup-dev.sh run |
| 115 | +rustup target add x86_64-unknown-uefi |
| 116 | +cargo build --release --target x86_64-unknown-uefi -p morpheus-bootloader |
57 | 117 | ``` |
58 | 118 |
|
59 | | -See additional helper scripts in `testing/` for preparing initrds and disk images. |
| 119 | +The EFI binary lands at `target/x86_64-unknown-uefi/release/morpheus-bootloader.efi`. |
| 120 | + |
| 121 | +Requirements: Rust 1.75+, `x86_64-unknown-uefi` target, QEMU + OVMF for testing. |
60 | 122 |
|
61 | 123 | --- |
62 | 124 |
|
63 | | -### CI/CD Pipeline |
| 125 | +## Running |
64 | 126 |
|
65 | | -The project uses GitHub Actions for continuous integration: |
| 127 | +```bash |
| 128 | +./setup-dev.sh run |
| 129 | +``` |
66 | 130 |
|
67 | | -| Workflow | Purpose | |
68 | | -|----------|---------| |
69 | | -| **CI** | Lint (rustfmt, clippy), build, and test on host | |
70 | | -| **UEFI Build** | 2-pass build for relocation embedding | |
71 | | -| **UEFI E2E** | Boot test in QEMU with OVMF | |
72 | | -| **Security Audit** | Weekly cargo-audit and cargo-deny | |
73 | | -| **Release** | Automated releases on version tags | |
| 131 | +Boot messages appear on both serial (stdout in QEMU) and the framebuffer simultaneously. A 1920×1080 desktop loads when hardware init completes. Type `help` in the shell; `open storage` launches the Storage Manager. |
74 | 132 |
|
75 | | -#### Local CI Scripts |
| 133 | +--- |
76 | 134 |
|
77 | | -```bash |
78 | | -# Build UEFI bootloader (2-pass with reloc embedding) |
79 | | -./scripts/ci-build-uefi.sh |
| 135 | +## Testing |
80 | 136 |
|
81 | | -# Run E2E boot test |
| 137 | +```bash |
| 138 | +# Build and E2E boot test in QEMU |
82 | 139 | ./scripts/qemu-e2e.sh target/x86_64-unknown-uefi/release/morpheus-bootloader.efi |
83 | 140 |
|
84 | | -# Generate test fixtures (ISO, FAT images) |
| 141 | +# Generate test fixtures (disk images, ISOs) |
85 | 142 | ./scripts/gen-fixtures.sh fixtures/ |
| 143 | + |
| 144 | +# Run syscall E2E tests |
| 145 | +cargo test -p morpheus-syscall-e2e |
86 | 146 | ``` |
87 | 147 |
|
| 148 | +Additional helper scripts for disk image and initrd preparation are in `testing/`. |
| 149 | + |
88 | 150 | --- |
89 | 151 |
|
90 | | -### Project Status |
| 152 | +## CI |
91 | 153 |
|
92 | | -This is experimental, not production-hardened, and the network and persistence layers are still under construction. Expect sharp edges and incomplete flows. |
| 154 | +| Workflow | What it does | |
| 155 | +|---|---| |
| 156 | +| **CI** | `rustfmt`, `clippy`, build, host tests | |
| 157 | +| **UEFI Build** | 2-pass build (first pass extracts relocations, second embeds them) | |
| 158 | +| **UEFI E2E** | Full boot test in QEMU + OVMF, serial output verified | |
| 159 | +| **Security Audit** | Weekly `cargo-audit` and `cargo-deny` | |
| 160 | +| **Release** | Automated EFI binary release on version tags | |
93 | 161 |
|
94 | 162 | --- |
95 | 163 |
|
96 | | -### Additional Documentation |
| 164 | +## Project Status |
97 | 165 |
|
98 | | -Can be found in `/docs`. |
| 166 | +The core is solid. The boot sequence, memory manager, scheduler, paging, HelixFS, the syscall interface, and the display stack all work. A real shell runs. User processes spawn, context-switch, and exit cleanly. The network drivers initialize real hardware. |
| 167 | + |
| 168 | +What's missing or incomplete: APIC support (8259 PIC only for now), `SYS_SIGACTION` handler storage in the process struct, arbitrary-size `truncate`, SMEP/SMAP enforcement, ASLR, and SMP (explicitly out of scope for the current design). The network stack's URL parsing is a placeholder. The ESP persistence backend is not implemented. |
| 169 | + |
| 170 | +This is a new thing. The foundation is unusually clean for a project at this stage. There is real work to do and real ground to cover — which makes it a good time to get involved. |
99 | 171 |
|
100 | 172 | --- |
101 | 173 |
|
102 | | -### Contributing |
| 174 | +## Documentation |
103 | 175 |
|
104 | | -See [CONTRIBUTING.md](CONTRIBUTING.md) for how to set up the toolchain, run builds/tests, and send focused PRs. |
| 176 | +- `docs/SDK.md` — application development guide |
| 177 | +- `docs/md/` — architecture deep-dives, ABI reference, hardware init inventory |
| 178 | +- `hwinit/ARCHITECTURE.md` — hardware init module map |
| 179 | +- `iso9660/ARCHITECTURE.md` — ISO 9660 parser design |
105 | 180 |
|
106 | 181 | --- |
107 | 182 |
|
108 | | -### Support |
| 183 | +## Contributing |
109 | 184 |
|
110 | | -For technical assistance, please contact our [24/7 support team](https://www.nsa.gov). |
| 185 | +See [CONTRIBUTING.md](CONTRIBUTING.md) for toolchain setup, build workflows, and PR conventions. The codebase is extensively commented — every module has an architecture doc block explaining invariants and what it does not do. |
| 186 | + |
| 187 | +Good starting points: SMEP/SMAP enforcement in `hwinit/src/cpu/`, signal handler storage in `hwinit/src/process/mod.rs`, wiring `vfs_versions()` through to `SYS_VERSIONS`, or picking up any module marked with a `// TODO` comment. |
| 188 | + |
| 189 | +--- |
| 190 | + |
| 191 | +## License |
| 192 | + |
| 193 | +GPL-3.0-or-later. See [LICENSE-GPL-3.0](LICENSE-GPL-3.0). |
| 194 | + |
| 195 | +The `iso9660` subcrate is dual-licensed MIT / Apache-2.0 for standalone use. |
111 | 196 |
|
112 | 197 | --- |
113 | 198 |
|
| 199 | +## Support |
| 200 | + |
| 201 | +For technical assistance, please contact our [24/7 support team](https://www.nsa.gov). |
| 202 | + |
114 | 203 | ### License |
115 | 204 |
|
116 | 205 | Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option. |
|
0 commit comments