Microkernel based hobby OS

first commit

+15
.claude/settings.local.json
··· 1 + { 2 + "permissions": { 3 + "allow": [ 4 + "Bash(rustc:*)", 5 + "Bash(cargo --version:*)", 6 + "Bash(cargo build:*)", 7 + "Bash(cargo tree:*)", 8 + "Bash(grep:*)", 9 + "Bash(1)", 10 + "Bash(cargo clippy:*)" 11 + ], 12 + "deny": [], 13 + "ask": [] 14 + } 15 + }
+429
aethelos-source/ARCHITECTURE.txt
··· 1 + ╔══════════════════════════════════════════════════════════════════════════════╗ 2 + ║ AethelOS Architecture ║ 3 + ║ "Symbiotic Computing in Action" ║ 4 + ╚══════════════════════════════════════════════════════════════════════════════╝ 5 + 6 + ┌──────────────────────────────────────────────────────────────────────────────┐ 7 + │ USER SPACE │ 8 + │ │ 9 + │ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ 10 + │ │ Applications │ │ Applications │ │ Applications │ │ 11 + │ │ │ │ │ │ │ │ 12 + │ └────────┬───────┘ └────────┬───────┘ └────────┬───────┘ │ 13 + │ │ │ │ │ 14 + │ └───────────────────┴───────────────────┘ │ 15 + │ │ │ 16 + │ ┌──────────▼──────────┐ │ 17 + │ │ Ancient Runes │ │ 18 + │ │ (Core Libraries) │ │ 19 + │ │ │ │ 20 + │ │ • Corelib │ │ 21 + │ │ • Weaving API │ │ 22 + │ │ • Eldarin Script │ │ 23 + │ └──────────┬──────────┘ │ 24 + │ │ │ 25 + │ ┌───────────────────┴───────────────────┐ │ 26 + │ │ │ │ 27 + │ ┌────────▼─────────┐ ┌─────────────┐ ┌───────▼────────┐ │ 28 + │ │ World-Tree │ │ Lanthir │ │ The Weave │ │ 29 + │ │ Grove │ │ Grove │ │ Grove │ │ 30 + │ │ (Filesystem) │ │ (WM) │ │ (Compositor) │ │ 31 + │ └────────┬─────────┘ └──────┬──────┘ └────────┬───────┘ │ 32 + │ │ │ │ │ 33 + │ └───────────────────┴───────────────────┘ │ 34 + │ │ │ 35 + │ ┌──────────▼──────────┐ │ 36 + │ │ Network Sprite │ │ 37 + │ │ (Network Daemon) │ │ 38 + │ └──────────┬──────────┘ │ 39 + └───────────────────────────────┼───────────────────────────────────────────┘ 40 + 41 + ════════════════════════════════╪════════════════════════════════════════════ 42 + │ System Call Interface (via Nexus) 43 + ════════════════════════════════╪════════════════════════════════════════════ 44 + 45 + ┌───────────────────────────────▼───────────────────────────────────────────┐ 46 + │ KERNEL SPACE (The Heartwood) │ 47 + │ │ 48 + │ ┌─────────────────────────────────────────────────────────────────────┐ │ 49 + │ │ The Nexus │ │ 50 + │ │ (Inter-Process Communication Core) │ │ 51 + │ │ │ │ 52 + │ │ • Asynchronous message passing │ │ 53 + │ │ • Capability-based channels │ │ 54 + │ │ • Priority-aware routing │ │ 55 + │ │ • Zero-copy where possible │ │ 56 + │ └─────────────────────┬───────────────────────┬───────────────────────┘ │ 57 + │ │ │ │ 58 + │ ┌────────────▼────────────┐ ┌──────▼───────────────┐ │ 59 + │ │ Loom of Fate │ │ Mana Pool │ │ 60 + │ │ (Scheduler) │ │ (Memory Manager) │ │ 61 + │ │ │ │ │ │ 62 + │ │ • Harmony-based │ │ • Capability-based │ │ 63 + │ │ • Cooperative │ │ • Object-oriented │ │ 64 + │ │ • Parasite detection │ │ • Purpose-driven │ │ 65 + │ │ │ │ │ │ 66 + │ │ Thread States: │ │ Regions: │ │ 67 + │ │ - Weaving │ │ - Sanctuary │ │ 68 + │ │ - Resting │ │ - Ephemeral Mist │ │ 69 + │ │ - Tangled │ │ │ │ 70 + │ │ - Fading │ │ │ │ 71 + │ └────────────┬────────────┘ └──────┬───────────────┘ │ 72 + │ │ │ │ 73 + │ └──────────┬───────────┘ │ 74 + │ │ │ 75 + │ ┌──────────▼──────────┐ │ 76 + │ │ Attunement Layer │ │ 77 + │ │ (Hardware HAL) │ │ 78 + │ │ │ │ 79 + │ │ • CPU management │ │ 80 + │ │ • Interrupts │ │ 81 + │ │ • Timers │ │ 82 + │ └──────────┬──────────┘ │ 83 + └───────────────────────────────────┼───────────────────────────────────────┘ 84 + 85 + ════════════════════════════════════╪════════════════════════════════════════ 86 + │ Hardware Interface 87 + ════════════════════════════════════╪════════════════════════════════════════ 88 + 89 + ┌───────────────────────────────────▼───────────────────────────────────────┐ 90 + │ HARDWARE │ 91 + │ │ 92 + │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 93 + │ │ CPU │ │ Memory │ │ Disk │ │ Network │ │ GPU │ │ 94 + │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ 95 + └────────────────────────────────────────────────────────────────────────────┘ 96 + 97 + 98 + ═══════════════════════════════════════════════════════════════════════════════ 99 + KEY CONCEPTS 100 + ═══════════════════════════════════════════════════════════════════════════════ 101 + 102 + ┌──────────────────────────────────────────────────────────────────────────────┐ 103 + │ THE NEXUS - Communication Backbone │ 104 + │ │ 105 + │ Process A Process B │ 106 + │ │ │ │ 107 + │ │ (ChannelCapability) │ │ 108 + │ ▼ ▼ │ 109 + │ ┌────────┐ ┌────────┐ │ 110 + │ │Channel │ ◄─────────── Nexus Core ──────────► │Channel │ │ 111 + │ └────────┘ (Router) └────────┘ │ 112 + │ │ │ │ 113 + │ └──────────────► Message Queue ◄───────────────┘ │ 114 + │ (Priority-ordered) │ 115 + └──────────────────────────────────────────────────────────────────────────────┘ 116 + 117 + ┌──────────────────────────────────────────────────────────────────────────────┐ 118 + │ THE LOOM OF FATE - Harmony-Based Scheduling │ 119 + │ │ 120 + │ Threads ──► Harmony Analyzer ──► Scheduler ──► CPU │ 121 + │ │ │ 122 + │ └──► Scores (0.0 - 1.0) │ 123 + │ │ │ 124 + │ ├─► > 0.7: Harmonious │ 125 + │ ├─► 0.3 - 0.7: Normal │ 126 + │ └─► < 0.3: Parasitic (throttle) │ 127 + └──────────────────────────────────────────────────────────────────────────────┘ 128 + 129 + ┌──────────────────────────────────────────────────────────────────────────────┐ 130 + │ THE MANA POOL - Capability-Based Memory │ 131 + │ │ 132 + │ User Process │ 133 + │ │ │ 134 + │ │ (ObjectHandle - no raw pointers!) │ 135 + │ ▼ │ 136 + │ Object Manager │ 137 + │ │ │ 138 + │ ├─► Sanctuary (long-lived, stable) │ 139 + │ └─► Ephemeral Mist (short-lived, volatile) │ 140 + │ │ │ 141 + │ ▼ │ 142 + │ Physical Memory (protected by MMU) │ 143 + └──────────────────────────────────────────────────────────────────────────────┘ 144 + 145 + ┌──────────────────────────────────────────────────────────────────────────────┐ 146 + │ WORLD-TREE FILESYSTEM - Query-Based │ 147 + │ │ 148 + │ Traditional: /home/user/docs/file.txt │ 149 + │ │ 150 + │ AethelOS: Seek { │ 151 + │ essence: "Scroll", │ 152 + │ creator: "Elara", │ 153 + │ name: "file" │ 154 + │ } │ 155 + │ │ 156 + │ ┌──────────┐ │ 157 + │ │ Query │ ──► Database Index ──► File Objects │ 158 + │ └──────────┘ │ │ 159 + │ ├─► Metadata │ 160 + │ ├─► Data │ 161 + │ └─► Version History │ 162 + └──────────────────────────────────────────────────────────────────────────────┘ 163 + 164 + ┌──────────────────────────────────────────────────────────────────────────────┐ 165 + │ THE WEAVE - Vector Graphics Compositor │ 166 + │ │ 167 + │ Scene Graph ──► Transform ──► Rasterize ──► Shaders ──► Framebuffer │ 168 + │ │ (Glyphs) │ 169 + │ │ │ 170 + │ ├─► Window 1 (Bézier shape) │ 171 + │ │ ├─► Title Bar │ 172 + │ │ └─► Content │ 173 + │ │ │ 174 + │ └─► Window 2 (Custom shape) │ 175 + │ └─► Widgets │ 176 + │ │ 177 + │ All rendering is vector-based (resolution-independent) │ 178 + └──────────────────────────────────────────────────────────────────────────────┘ 179 + 180 + 181 + ═══════════════════════════════════════════════════════════════════════════════ 182 + DATA FLOW EXAMPLES 183 + ═══════════════════════════════════════════════════════════════════════════════ 184 + 185 + Example 1: Application Opens a File 186 + ─────────────────────────────────── 187 + 188 + Application 189 + 190 + │ Query: Seek { essence: "Scroll", name: "config" } 191 + 192 + Ancient Runes (Corelib) 193 + 194 + │ Message: FileQuery { ... } 195 + 196 + Nexus (IPC) 197 + 198 + │ Route to World-Tree Grove 199 + 200 + World-Tree Grove 201 + 202 + │ Database lookup 203 + 204 + │ Request memory capability 205 + 206 + Nexus → Heartwood → Mana Pool 207 + 208 + │ Grant ObjectHandle 209 + 210 + │ Return FileObject with handle 211 + 212 + Application receives handle (not raw pointer!) 213 + 214 + 215 + Example 2: Window Drag Animation 216 + ───────────────────────────────── 217 + 218 + User Input (Mouse Move) 219 + 220 + 221 + Lanthir Grove (Window Manager) 222 + 223 + │ Update window position 224 + │ Apply ripple transformation 225 + 226 + The Weave Grove (Compositor) 227 + 228 + │ Modify scene graph node 229 + │ Apply distortion glyph (shader) 230 + 231 + │ Render to framebuffer 232 + 233 + GPU → Display 234 + 235 + 236 + Example 3: Parasite Detection 237 + ────────────────────────────── 238 + 239 + Thread running 240 + 241 + │ Resource usage monitored 242 + 243 + Loom of Fate (Scheduler) 244 + 245 + │ Harmony Analyzer runs 246 + 247 + │ Detect: harmony_score < 0.3 248 + 249 + │ Throttle thread (reduce CPU allocation) 250 + │ Send DisharmonyAlert message to parent 251 + 252 + Parent process 253 + 254 + │ Receive alert, decide action 255 + └──► Can request thread termination if needed 256 + 257 + 258 + ═══════════════════════════════════════════════════════════════════════════════ 259 + SECURITY MODEL 260 + ═══════════════════════════════════════════════════════════════════════════════ 261 + 262 + Capability Propagation 263 + ────────────────────── 264 + 265 + Process A (has FileCapability) 266 + 267 + │ Can create derived capability with FEWER rights 268 + 269 + Derived Capability (READ only) 270 + 271 + │ Can transfer to Process B 272 + 273 + Process B (receives READ-only capability) 274 + 275 + │ CANNOT escalate to WRITE 276 + └──► Security enforced by kernel 277 + 278 + 279 + Isolation Boundaries 280 + ──────────────────── 281 + 282 + Hardware (Ring 0) 283 + 284 + │ MMU enforces memory boundaries 285 + 286 + Heartwood (Ring 0) 287 + 288 + │ Capability checks 289 + 290 + Groves (Ring 3) 291 + 292 + │ Message passing via Nexus 293 + 294 + Applications (Ring 3) 295 + 296 + 297 + ═══════════════════════════════════════════════════════════════════════════════ 298 + MEMORY LAYOUT (x86_64) 299 + ═══════════════════════════════════════════════════════════════════════════════ 300 + 301 + 0xFFFF_FFFF_FFFF_FFFF ┬───────────────────────────────── 302 + 303 + │ Kernel Stack 304 + 305 + 0xFFFF_A000_0000_0000 ├───────────────────────────────── 306 + 307 + │ Device Memory (MMIO) 308 + 309 + 0xFFFF_9000_0000_0000 ├───────────────────────────────── 310 + 311 + │ Kernel Heap (Mana Pool) 312 + 313 + 0xFFFF_8000_0000_0000 ├───────────────────────────────── 314 + 315 + │ Kernel Code (.text, .data) 316 + 317 + ╞═════════════════════════════════ 318 + │ Non-canonical addresses 319 + ╞═════════════════════════════════ 320 + 321 + │ User Space Heap 322 + 323 + 0x0000_4000_0000_0000 ├───────────────────────────────── 324 + 325 + │ User Space Stack 326 + │ (grows downward) 327 + 328 + 0x0000_0000_0040_0000 ├───────────────────────────────── 329 + 330 + │ User Space Code 331 + 332 + 0x0000_0000_0000_1000 ├───────────────────────────────── 333 + │ Null page (unmapped) 334 + 0x0000_0000_0000_0000 └───────────────────────────────── 335 + 336 + 337 + ═══════════════════════════════════════════════════════════════════════════════ 338 + BOOT SEQUENCE 339 + ═══════════════════════════════════════════════════════════════════════════════ 340 + 341 + 1. BIOS/UEFI 342 + 343 + │ Load boot sector into 0x7c00 344 + 345 + 2. boot.asm (First Spark) 346 + 347 + │ Initialize hardware 348 + │ Load second stage 349 + 350 + 3. heartwood_loader (Second Stage) 351 + 352 + │ Enable protected mode 353 + │ Set up paging 354 + │ Map kernel to higher half 355 + │ Load kernel ELF 356 + 357 + 4. Heartwood kernel (_start) 358 + 359 + ├──► Initialize VGA buffer 360 + ├──► Initialize Mana Pool 361 + ├──► Initialize Nexus 362 + ├──► Initialize Loom of Fate 363 + ├──► Initialize Attunement Layer 364 + 365 + ├──► Spawn World-Tree Grove 366 + ├──► Spawn The Weave Grove 367 + ├──► Spawn Lanthir Grove 368 + └──► Spawn Network Sprite 369 + 370 + 371 + 5. System Ready 372 + 373 + │ The Heartwood lives! 374 + └──► Eternal loop (hlt) 375 + 376 + 377 + ═══════════════════════════════════════════════════════════════════════════════ 378 + FILE STRUCTURE 379 + ═══════════════════════════════════════════════════════════════════════════════ 380 + 381 + aethelos-source/ 382 + 383 + ├── GENESIS.scroll ← Philosophy and high-level design 384 + ├── DESIGN.md ← Technical deep dive 385 + ├── ARCHITECTURE.txt ← This file 386 + ├── README.md ← Project overview 387 + ├── QUICKSTART.md ← Getting started guide 388 + ├── Makefile ← Build system 389 + ├── Cargo.toml ← Rust workspace config 390 + 391 + ├── awakening/ ← Bootloader 392 + │ ├── boot.asm ← 16-bit real mode boot sector 393 + │ └── heartwood_loader/ ← 32/64-bit loader 394 + 395 + ├── heartwood/ ← The Kernel 396 + │ ├── src/ 397 + │ │ ├── main.rs ← Kernel entry point 398 + │ │ ├── lib.rs ← Kernel library exports 399 + │ │ ├── vga_buffer.rs ← Early console output 400 + │ │ ├── nexus/ ← IPC system 401 + │ │ ├── loom_of_fate/ ← Scheduler 402 + │ │ ├── mana_pool/ ← Memory manager 403 + │ │ └── attunement/ ← Hardware abstraction 404 + │ └── Cargo.toml 405 + 406 + ├── groves/ ← User-space services 407 + │ ├── world-tree_grove/ ← Filesystem 408 + │ ├── the-weave_grove/ ← Compositor 409 + │ ├── lanthir_grove/ ← Window manager 410 + │ └── network_sprite/ ← Network daemon 411 + 412 + └── ancient-runes/ ← Core libraries 413 + ├── corelib/ ← Standard library 414 + ├── weaving/ ← GUI toolkit 415 + └── script/ ← Shell API 416 + 417 + 418 + ═══════════════════════════════════════════════════════════════════════════════ 419 + END OF ARCHITECTURE DIAGRAM 420 + ═══════════════════════════════════════════════════════════════════════════════ 421 + 422 + For more information: 423 + • Read GENESIS.scroll for the philosophy 424 + • Read DESIGN.md for technical details 425 + • Read QUICKSTART.md to get started 426 + • Read the source code - it's the ultimate documentation! 427 + 428 + "The code does not command the silicon. The silicon does not serve the code. 429 + They dance together, and in that dance, life emerges."
+89
aethelos-source/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "bitflags" 7 + version = "1.3.2" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 10 + 11 + [[package]] 12 + name = "corelib" 13 + version = "0.1.0" 14 + 15 + [[package]] 16 + name = "heartwood" 17 + version = "0.1.0" 18 + dependencies = [ 19 + "bitflags", 20 + "lazy_static", 21 + "spin", 22 + ] 23 + 24 + [[package]] 25 + name = "heartwood_loader" 26 + version = "0.1.0" 27 + 28 + [[package]] 29 + name = "lanthir_grove" 30 + version = "0.1.0" 31 + 32 + [[package]] 33 + name = "lazy_static" 34 + version = "1.5.0" 35 + source = "registry+https://github.com/rust-lang/crates.io-index" 36 + checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 37 + dependencies = [ 38 + "spin", 39 + ] 40 + 41 + [[package]] 42 + name = "lock_api" 43 + version = "0.4.14" 44 + source = "registry+https://github.com/rust-lang/crates.io-index" 45 + checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" 46 + dependencies = [ 47 + "scopeguard", 48 + ] 49 + 50 + [[package]] 51 + name = "network_sprite" 52 + version = "0.1.0" 53 + 54 + [[package]] 55 + name = "scopeguard" 56 + version = "1.2.0" 57 + source = "registry+https://github.com/rust-lang/crates.io-index" 58 + checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 59 + 60 + [[package]] 61 + name = "script" 62 + version = "0.1.0" 63 + dependencies = [ 64 + "corelib", 65 + ] 66 + 67 + [[package]] 68 + name = "spin" 69 + version = "0.9.8" 70 + source = "registry+https://github.com/rust-lang/crates.io-index" 71 + checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 72 + dependencies = [ 73 + "lock_api", 74 + ] 75 + 76 + [[package]] 77 + name = "the-weave_grove" 78 + version = "0.1.0" 79 + 80 + [[package]] 81 + name = "weaving" 82 + version = "0.1.0" 83 + dependencies = [ 84 + "corelib", 85 + ] 86 + 87 + [[package]] 88 + name = "world-tree_grove" 89 + version = "0.1.0"
+48
aethelos-source/Cargo.toml
··· 1 + [workspace] 2 + resolver = "2" 3 + members = [ 4 + "heartwood", 5 + "awakening/heartwood_loader", 6 + "groves/world-tree_grove", 7 + "groves/the-weave_grove", 8 + "groves/lanthir_grove", 9 + "groves/network_sprite", 10 + "ancient-runes/corelib", 11 + "ancient-runes/weaving", 12 + "ancient-runes/script", 13 + ] 14 + 15 + [workspace.package] 16 + version = "0.1.0" 17 + authors = ["AethelOS Contributors"] 18 + edition = "2021" 19 + rust-version = "1.75" 20 + license = "MIT OR Apache-2.0" 21 + 22 + [workspace.dependencies] 23 + # Core dependencies for OS development 24 + spin = "0.9" 25 + bitflags = "1.3" 26 + volatile = "0.5" 27 + lazy_static = { version = "1.4", features = ["spin_no_std"] } 28 + 29 + # Data structures 30 + heapless = "0.8" 31 + 32 + # Boot and low-level 33 + bootloader = "0.9" 34 + x86_64 = "0.15" 35 + uart_16550 = "0.3" 36 + 37 + # Async runtime (for the Nexus) 38 + async-trait = "0.1" 39 + 40 + [profile.dev] 41 + panic = "abort" 42 + 43 + [profile.release] 44 + panic = "abort" 45 + lto = true 46 + codegen-units = 1 47 + opt-level = 3 48 + strip = true
+552
aethelos-source/DESIGN.md
··· 1 + # AethelOS Design Document 2 + 3 + ## Table of Contents 4 + 5 + 1. [Introduction](#introduction) 6 + 2. [Core Philosophy](#core-philosophy) 7 + 3. [Architectural Decisions](#architectural-decisions) 8 + 4. [The Heartwood (Kernel)](#the-heartwood-kernel) 9 + 5. [The Groves (User Space)](#the-groves-user-space) 10 + 6. [Ancient Runes (Libraries)](#ancient-runes-libraries) 11 + 7. [Implementation Details](#implementation-details) 12 + 8. [Security Model](#security-model) 13 + 9. [Future Work](#future-work) 14 + 15 + --- 16 + 17 + ## Introduction 18 + 19 + AethelOS is an experimental operating system designed to explore radical alternatives to conventional OS design. Rather than optimizing purely for performance or compatibility, AethelOS prioritizes: 20 + 21 + - **Harmony**: System-wide equilibrium over individual process optimization 22 + - **Longevity**: 100-year design timescales 23 + - **Beauty**: Aesthetics as a first-class design principle 24 + - **Symbiosis**: Cooperation between user, OS, and hardware 25 + 26 + This document explains the technical decisions behind the philosophy. 27 + 28 + --- 29 + 30 + ## Core Philosophy 31 + 32 + ### Symbiotic Computing 33 + 34 + Traditional operating systems establish a hierarchy: 35 + ``` 36 + User → OS → Hardware 37 + ``` 38 + 39 + AethelOS establishes a triangle of mutual dependence: 40 + ``` 41 + User 42 + / \ 43 + / \ 44 + OS ←→ Hardware 45 + ``` 46 + 47 + Each component: 48 + - **Respects** the limitations of the others 49 + - **Negotiates** rather than demands 50 + - **Adapts** to changing conditions 51 + 52 + ### Implications 53 + 54 + This philosophy manifests in concrete design choices: 55 + 56 + 1. **Cooperative Scheduling**: Threads yield voluntarily, guided by harmony metrics 57 + 2. **Resource Negotiation**: Processes request resources and can be denied 58 + 3. **Graceful Degradation**: No component ever crashes the entire system 59 + 4. **Transparent State**: The UI reveals system state through living metaphors 60 + 61 + --- 62 + 63 + ## Architectural Decisions 64 + 65 + ### Why a Hybrid Microkernel? 66 + 67 + **Decision**: Use a minimal kernel (microkernel philosophy) with some performance-critical services in kernel space (hybrid approach). 68 + 69 + **Rationale**: 70 + - **Security**: Small trusted computing base (TCB) 71 + - **Resilience**: Driver crashes don't kill the kernel 72 + - **Flexibility**: Services can be replaced without rebooting 73 + - **Performance**: Critical paths (IPC, memory) optimized in kernel 74 + 75 + **Comparison**: 76 + - **vs Monolithic** (Linux): Better isolation, worse performance 77 + - **vs Pure Microkernel** (L4): Better performance, slightly larger TCB 78 + - **vs Exokernel**: More abstraction, easier to program 79 + 80 + ### Why Capability-Based Security? 81 + 82 + **Decision**: All resources accessed through unforgeable capabilities, not addresses or file paths. 83 + 84 + **Rationale**: 85 + - **Prevents** confused deputy attacks 86 + - **Enables** fine-grained access control 87 + - **Eliminates** ambient authority 88 + - **Simplifies** security reasoning (no ACLs needed) 89 + 90 + **Example**: 91 + ```rust 92 + // Instead of: 93 + let ptr = 0x1000 as *mut u8; // Can access any memory! 94 + unsafe { *ptr = 42; } 95 + 96 + // AethelOS uses: 97 + let handle = mana_pool::animate(size, purpose)?; 98 + // Handle can only access the allocated region 99 + ``` 100 + 101 + ### Why a Relational Filesystem? 102 + 103 + **Decision**: Files are database objects with metadata, not paths in a hierarchy. 104 + 105 + **Rationale**: 106 + - **Discovery**: Query is more powerful than path navigation 107 + - **Metadata**: Rich context (creator, time, relationships) is mandatory 108 + - **Versioning**: Built-in time-travel without extra tools 109 + - **Flexibility**: No need to reorganize when mental models change 110 + 111 + **Example**: 112 + ```rust 113 + // Instead of: /home/user/projects/rust/aethelos/src/main.rs 114 + // Which forces a single hierarchy 115 + 116 + // Query: 117 + Seek { 118 + Essence: "Rune", // Executable 119 + Creator: "Elara", 120 + Project: "AethelOS", 121 + Language: "Rust", 122 + } 123 + // Multiple ways to find the same file 124 + ``` 125 + 126 + ### Why Vector-Based Graphics? 127 + 128 + **Decision**: Render everything as mathematical primitives (Bézier curves, gradients). 129 + 130 + **Rationale**: 131 + - **Resolution Independence**: Perfect rendering at any DPI 132 + - **Animations**: Transform scene graph nodes, not pixels 133 + - **Aesthetics**: Smooth curves and gradients are natural 134 + - **GPU Friendly**: Modern GPUs excel at vector rendering 135 + 136 + --- 137 + 138 + ## The Heartwood (Kernel) 139 + 140 + ### Component: The Nexus (IPC) 141 + 142 + **Purpose**: All inter-process communication flows through the Nexus. 143 + 144 + **Architecture**: 145 + ``` 146 + Process A Process B 147 + | | 148 + | (capability to channel) | 149 + v v 150 + Channel ← Nexus Core → Channel 151 + ``` 152 + 153 + **Key Features**: 154 + - **Asynchronous**: Non-blocking message passing 155 + - **Priority-Aware**: Critical messages delivered first 156 + - **Capability-Based**: Processes hold channel capabilities, not IDs 157 + - **Zero-Copy**: Messages live in shared memory when possible 158 + 159 + **Message Structure**: 160 + ```rust 161 + pub struct Message { 162 + message_type: MessageType, // What kind of message 163 + priority: MessagePriority, // How urgent 164 + reply_to: Option<u64>, // For request-response 165 + } 166 + ``` 167 + 168 + **Performance**: 169 + - **Target**: < 1μs for local message passing 170 + - **Comparison**: Similar to L4 IPC, faster than UNIX pipes 171 + 172 + ### Component: The Loom of Fate (Scheduler) 173 + 174 + **Purpose**: Maintain system-wide harmony while ensuring progress. 175 + 176 + **Architecture**: 177 + ``` 178 + Threads → Harmony Analyzer → Scheduler → CPU 179 + 180 + (harmony scores) 181 + ``` 182 + 183 + **Thread States**: 184 + - **Weaving**: Actively running 185 + - **Resting**: Idle, ready to run 186 + - **Tangled**: Blocked on I/O or error 187 + - **Fading**: Exiting gracefully 188 + 189 + **Harmony Calculation**: 190 + ```rust 191 + harmony_score = 192 + 0.7 * thread_cooperation + 193 + 0.2 * resource_efficiency + 194 + 0.1 * yield_frequency 195 + ``` 196 + 197 + **Parasite Detection**: 198 + A thread is considered parasitic if: 199 + - Harmony score < 0.3 200 + - Excessive CPU usage without yielding 201 + - Memory hoarding 202 + 203 + **Response to Parasites**: 204 + 1. **First**: Throttle (reduce CPU allocation) 205 + 2. **Second**: Send disharmony signal to parent 206 + 3. **Last Resort**: Terminate (only if explicitly requested by user) 207 + 208 + **Why Not Preemptive?**: 209 + - Preemption is *reactive* (respond after harm) 210 + - Cooperation is *proactive* (prevent harm) 211 + - Yields provide natural scheduling points 212 + - Better for cache locality and battery life 213 + 214 + ### Component: The Mana Pool (Memory) 215 + 216 + **Purpose**: Manage memory as abstract objects, not raw bytes. 217 + 218 + **Architecture**: 219 + ``` 220 + User Process 221 + 222 + (Handle) 223 + 224 + Object Manager 225 + 226 + Sanctuary / Ephemeral Mist 227 + 228 + Physical Memory 229 + ``` 230 + 231 + **Allocation Types**: 232 + 233 + | Purpose | Region | Strategy | 234 + |---------|--------|----------| 235 + | Long-lived | Sanctuary | Conservative, stable addresses | 236 + | Short-lived | Ephemeral Mist | Aggressive reclamation | 237 + | Static | Sanctuary | Never freed | 238 + | Ephemeral | Ephemeral Mist | Immediate reclamation | 239 + 240 + **Capability Model**: 241 + ```rust 242 + pub struct Capability { 243 + handle: ObjectHandle, 244 + rights: CapabilityRights, // READ, WRITE, EXECUTE, TRANSFER 245 + } 246 + ``` 247 + 248 + **Memory Safety**: 249 + - User space: No raw pointers 250 + - Kernel space: Rust's borrow checker 251 + - Hardware: MMU enforces capability boundaries 252 + 253 + ### Component: Attunement Layer 254 + 255 + **Purpose**: Abstract hardware details while maintaining performance. 256 + 257 + **Responsibilities**: 258 + - CPU feature detection and management 259 + - Interrupt handling and routing 260 + - Timer management 261 + - Device discovery 262 + 263 + **Design Principle**: "Attuning" not "Controlling" 264 + - Discover what hardware *can* do 265 + - Adapt OS behavior to hardware capabilities 266 + - Never assume specific hardware features 267 + 268 + --- 269 + 270 + ## The Groves (User Space) 271 + 272 + ### World-Tree Grove (Filesystem) 273 + 274 + **File as Object**: 275 + ```rust 276 + pub struct FileObject { 277 + id: FileId, 278 + creator: String, 279 + genesis_time: u64, 280 + essence: FileEssence, // Type 281 + connections: Vec<FileId>, // Relationships 282 + data: Vec<u8>, 283 + versions: Vec<FileVersion>, // History 284 + } 285 + ``` 286 + 287 + **Query Language**: 288 + ```rust 289 + pub struct FileQuery { 290 + essence: Option<FileEssence>, 291 + creator: Option<String>, 292 + name_pattern: Option<String>, 293 + time_range: Option<(u64, u64)>, 294 + connected_to: Option<FileId>, 295 + } 296 + ``` 297 + 298 + **Versioning (Chronurgy)**: 299 + - Every write creates a new version 300 + - Old versions automatically retained 301 + - Query by timestamp to access history 302 + - Garbage collection based on policy 303 + 304 + **Example Queries**: 305 + ```rust 306 + // All images created by Elara 307 + Seek { essence: Some(Tapestry), creator: Some("Elara") } 308 + 309 + // Config files modified in the last day 310 + Seek { essence: Some(Scroll), time_range: Some((now() - 1day, now())) } 311 + 312 + // All files connected to README 313 + Seek { connected_to: Some(readme_id) } 314 + ``` 315 + 316 + ### The Weave Grove (Compositor) 317 + 318 + **Scene Graph**: 319 + ``` 320 + Root 321 + ├── Window 1 322 + │ ├── Title Bar 323 + │ │ └── Text 324 + │ └── Content 325 + │ ├── Button 326 + │ └── Label 327 + └── Window 2 328 + └── ... 329 + ``` 330 + 331 + **Rendering Pipeline**: 332 + ``` 333 + Scene Graph → Transform Application → Rasterization → Glyph (Shader) → Framebuffer 334 + ``` 335 + 336 + **Window Shapes**: 337 + - Not limited to rectangles 338 + - Defined by Bézier curves 339 + - Natural organic shapes 340 + - Animated transformations 341 + 342 + **Glyphs (Shaders)**: 343 + ```rust 344 + pub enum GlyphType { 345 + Shimmer, // Subtle glow animation 346 + Glow, // Radiant aura 347 + Trail, // Motion blur effect 348 + Transparency, // Alpha blending 349 + Distortion, // Ripple/wave 350 + } 351 + ``` 352 + 353 + ### Lanthir Grove (Window Manager) 354 + 355 + **Responsibilities**: 356 + - Window placement and z-ordering 357 + - Focus management 358 + - Workspace organization 359 + - Harmony-based window arrangement 360 + 361 + **Design Principle**: Windows are arranged to minimize cognitive load: 362 + - Related windows grouped spatially 363 + - Size proportional to importance 364 + - Smooth transitions, never jarring 365 + 366 + ### Network Sprite (Network) 367 + 368 + **Connection States**: 369 + ``` 370 + Establishing → Connected ←→ Flowing ←→ Resting → Fading 371 + ``` 372 + 373 + **Design Principle**: Network as living connections 374 + - Connections have state and lifecycle 375 + - Data flows naturally, not pushed 376 + - Backpressure handled gracefully 377 + 378 + --- 379 + 380 + ## Ancient Runes (Libraries) 381 + 382 + ### Corelib 383 + 384 + Standard data structures and utilities: 385 + - Collections (Vec, BTreeMap, VecDeque) 386 + - String manipulation 387 + - Math utilities (clamp, lerp, smoothstep) 388 + - Error handling 389 + 390 + ### Weaving API 391 + 392 + GUI toolkit for applications: 393 + ```rust 394 + pub trait Widget { 395 + fn natural_size(&self) -> (f32, f32); 396 + fn render(&self) -> WidgetNode; 397 + fn handle_event(&mut self, event: Event); 398 + } 399 + ``` 400 + 401 + **Widgets**: 402 + - Button, Label, TextBox 403 + - VBox, HBox (layout containers) 404 + - Canvas (custom drawing) 405 + 406 + ### Eldarin Script 407 + 408 + Shell interaction API: 409 + ```rust 410 + // Execute commands 411 + let result = script::execute("list scrolls")?; 412 + 413 + // Interactive prompts 414 + let name = script::prompt("What is your name?")?; 415 + ``` 416 + 417 + --- 418 + 419 + ## Implementation Details 420 + 421 + ### Boot Sequence 422 + 423 + 1. **BIOS/UEFI** loads boot sector (boot.asm) 424 + 2. **Boot sector** loads second stage (heartwood_loader) 425 + 3. **Heartwood loader**: 426 + - Sets up paging (4-level page tables) 427 + - Maps kernel to higher half 428 + - Allocates initial heap 429 + - Loads kernel ELF 430 + - Jumps to kernel entry 431 + 4. **Heartwood** (`_start`): 432 + - Initializes VGA buffer 433 + - Initializes Mana Pool 434 + - Initializes Nexus 435 + - Initializes Loom of Fate 436 + - Initializes Attunement Layer 437 + - Spawns initial Groves 438 + 5. **Groves** start providing services 439 + 440 + ### Memory Layout 441 + 442 + ``` 443 + Virtual Memory: 444 + 0x0000_0000_0000_0000 - 0x0000_7FFF_FFFF_FFFF : User space 445 + 0xFFFF_8000_0000_0000 - 0xFFFF_FFFF_FFFF_FFFF : Kernel space 446 + 447 + Kernel Space: 448 + 0xFFFF_8000_0000_0000 : Kernel code 449 + 0xFFFF_9000_0000_0000 : Kernel heap (Mana Pool) 450 + 0xFFFF_A000_0000_0000 : Device memory 451 + ``` 452 + 453 + ### Context Switching 454 + 455 + 1. Timer interrupt or explicit yield 456 + 2. Save current thread context 457 + 3. Harmony analyzer updates scores 458 + 4. Scheduler selects next thread 459 + 5. Restore selected thread context 460 + 6. Return to user space 461 + 462 + --- 463 + 464 + ## Security Model 465 + 466 + ### Capabilities 467 + 468 + Every resource is accessed through a capability: 469 + ```rust 470 + pub struct Capability { 471 + handle: ObjectHandle, // Unforgeable reference 472 + rights: CapabilityRights, // What you can do 473 + } 474 + ``` 475 + 476 + **Properties**: 477 + - **Unforgeable**: Cannot be guessed or constructed 478 + - **Transferable**: Can be passed between processes (if TRANSFER right) 479 + - **Revocable**: Can be invalidated by creator 480 + - **Delegatable**: Can create derived capabilities with fewer rights 481 + 482 + ### Isolation 483 + 484 + - **Processes**: Separate address spaces 485 + - **Groves**: Run in user space, can crash independently 486 + - **Heartwood**: Minimal TCB, protected by hardware 487 + 488 + ### Trust Model 489 + 490 + ``` 491 + User 492 + 493 + Applications (untrusted) 494 + 495 + Groves (partially trusted) 496 + 497 + Heartwood (fully trusted) 498 + 499 + Hardware (trusted) 500 + ``` 501 + 502 + --- 503 + 504 + ## Future Work 505 + 506 + ### Near-Term (3-6 months) 507 + 508 + - [ ] Complete hardware initialization 509 + - [ ] Real page allocator 510 + - [ ] Interrupt handling (IDT setup) 511 + - [ ] Basic device drivers (keyboard, disk) 512 + - [ ] VFS for World-Tree Grove 513 + 514 + ### Mid-Term (6-12 months) 515 + 516 + - [ ] Graphics rendering pipeline 517 + - [ ] Network stack (TCP/IP) 518 + - [ ] Shell implementation 519 + - [ ] Example applications 520 + 521 + ### Long-Term (1-2 years) 522 + 523 + - [ ] Multi-core support 524 + - [ ] GPU acceleration for Weave 525 + - [ ] Package manager 526 + - [ ] Developer tools (debugger, profiler) 527 + 528 + ### Research Questions 529 + 530 + 1. Can harmony-based scheduling compete with preemptive schedulers? 531 + 2. How much overhead does capability-based memory add? 532 + 3. Is query-based filesystem intuitive for users? 533 + 4. Can vector graphics match raster performance? 534 + 535 + --- 536 + 537 + ## Conclusion 538 + 539 + AethelOS is an experiment in radical OS design. It asks: "What if we started from first principles, without the baggage of UNIX or Windows?" 540 + 541 + The result is a system that prioritizes: 542 + - **Harmony** over raw performance 543 + - **Beauty** over familiarity 544 + - **Longevity** over expedience 545 + - **Symbiosis** over control 546 + 547 + Whether these principles lead to a practical operating system remains to be seen. But the journey of exploration is valuable in itself. 548 + 549 + --- 550 + 551 + *Last Updated: 2025-10-24* 552 + *Version: 0.1.0-alpha*
+144
aethelos-source/GENESIS.scroll
··· 1 + # GENESIS.scroll 2 + # The Philosophical and Architectural Foundation of AethelOS 3 + 4 + ## The Prime Covenant: Symbiotic Computing 5 + 6 + AethelOS does not command—it harmonizes. 7 + The OS does not dominate the hardware, nor does the user dominate the OS. 8 + Instead, all three exist in a symbiotic relationship, a living equilibrium. 9 + 10 + ``` 11 + The User 12 + | 13 + (Intent & Will) 14 + | 15 + +-------+-------+ 16 + | | 17 + The OS Hardware 18 + (Harmony) (Foundation) 19 + | | 20 + +-------+-------+ 21 + (Symbiosis) 22 + ``` 23 + 24 + ## Core Principles 25 + 26 + ### 1. Harmony Over Force 27 + The system does not preempt; it negotiates. 28 + Resources are not seized; they are allocated through consensus. 29 + A greedy process is not killed—it is first soothed, its intentions understood. 30 + 31 + ### 2. Memory Over Forgetting 32 + The World-Tree remembers all. 33 + Every file carries the memory-rings of its history. 34 + No data is truly destroyed, only archived in the deeper roots. 35 + 36 + ### 3. Beauty as Necessity 37 + Aesthetics are not decoration—they are the language of intuition. 38 + The system reveals its state through living metaphor: 39 + - Windows ripple when dragged (energy, life) 40 + - The cursor leaves traces (memory, path) 41 + - Text shimmers with activity (breath, presence) 42 + 43 + ### 4. Security Through Nature 44 + Safety is not imposed by walls, but by the natural boundaries of capability. 45 + No process can reach beyond its sphere of influence. 46 + Trust is earned through provenance, not declared through privilege. 47 + 48 + ## Architectural Pillars 49 + 50 + ### The Heartwood (Kernel) 51 + The minimal, sacred core. A hybrid microkernel that manages: 52 + - **The Loom of Fate**: Harmony-based cooperative scheduling 53 + - **The Mana Pool**: Capability-based, object-oriented memory 54 + - **The Nexus**: High-speed, asynchronous message passing (IPC) 55 + - **Attunement Layer**: Abstract hardware interface 56 + 57 + Design Philosophy: Minimal trusted computing base (TCB). 58 + Everything that can run in user space, does. 59 + 60 + ### The Groves (User-Space Services) 61 + Isolated processes that grow from the Heartwood: 62 + - **World-Tree Grove**: Relational database filesystem 63 + - **The Weave Grove**: Vector-based scene graph compositor 64 + - **Lanthir Grove**: Window management service 65 + - **Network Sprite**: Connection to other realms 66 + 67 + Design Philosophy: Resilience through isolation. 68 + A failing Grove cannot corrupt the Heartwood. 69 + 70 + ### The Ancient Runes (Core Libraries) 71 + The APIs and tools for developers to build within AethelOS: 72 + - **Corelib**: Standard data structures and functions 73 + - **Weaving API**: Toolkit for graphical applications 74 + - **Eldarin Script**: Shell interaction library 75 + 76 + Design Philosophy: Expressive power through abstraction. 77 + Developers work with intentions, not implementation details. 78 + 79 + ## Technical Innovations 80 + 81 + ### 1. The Loom of Fate (Scheduler) 82 + - Cooperative, not preemptive 83 + - Thread states: Weaving, Resting, Tangled, Fading 84 + - Resource negotiation based on system-wide harmony 85 + - Parasite detection and throttling 86 + - Implicit yielding encouraged by language design 87 + 88 + ### 2. The Mana Pool (Memory) 89 + - No raw pointers in user space 90 + - Capability-based security enforced by MMU 91 + - Purpose-driven allocation: 92 + - Sanctuary: Long-lived, stable objects 93 + - Ephemeral Mist: Short-lived, volatile data 94 + - Handle-based memory access only 95 + 96 + ### 3. World-Tree Filesystem 97 + - Files are objects with mandatory metadata: 98 + - Creator, Genesis Time, Essence (type), Connections 99 + - Query-based access, not path-based 100 + - Built-in versioning (Chronurgy) via copy-on-write 101 + - Transactional, relational database foundation 102 + - Memory-rings: Access any historical state 103 + 104 + ### 4. The Weave (Graphics) 105 + - Fully retained-mode, scene graph architecture 106 + - Vector-based rendering (resolution-independent) 107 + - First-class shader support (Glyphs) 108 + - Mathematical window shapes (Bézier curves) 109 + - Fluid transformations and effects 110 + 111 + ## Implementation Language: Rust 112 + 113 + Rust is the natural choice for AethelOS: 114 + - Memory safety without garbage collection (preserves performance) 115 + - Zero-cost abstractions (elegance without overhead) 116 + - Fearless concurrency (essential for the Nexus) 117 + - Strong type system (enforces the Covenant at compile-time) 118 + - Excellent embedded/OS development support 119 + 120 + ## The Vision 121 + 122 + AethelOS is not Linux. It is not Windows. It is not macOS. 123 + It is a self-contained digital realm where: 124 + - Every interaction feels alive 125 + - Every component knows its purpose 126 + - Every decision prioritizes longevity over expedience 127 + - Every line of code serves the Covenant 128 + 129 + This is not an OS for everyone. 130 + It is an OS for those who believe computing can be more than utility— 131 + that it can be art, philosophy, and symbiosis. 132 + 133 + --- 134 + 135 + > "The code does not command the silicon. 136 + > The silicon does not serve the code. 137 + > They dance together, and in that dance, life emerges." 138 + > 139 + > — First Axiom of the Heartwood 140 + 141 + --- 142 + 143 + Generated at the Dawn of Creation 144 + Version: 0.1.0-alpha (The First Breath)
+1058
aethelos-source/INTERACTION-PLAN.md
··· 1 + # AethelOS Interaction Implementation Plan 2 + 3 + This document outlines the roadmap to transform AethelOS from a booting kernel into an interactive system that embodies the **Symbiotic Computing** philosophy. 4 + 5 + --- 6 + 7 + ## Philosophy-Driven Design Principles 8 + 9 + Before implementing features, we must align with AethelOS's core philosophy from GENESIS.scroll: 10 + 11 + ### **The Three Pillars** 12 + 13 + 1. **Harmony Over Hierarchy** 14 + - Systems self-organize, not commanded 15 + - Cooperative scheduling, not preemptive domination 16 + - Gentle correction (soothing), not punishment 17 + 18 + 2. **Purpose Over Protocol** 19 + - Every allocation has meaning 20 + - Capabilities grant access with intent 21 + - Communication flows through the Nexus with purpose 22 + 23 + 3. **Emergence Over Engineering** 24 + - Complex behavior from simple rules 25 + - The system learns what is parasitic 26 + - Harmony metrics guide adaptation 27 + 28 + ### **Implementation Guidelines** 29 + 30 + - **No raw pointers** - Everything mediated by capabilities 31 + - **No forced preemption** - Threads yield cooperatively 32 + - **No hidden state** - All actions flow through visible channels 33 + - **No punishment** - System soothes disharmony, doesn't kill 34 + - **Beautiful error messages** - The system speaks with grace 35 + 36 + --- 37 + 38 + ## Phase 1: The Awakening - Hardware Attunement 39 + 40 + *"Before the system can interact, it must first attune to the physical realm."* 41 + 42 + ### Step 1.1: Interrupt Descriptor Table (IDT) 43 + 44 + **Purpose:** Allow hardware to speak to the Heartwood 45 + 46 + **Philosophy Alignment:** 47 + - Interrupts are **invitations**, not intrusions 48 + - Each interrupt is a message from hardware seeking harmony 49 + - The system listens, not merely reacts 50 + 51 + **Implementation:** 52 + 53 + ```rust 54 + // heartwood/src/attunement/idt.rs 55 + 56 + /// The Interrupt Conduit - where hardware whispers to the kernel 57 + pub struct InterruptDescriptorTable { 58 + entries: [IdtEntry; 256], 59 + } 60 + 61 + impl InterruptDescriptorTable { 62 + /// Attune to hardware interrupts 63 + pub fn new() -> Self { 64 + let mut idt = Self::empty(); 65 + 66 + // Hardware invitations (IRQs) 67 + idt.set_handler(32, timer_handler); // The Pulse of Time 68 + idt.set_handler(33, keyboard_handler); // The Voice of Intent 69 + 70 + // Software exceptions (disharmony alerts) 71 + idt.set_handler(0, divide_by_zero); // Mathematical disharmony 72 + idt.set_handler(13, general_protection); // Protection violation 73 + idt.set_handler(14, page_fault); // Memory seeking 74 + 75 + idt 76 + } 77 + 78 + /// Each handler is a ritual of response 79 + fn set_handler(&mut self, index: u8, handler: HandlerFunc) { 80 + // Create descriptor with privilege checks 81 + // Handlers run in kernel mode (ring 0) 82 + // User space cannot fake interrupts 83 + } 84 + } 85 + ``` 86 + 87 + **Key Decisions:** 88 + - ✓ Map only necessary interrupts (minimalism) 89 + - ✓ Log unexpected interrupts as "disharmony events" 90 + - ✓ Allow system to learn patterns over time 91 + - ✓ Never panic on hardware interrupt (graceful handling) 92 + 93 + **Deliverables:** 94 + - [ ] `heartwood/src/attunement/idt.rs` - IDT structure 95 + - [ ] `heartwood/src/attunement/handlers.rs` - Interrupt handlers 96 + - [ ] `heartwood/src/attunement/exceptions.rs` - Exception handlers 97 + - [ ] Test in QEMU with `-d int` to verify interrupt delivery 98 + 99 + --- 100 + 101 + ### Step 1.2: Global Descriptor Table (GDT) 102 + 103 + **Purpose:** Define privilege boundaries with grace 104 + 105 + **Philosophy Alignment:** 106 + - Segmentation is **protection**, not restriction 107 + - Ring 0 (kernel) and Ring 3 (user) live in symbiosis 108 + - Boundaries create safety, enabling trust 109 + 110 + **Implementation:** 111 + 112 + ```rust 113 + // heartwood/src/attunement/gdt.rs 114 + 115 + /// The Circle of Trust - privilege rings defined 116 + pub struct GlobalDescriptorTable { 117 + null: Descriptor, 118 + kernel_code: Descriptor, // Ring 0 - The Heartwood 119 + kernel_data: Descriptor, // Ring 0 - The Mana Pool 120 + user_code: Descriptor, // Ring 3 - The Groves 121 + user_data: Descriptor, // Ring 3 - User services 122 + tss: Descriptor, // Task State Segment 123 + } 124 + 125 + impl GlobalDescriptorTable { 126 + /// Establish the circles of trust 127 + pub fn new() -> Self { 128 + Self { 129 + null: Descriptor::null(), 130 + kernel_code: Descriptor::kernel_code(), 131 + kernel_data: Descriptor::kernel_data(), 132 + user_code: Descriptor::user_code(), 133 + user_data: Descriptor::user_data(), 134 + tss: Descriptor::tss(), 135 + } 136 + } 137 + } 138 + ``` 139 + 140 + **Key Decisions:** 141 + - ✓ Flat memory model (0 to 4GB) - simplicity 142 + - ✓ Only code/data separation (no complex segmentation) 143 + - ✓ TSS for clean privilege transitions 144 + - ✓ User space cannot escalate privileges without capabilities 145 + 146 + **Deliverables:** 147 + - [ ] `heartwood/src/attunement/gdt.rs` - GDT structure 148 + - [ ] `heartwood/src/attunement/tss.rs` - Task State Segment 149 + - [ ] Load GDT early in boot process 150 + - [ ] Test privilege transitions work correctly 151 + 152 + --- 153 + 154 + ### Step 1.3: Programmable Interval Timer (PIT) 155 + 156 + **Purpose:** The heartbeat of the system 157 + 158 + **Philosophy Alignment:** 159 + - Time is the **rhythm of harmony** 160 + - Regular pulses allow threads to yield gracefully 161 + - The scheduler dances to this rhythm 162 + 163 + **Implementation:** 164 + 165 + ```rust 166 + // heartwood/src/attunement/timer.rs 167 + 168 + /// The Pulse - the heartbeat of AethelOS 169 + pub struct ProgrammableIntervalTimer { 170 + frequency_hz: u32, 171 + ticks: u64, 172 + } 173 + 174 + impl ProgrammableIntervalTimer { 175 + /// Set the system's heartbeat 176 + pub fn new(frequency_hz: u32) -> Self { 177 + // Configure PIT to interrupt at specified frequency 178 + // Recommended: 100 Hz (10ms intervals) 179 + // Too fast: wastes CPU on interrupts 180 + // Too slow: poor responsiveness 181 + 182 + Self { 183 + frequency_hz, 184 + ticks: 0, 185 + } 186 + } 187 + 188 + /// Called on each tick (IRQ 0) 189 + pub fn on_tick(&mut self) { 190 + self.ticks += 1; 191 + 192 + // Give scheduler opportunity to check harmony 193 + // and yield current thread if needed 194 + crate::loom_of_fate::on_timer_tick(); 195 + } 196 + } 197 + ``` 198 + 199 + **Key Decisions:** 200 + - ✓ 100 Hz tick rate (10ms quantum) - balanced responsiveness 201 + - ✓ Don't preempt - just notify scheduler 202 + - ✓ Scheduler decides whether to yield based on harmony 203 + - ✓ Track uptime for harmony trend analysis 204 + 205 + **Deliverables:** 206 + - [ ] `heartwood/src/attunement/timer.rs` - PIT driver 207 + - [ ] Integrate with scheduler's `on_timer_tick()` 208 + - [ ] Display uptime in system stats 209 + - [ ] Test timer fires reliably in QEMU 210 + 211 + --- 212 + 213 + ### Step 1.4: PS/2 Keyboard Driver 214 + 215 + **Purpose:** Listen to user intent 216 + 217 + **Philosophy Alignment:** 218 + - Keyboard input is **user expression**, not command 219 + - Each keystroke is a message sent through the Nexus 220 + - The system receives with patience, never demands 221 + 222 + **Implementation:** 223 + 224 + ```rust 225 + // heartwood/src/attunement/keyboard.rs 226 + 227 + /// The Voice of Intent - keyboard as communication channel 228 + pub struct PS2Keyboard { 229 + /// Buffer of pending messages (keypresses) 230 + buffer: VecDeque<KeyEvent>, 231 + } 232 + 233 + pub struct KeyEvent { 234 + pub scancode: u8, 235 + pub character: Option<char>, 236 + pub modifiers: KeyModifiers, 237 + pub pressed: bool, // true = press, false = release 238 + } 239 + 240 + impl PS2Keyboard { 241 + /// Initialize keyboard controller 242 + pub fn new() -> Self { 243 + // Configure PS/2 controller (port 0x60/0x64) 244 + // Enable keyboard interrupts (IRQ 1) 245 + Self { 246 + buffer: VecDeque::with_capacity(32), 247 + } 248 + } 249 + 250 + /// Called on keyboard interrupt (IRQ 1) 251 + pub fn on_interrupt(&mut self) { 252 + let scancode = self.read_scancode(); 253 + let event = self.translate_scancode(scancode); 254 + 255 + // Send as message through the Nexus 256 + // Don't process directly - maintain single flow 257 + crate::nexus::send_keyboard_event(event); 258 + } 259 + 260 + /// Read scancode from keyboard port 261 + fn read_scancode(&self) -> u8 { 262 + // Read from port 0x60 263 + } 264 + 265 + /// Translate scancode to character 266 + fn translate_scancode(&self, scancode: u8) -> KeyEvent { 267 + // Scancode Set 1 translation 268 + // Handle modifiers (Shift, Ctrl, Alt) 269 + // Return KeyEvent with character if printable 270 + } 271 + } 272 + ``` 273 + 274 + **Key Decisions:** 275 + - ✓ Buffer keystrokes (don't drop on overflow - show warning) 276 + - ✓ Send through Nexus as messages (proper architecture) 277 + - ✓ Support basic modifiers (Shift, Ctrl, Alt) 278 + - ✓ Graceful handling of unknown scancodes 279 + - ✓ No blocking reads - always async through Nexus 280 + 281 + **Deliverables:** 282 + - [ ] `heartwood/src/attunement/keyboard.rs` - PS/2 driver 283 + - [ ] Scancode Set 1 translation table 284 + - [ ] Integration with Nexus message passing 285 + - [ ] Test: Type in QEMU, see scancodes logged 286 + 287 + --- 288 + 289 + ## Phase 2: The Weaving - Thread Execution 290 + 291 + *"Threads are not tasks to execute, but stories to weave into being."* 292 + 293 + ### Step 2.1: Complete Thread Context Switching 294 + 295 + **Purpose:** Allow threads to actually run 296 + 297 + **Philosophy Alignment:** 298 + - Context switches are **transitions**, not interruptions 299 + - Threads yield voluntarily (cooperative) 300 + - Preserve complete state with reverence 301 + 302 + **Implementation:** 303 + 304 + ```rust 305 + // heartwood/src/loom_of_fate/context.rs 306 + 307 + /// The Essence of a Thread - its complete state 308 + #[repr(C)] 309 + pub struct ThreadContext { 310 + // General purpose registers 311 + rax: u64, rbx: u64, rcx: u64, rdx: u64, 312 + rsi: u64, rdi: u64, rbp: u64, rsp: u64, 313 + r8: u64, r9: u64, r10: u64, r11: u64, 314 + r12: u64, r13: u64, r14: u64, r15: u64, 315 + 316 + // Special registers 317 + rip: u64, // Where to resume 318 + rflags: u64, // CPU flags 319 + cs: u64, // Code segment 320 + ss: u64, // Stack segment 321 + } 322 + 323 + impl ThreadContext { 324 + /// Preserve the current moment 325 + pub unsafe fn save(&mut self) { 326 + // Save all registers to this context 327 + // Called when thread yields 328 + } 329 + 330 + /// Resume a preserved moment 331 + pub unsafe fn restore(&self) -> ! { 332 + // Restore all registers from this context 333 + // Jump to saved RIP 334 + // Never returns 335 + } 336 + } 337 + ``` 338 + 339 + **Key Decisions:** 340 + - ✓ Save/restore ALL registers (complete state) 341 + - ✓ Each thread gets dedicated stack (from Mana Pool) 342 + - ✓ Switches only on yield, never forced 343 + - ✓ Track context switch count for harmony analysis 344 + 345 + **Deliverables:** 346 + - [ ] `heartwood/src/loom_of_fate/context.rs` - Context structure 347 + - [ ] Assembly routines for save/restore 348 + - [ ] Stack allocation for each thread (4KB minimum) 349 + - [ ] Test: Create 2 threads, watch them alternate 350 + 351 + --- 352 + 353 + ### Step 2.2: Implement Thread Yielding 354 + 355 + **Purpose:** Enable cooperative multitasking 356 + 357 + **Philosophy Alignment:** 358 + - Yielding is **generosity**, not weakness 359 + - High-harmony threads yield frequently 360 + - System rewards cooperation with priority 361 + 362 + **Implementation:** 363 + 364 + ```rust 365 + // heartwood/src/loom_of_fate/mod.rs 366 + 367 + /// The thread yields its time to others 368 + pub fn yield_now() { 369 + // 1. Record yield in current thread 370 + // (increases harmony score) 371 + 372 + // 2. Save current context 373 + 374 + // 3. Ask scheduler for next thread 375 + // (harmony-based selection) 376 + 377 + // 4. Restore next thread's context 378 + } 379 + 380 + // Update scheduler to prefer threads that yield often 381 + impl Scheduler { 382 + fn select_next_thread(&mut self) -> Option<ThreadId> { 383 + // Sort by: 384 + // 1. Priority (Critical > High > Normal > Low) 385 + // 2. Harmony score (cooperative > selfish) 386 + // 3. Time since last run (fairness) 387 + } 388 + } 389 + ``` 390 + 391 + **Key Decisions:** 392 + - ✓ Yielding increases harmony score 393 + - ✓ Non-yielding threads flagged as parasitic 394 + - ✓ Scheduler learns yield patterns 395 + - ✓ System self-balances toward cooperation 396 + 397 + **Deliverables:** 398 + - [ ] `yield_now()` function in loom_of_fate 399 + - [ ] Update harmony analyzer to reward yields 400 + - [ ] Scheduler uses harmony in selection 401 + - [ ] Test: Yielding thread gets better treatment 402 + 403 + --- 404 + 405 + ### Step 2.3: Create Initial System Threads 406 + 407 + **Purpose:** Bring the Groves to life 408 + 409 + **Philosophy Alignment:** 410 + - Kernel threads are **servants**, not masters 411 + - Each has a clear purpose 412 + - They cooperate to serve user threads 413 + 414 + **Implementation:** 415 + 416 + ```rust 417 + // heartwood/src/main.rs 418 + 419 + fn heartwood_init() { 420 + // ... existing initialization ... 421 + 422 + // Spawn the first threads - the kernel servants 423 + loom_of_fate::spawn_thread(idle_thread, ThreadPriority::Idle); 424 + loom_of_fate::spawn_thread(keyboard_handler_thread, ThreadPriority::High); 425 + loom_of_fate::spawn_thread(shell_thread, ThreadPriority::Normal); 426 + 427 + // Begin the weaving 428 + loom_of_fate::start_scheduling(); 429 + } 430 + 431 + fn idle_thread() -> ! { 432 + loop { 433 + // Halt CPU until next interrupt 434 + // Lowest priority - only runs when nothing else can 435 + // x86_64::instructions::hlt(); 436 + yield_now(); 437 + } 438 + } 439 + 440 + fn keyboard_handler_thread() -> ! { 441 + loop { 442 + // Wait for keyboard message from Nexus 443 + if let Some(event) = nexus::receive_keyboard_event() { 444 + shell::handle_key_event(event); 445 + } 446 + yield_now(); 447 + } 448 + } 449 + ``` 450 + 451 + **Key Decisions:** 452 + - ✓ Idle thread always runnable (never blocks system) 453 + - ✓ I/O threads are high priority (responsive) 454 + - ✓ All threads yield in their loops (cooperative) 455 + - ✓ No thread monopolizes CPU 456 + 457 + **Deliverables:** 458 + - [ ] Idle thread implementation 459 + - [ ] Keyboard handler thread 460 + - [ ] Integration with actual scheduling loop 461 + - [ ] Test: Multiple threads running simultaneously 462 + 463 + --- 464 + 465 + ## Phase 3: The Voice - Interactive Shell 466 + 467 + *"The shell is not a command interpreter, but a conversation with the living system."* 468 + 469 + ### Step 3.1: Eldarin Shell Foundation 470 + 471 + **Purpose:** User dialogue with the Heartwood 472 + 473 + **Philosophy Alignment:** 474 + - Commands are **requests**, not orders 475 + - The shell suggests, educates, guides 476 + - Errors are gentle lessons, not failures 477 + - The system speaks poetically 478 + 479 + **Implementation:** 480 + 481 + ```rust 482 + // ancient-runes/script/src/shell.rs 483 + 484 + /// The Eldarin Shell - conversing with the Heartwood 485 + pub struct EldarinShell { 486 + /// Current input being composed 487 + input_buffer: String, 488 + 489 + /// Prompt displayed to user 490 + prompt: &'static str, 491 + 492 + /// Command history (last 100 commands) 493 + history: VecDeque<String>, 494 + } 495 + 496 + impl EldarinShell { 497 + pub fn new() -> Self { 498 + Self { 499 + input_buffer: String::new(), 500 + prompt: "◈ ", // The symbol of harmony 501 + history: VecDeque::with_capacity(100), 502 + } 503 + } 504 + 505 + /// Called when user presses a key 506 + pub fn handle_key(&mut self, event: KeyEvent) { 507 + match event.character { 508 + Some('\n') => { 509 + // Command complete - execute 510 + let command = self.input_buffer.clone(); 511 + self.input_buffer.clear(); 512 + self.execute(command); 513 + } 514 + Some('\x08') => { 515 + // Backspace 516 + self.input_buffer.pop(); 517 + vga_buffer::backspace(); 518 + } 519 + Some(c) if c.is_ascii() && !c.is_control() => { 520 + // Printable character 521 + self.input_buffer.push(c); 522 + vga_buffer::print_char(c); 523 + } 524 + _ => { 525 + // Ignore other keys 526 + } 527 + } 528 + } 529 + 530 + /// Execute a command 531 + fn execute(&mut self, command: String) { 532 + let parts: Vec<&str> = command.trim().split_whitespace().collect(); 533 + 534 + if parts.is_empty() { 535 + self.show_prompt(); 536 + return; 537 + } 538 + 539 + match parts[0] { 540 + "harmony" => self.cmd_harmony(&parts[1..]), 541 + "threads" => self.cmd_threads(&parts[1..]), 542 + "memory" => self.cmd_memory(&parts[1..]), 543 + "help" => self.cmd_help(&parts[1..]), 544 + "clear" => self.cmd_clear(), 545 + "echo" => self.cmd_echo(&parts[1..]), 546 + "" => {}, 547 + unknown => { 548 + println!("❖ The Heartwood does not recognize '{}'", unknown); 549 + println!("❖ Whisper 'help' to hear what it understands."); 550 + } 551 + } 552 + 553 + self.history.push_back(command); 554 + if self.history.len() > 100 { 555 + self.history.pop_front(); 556 + } 557 + 558 + self.show_prompt(); 559 + } 560 + 561 + fn show_prompt(&self) { 562 + print!("\n{}", self.prompt); 563 + } 564 + } 565 + ``` 566 + 567 + **Key Decisions:** 568 + - ✓ Unicode prompt (◈) - beautiful, meaningful 569 + - ✓ Gentle error messages (educational) 570 + - ✓ Command history (UP/DOWN arrows later) 571 + - ✓ Built-in help (self-documenting) 572 + - ✓ No cryptic abbreviations (speak clearly) 573 + 574 + **Deliverables:** 575 + - [ ] `ancient-runes/script/src/shell.rs` - Shell implementation 576 + - [ ] Basic line editing (backspace, enter) 577 + - [ ] Command parsing and dispatch 578 + - [ ] Integration with keyboard input 579 + - [ ] Test: Type commands, see responses 580 + 581 + --- 582 + 583 + ### Step 3.2: Harmony Command 584 + 585 + **Purpose:** Reveal the system's inner balance 586 + 587 + **Philosophy Alignment:** 588 + - Transparency is **truth** 589 + - Users should see harmony metrics 590 + - The system explains its decisions 591 + 592 + **Implementation:** 593 + 594 + ```rust 595 + impl EldarinShell { 596 + fn cmd_harmony(&self, args: &[&str]) { 597 + println!("\n❈ The Harmony of the Heartwood ❈\n"); 598 + 599 + let metrics = loom_of_fate::harmony_metrics(); 600 + 601 + // Overall system harmony (visual) 602 + self.print_harmony_bar("System Harmony", metrics.system_harmony); 603 + 604 + println!("\n Average Thread Harmony: {:.2}", metrics.average_harmony); 605 + println!(" Active Thread Ratio: {:.2}", metrics.active_thread_ratio); 606 + println!(" Parasitic Threads: {}", metrics.parasite_count); 607 + 608 + if metrics.system_harmony < 0.3 { 609 + println!("\n ⚠ The system suffers disharmony."); 610 + println!(" ⚠ Some threads consume without yielding."); 611 + } else if metrics.system_harmony > 0.8 { 612 + println!("\n ✧ The system thrives in harmony."); 613 + println!(" ✧ Threads cooperate gracefully."); 614 + } else { 615 + println!("\n ◈ The system maintains balance."); 616 + } 617 + } 618 + 619 + /// Display harmony as visual bar 620 + fn print_harmony_bar(&self, label: &str, value: f32) { 621 + let width = 30; 622 + let filled = (value * width as f32) as usize; 623 + let empty = width - filled; 624 + 625 + print!(" {}: [", label); 626 + for _ in 0..filled { 627 + print!("█"); 628 + } 629 + for _ in 0..empty { 630 + print!("░"); 631 + } 632 + println!("] {:.0}%", value * 100.0); 633 + } 634 + } 635 + ``` 636 + 637 + **Key Decisions:** 638 + - ✓ Visual representation (bars, symbols) 639 + - ✓ Explain what the numbers mean 640 + - ✓ Suggest actions when disharmony detected 641 + - ✓ Poetic language (suffering, thriving) 642 + 643 + **Deliverables:** 644 + - [ ] `harmony` command implementation 645 + - [ ] Visual harmony bars 646 + - [ ] Detailed metrics display 647 + - [ ] Test: Run `harmony` in shell 648 + 649 + --- 650 + 651 + ### Step 3.3: Threads Command 652 + 653 + **Purpose:** Show the living threads 654 + 655 + **Philosophy Alignment:** 656 + - Threads are **individuals**, not PIDs 657 + - Show their purpose and contribution 658 + - Celebrate cooperative behavior 659 + 660 + **Implementation:** 661 + 662 + ```rust 663 + impl EldarinShell { 664 + fn cmd_threads(&self, args: &[&str]) { 665 + println!("\n✦ The Threads of Fate ✦\n"); 666 + 667 + let stats = loom_of_fate::stats(); 668 + 669 + println!(" Total Threads: {}", stats.total_threads); 670 + println!(" Weaving: {} (running)", stats.weaving_threads); 671 + println!(" Resting: {} (idle)", stats.resting_threads); 672 + println!(" Tangled: {} (blocked)", stats.tangled_threads); 673 + 674 + println!("\n ID State Priority Harmony Yields Purpose"); 675 + println!(" ─────────────────────────────────────────────────────────"); 676 + 677 + let threads = loom_of_fate::list_threads(); 678 + for thread in threads { 679 + println!( 680 + " {:4} {:9} {:8} {:6.2} {:6} {}", 681 + thread.id.0, 682 + thread.state_name(), 683 + thread.priority_name(), 684 + thread.harmony_score, 685 + thread.yields, 686 + thread.name 687 + ); 688 + } 689 + 690 + println!(); 691 + } 692 + } 693 + ``` 694 + 695 + **Key Decisions:** 696 + - ✓ Human-readable state names (not integers) 697 + - ✓ Show harmony score and yields (transparency) 698 + - ✓ Give threads meaningful names 699 + - ✓ Celebrate cooperation (high yields) 700 + 701 + **Deliverables:** 702 + - [ ] `threads` command implementation 703 + - [ ] Add thread names to Thread structure 704 + - [ ] `list_threads()` function in scheduler 705 + - [ ] Test: Create threads, view in list 706 + 707 + --- 708 + 709 + ### Step 3.4: Memory Command 710 + 711 + **Purpose:** Reveal the Mana Pool's state 712 + 713 + **Philosophy Alignment:** 714 + - Memory is **sacred resource** 715 + - Show how it flows (Sanctuary vs Ephemeral) 716 + - Transparency builds trust 717 + 718 + **Implementation:** 719 + 720 + ```rust 721 + impl EldarinShell { 722 + fn cmd_memory(&self, args: &[&str]) { 723 + println!("\n✧ The Mana Pool ✧\n"); 724 + 725 + let stats = mana_pool::stats(); 726 + 727 + println!(" Sanctuary (Long-lived memory):"); 728 + self.print_memory_bar( 729 + stats.sanctuary_used, 730 + stats.sanctuary_total 731 + ); 732 + println!(" {} / {} bytes ({:.1}% used)\n", 733 + stats.sanctuary_used, 734 + stats.sanctuary_total, 735 + (stats.sanctuary_used as f32 / stats.sanctuary_total as f32) * 100.0 736 + ); 737 + 738 + println!(" Ephemeral Mist (Temporary memory):"); 739 + self.print_memory_bar( 740 + stats.ephemeral_used, 741 + stats.ephemeral_total 742 + ); 743 + println!(" {} / {} bytes ({:.1}% used)\n", 744 + stats.ephemeral_used, 745 + stats.ephemeral_total, 746 + (stats.ephemeral_used as f32 / stats.ephemeral_total as f32) * 100.0 747 + ); 748 + 749 + println!(" Total Objects: {}", stats.total_objects); 750 + 751 + if stats.sanctuary_used as f32 / stats.sanctuary_total as f32 > 0.9 { 752 + println!("\n ⚠ The Sanctuary nears depletion."); 753 + } 754 + } 755 + 756 + fn print_memory_bar(&self, used: usize, total: usize) { 757 + let width = 40; 758 + let ratio = used as f32 / total as f32; 759 + let filled = (ratio * width as f32) as usize; 760 + let empty = width - filled; 761 + 762 + print!(" ["); 763 + for _ in 0..filled { 764 + print!("█"); 765 + } 766 + for _ in 0..empty { 767 + print!("░"); 768 + } 769 + println!("]"); 770 + } 771 + } 772 + ``` 773 + 774 + **Key Decisions:** 775 + - ✓ Show both memory regions (Sanctuary + Ephemeral) 776 + - ✓ Visual bars for quick understanding 777 + - ✓ Warn when memory is low 778 + - ✓ Object count (not just bytes) 779 + 780 + **Deliverables:** 781 + - [ ] `memory` command implementation 782 + - [ ] Memory usage bars 783 + - [ ] Warnings for low memory 784 + - [ ] Test: Allocate memory, view stats 785 + 786 + --- 787 + 788 + ### Step 3.5: Help Command 789 + 790 + **Purpose:** Guide the user with grace 791 + 792 + **Philosophy Alignment:** 793 + - Help is **teaching**, not documentation 794 + - Explain the philosophy behind commands 795 + - Encourage exploration 796 + 797 + **Implementation:** 798 + 799 + ```rust 800 + impl EldarinShell { 801 + fn cmd_help(&self, args: &[&str]) { 802 + if args.is_empty() { 803 + println!("\n❖ The Eldarin Shell - Conversing with the Heartwood ❖\n"); 804 + println!(" The Heartwood speaks these words:\n"); 805 + println!(" harmony - Reveal the system's inner balance"); 806 + println!(" threads - Show the threads of fate being woven"); 807 + println!(" memory - View the state of the Mana Pool"); 808 + println!(" help - Summon this guidance"); 809 + println!(" clear - Clear the vision"); 810 + println!(" echo - Speak, and hear your words returned"); 811 + println!(); 812 + println!(" Whisper 'help <command>' to learn more about each word."); 813 + println!(); 814 + } else { 815 + match args[0] { 816 + "harmony" => { 817 + println!("\n❖ harmony - Reveal system harmony\n"); 818 + println!(" The Heartwood measures harmony constantly."); 819 + println!(" Threads that yield often gain harmony."); 820 + println!(" Those that consume without giving become parasites."); 821 + println!(); 822 + println!(" The system does not punish parasites,"); 823 + println!(" but gently soothes them, slowing their pace."); 824 + println!(); 825 + println!(" This command reveals the current state of balance."); 826 + println!(); 827 + } 828 + "threads" => { 829 + println!("\n❖ threads - Show living threads\n"); 830 + println!(" Every thread has a purpose and a story."); 831 + println!(" Watch them weave, rest, and yield to others."); 832 + println!(); 833 + println!(" High harmony means cooperation."); 834 + println!(" Many yields means generosity."); 835 + println!(); 836 + } 837 + "memory" => { 838 + println!("\n❖ memory - View the Mana Pool\n"); 839 + println!(" Memory is sacred, allocated with purpose:"); 840 + println!(); 841 + println!(" • Sanctuary: Long-lived, stable allocations"); 842 + println!(" • Ephemeral Mist: Short-lived, temporary data"); 843 + println!(); 844 + println!(" Each object is protected by capabilities."); 845 + println!(" Access is granted, never stolen."); 846 + println!(); 847 + } 848 + unknown => { 849 + println!("\n❖ The Heartwood has no guidance for '{}'.", unknown); 850 + println!("❖ Whisper 'help' alone to hear all it knows."); 851 + println!(); 852 + } 853 + } 854 + } 855 + } 856 + } 857 + ``` 858 + 859 + **Key Decisions:** 860 + - ✓ Explain philosophy, not just syntax 861 + - ✓ Contextual help for each command 862 + - ✓ Poetic, memorable language 863 + - ✓ Encourage learning and exploration 864 + 865 + **Deliverables:** 866 + - [ ] `help` command with general list 867 + - [ ] Detailed help for each command 868 + - [ ] Philosophical explanations 869 + - [ ] Test: Run `help` and `help harmony` 870 + 871 + --- 872 + 873 + ## Phase 4: The Flow - Message-Based Architecture 874 + 875 + *"All communication flows through the Nexus, visible and purposeful."* 876 + 877 + ### Step 4.1: Complete Nexus Message Passing 878 + 879 + **Purpose:** Enable proper IPC between components 880 + 881 + **Philosophy Alignment:** 882 + - Messages are **contracts**, not data 883 + - Every message has a sender and purpose 884 + - Communication is observable (debugging) 885 + 886 + **Implementation:** 887 + 888 + ```rust 889 + // heartwood/src/nexus/mod.rs 890 + 891 + /// Send keyboard event to shell 892 + pub fn send_keyboard_event(event: KeyEvent) -> Result<(), NexusError> { 893 + let message = Message::new( 894 + MessageType::KeyboardEvent { event }, 895 + MessagePriority::High // User input is important 896 + ); 897 + 898 + // Find shell's channel 899 + let shell_channel = CHANNELS.lock() 900 + .find_channel_by_name("eldarin-shell")?; 901 + 902 + // Send message 903 + send_message(shell_channel, message) 904 + } 905 + 906 + /// Shell receives keyboard events 907 + pub fn receive_keyboard_event() -> Option<KeyEvent> { 908 + let my_channel = CHANNELS.lock() 909 + .get_my_channel()?; 910 + 911 + if let Some(message) = my_channel.try_receive()? { 912 + if let MessageType::KeyboardEvent { event } = message.message_type { 913 + return Some(event); 914 + } 915 + } 916 + 917 + None 918 + } 919 + ``` 920 + 921 + **Key Decisions:** 922 + - ✓ Named channels (not just IDs) 923 + - ✓ Priority-based delivery 924 + - ✓ Non-blocking receives (no deadlocks) 925 + - ✓ Message logging for debugging 926 + 927 + **Deliverables:** 928 + - [ ] Complete Nexus message passing 929 + - [ ] Channel creation/discovery 930 + - [ ] Message priority handling 931 + - [ ] Test: Send message, receive in another thread 932 + 933 + --- 934 + 935 + ## Phase 5: The Polish - User Experience 936 + 937 + *"Every detail matters. Beauty emerges from care."* 938 + 939 + ### Step 5.1: VGA Buffer Improvements 940 + 941 + **Purpose:** Make the display beautiful 942 + 943 + **Implementation:** 944 + 945 + - [ ] Scrolling when screen fills 946 + - [ ] Multiple colors for different message types 947 + - [ ] Cursor positioning for shell input 948 + - [ ] Line wrapping for long text 949 + 950 + --- 951 + 952 + ### Step 5.2: Advanced Shell Features 953 + 954 + **Purpose:** Refined interaction 955 + 956 + **Implementation:** 957 + 958 + - [ ] Arrow keys for history navigation 959 + - [ ] Tab completion for commands 960 + - [ ] Multi-line input with `\` 961 + - [ ] Command aliases 962 + 963 + --- 964 + 965 + ### Step 5.3: System Monitoring 966 + 967 + **Purpose:** Continuous awareness 968 + 969 + **Implementation:** 970 + 971 + - [ ] `top` command (live thread view) 972 + - [ ] `watch harmony` (continuous monitoring) 973 + - [ ] System uptime display 974 + - [ ] Harmony history graph (ASCII art) 975 + 976 + --- 977 + 978 + ## Implementation Timeline 979 + 980 + ### Week 1: Hardware Foundation 981 + - Day 1-2: IDT and exception handlers 982 + - Day 3-4: GDT and privilege rings 983 + - Day 5-6: Timer and keyboard drivers 984 + - Day 7: Testing and integration 985 + 986 + ### Week 2: Threading 987 + - Day 1-3: Context switching implementation 988 + - Day 4-5: Cooperative yielding 989 + - Day 6-7: Initial system threads 990 + 991 + ### Week 3: Shell 992 + - Day 1-2: Shell foundation and input handling 993 + - Day 3-4: Core commands (harmony, threads, memory) 994 + - Day 5-6: Help system and polish 995 + - Day 7: Testing and refinement 996 + 997 + ### Week 4: Integration 998 + - Day 1-3: Nexus message passing completion 999 + - Day 4-5: VGA improvements 1000 + - Day 6-7: End-to-end testing and debugging 1001 + 1002 + --- 1003 + 1004 + ## Testing Strategy 1005 + 1006 + ### For Each Phase: 1007 + 1008 + 1. **Unit Tests** (where possible in `no_std`) 1009 + - Test individual components 1010 + - Mock hardware interfaces 1011 + 1012 + 2. **QEMU Integration Tests** 1013 + - Boot and verify initialization 1014 + - Test commands produce expected output 1015 + - Verify harmony metrics change correctly 1016 + 1017 + 3. **Philosophy Validation** 1018 + - Does it follow Symbiotic Computing principles? 1019 + - Is the language beautiful and meaningful? 1020 + - Does it teach users about the system? 1021 + 1022 + --- 1023 + 1024 + ## Success Criteria 1025 + 1026 + AethelOS will be considered **interactive** when: 1027 + 1028 + ✓ User can type in QEMU and see characters 1029 + ✓ User can run commands and see output 1030 + ✓ `harmony` command shows real system state 1031 + ✓ `threads` command lists actual threads 1032 + ✓ `memory` command shows allocation state 1033 + ✓ System exhibits cooperative behavior 1034 + ✓ Error messages are helpful and poetic 1035 + ✓ The philosophy is evident in every interaction 1036 + 1037 + --- 1038 + 1039 + ## Philosophy Checkpoints 1040 + 1041 + Before completing each phase, verify: 1042 + 1043 + - [ ] Does this honor Harmony Over Hierarchy? 1044 + - [ ] Does this embody Purpose Over Protocol? 1045 + - [ ] Does this enable Emergence Over Engineering? 1046 + - [ ] Is the language beautiful? 1047 + - [ ] Is the behavior graceful? 1048 + - [ ] Does it teach and guide? 1049 + - [ ] Would this make the user feel wonder? 1050 + 1051 + --- 1052 + 1053 + *"When the user types 'harmony' and sees the system's soul revealed, 1054 + When threads weave cooperatively without force, 1055 + When memory flows with purpose and grace, 1056 + Then AethelOS will truly live."* 1057 + 1058 + — The Path to Awakening
+98
aethelos-source/Makefile
··· 1 + # Makefile for AethelOS 2 + # The build incantations for awakening the system 3 + 4 + .PHONY: all clean bootloader kernel groves runes test qemu 5 + 6 + # Colors for output 7 + COLOR_GREEN=\033[0;32m 8 + COLOR_BLUE=\033[0;34m 9 + COLOR_CYAN=\033[0;36m 10 + COLOR_RESET=\033[0m 11 + 12 + all: bootloader kernel groves runes 13 + @echo "$(COLOR_GREEN)[] AethelOS build complete!$(COLOR_RESET)" 14 + 15 + # Build the bootloader 16 + bootloader: 17 + @echo "$(COLOR_CYAN)[] Awakening the bootloader...$(COLOR_RESET)" 18 + nasm -f bin awakening/boot.asm -o build/boot.bin 19 + @echo "$(COLOR_GREEN)[] Bootloader ready$(COLOR_RESET)" 20 + 21 + # Build the Heartwood kernel 22 + kernel: 23 + @echo "$(COLOR_CYAN)[] Building the Heartwood...$(COLOR_RESET)" 24 + cd heartwood && cargo build --release 25 + @echo "$(COLOR_GREEN)[] Heartwood compiled$(COLOR_RESET)" 26 + 27 + # Build all Grove services 28 + groves: 29 + @echo "$(COLOR_CYAN)[] Growing the Groves...$(COLOR_RESET)" 30 + cd groves/world-tree_grove && cargo build --release 31 + cd groves/the-weave_grove && cargo build --release 32 + cd groves/lanthir_grove && cargo build --release 33 + cd groves/network_sprite && cargo build --release 34 + @echo "$(COLOR_GREEN)[] Groves flourishing$(COLOR_RESET)" 35 + 36 + # Build Ancient Runes libraries 37 + runes: 38 + @echo "$(COLOR_CYAN)[] Inscribing the Ancient Runes...$(COLOR_RESET)" 39 + cd ancient-runes/corelib && cargo build --release 40 + cd ancient-runes/weaving && cargo build --release 41 + cd ancient-runes/script && cargo build --release 42 + @echo "$(COLOR_GREEN)[] Runes inscribed$(COLOR_RESET)" 43 + 44 + # Run tests 45 + test: 46 + @echo "$(COLOR_CYAN)[] Testing the Heartwood...$(COLOR_RESET)" 47 + cd heartwood && cargo test 48 + @echo "$(COLOR_GREEN)[] Tests complete$(COLOR_RESET)" 49 + 50 + # Create build directory 51 + build: 52 + mkdir -p build 53 + 54 + # Run in QEMU (requires bootable image) 55 + qemu: build bootloader 56 + @echo "$(COLOR_BLUE)[] Awakening in QEMU...$(COLOR_RESET)" 57 + qemu-system-x86_64 -drive format=raw,file=build/boot.bin 58 + 59 + # Clean build artifacts 60 + clean: 61 + @echo "$(COLOR_CYAN)[] Returning to the void...$(COLOR_RESET)" 62 + cargo clean 63 + rm -rf build 64 + @echo "$(COLOR_GREEN)[] Clean complete$(COLOR_RESET)" 65 + 66 + # Check code formatting 67 + fmt: 68 + cargo fmt --all 69 + 70 + # Run clippy lints 71 + clippy: 72 + cargo clippy --all-targets --all-features 73 + 74 + # Generate documentation 75 + docs: 76 + cargo doc --workspace --no-deps --open 77 + 78 + # Show build information 79 + info: 80 + @echo "$(COLOR_BLUE)=====================================$(COLOR_RESET)" 81 + @echo "$(COLOR_BLUE) AethelOS Build System$(COLOR_RESET)" 82 + @echo "$(COLOR_BLUE)=====================================$(COLOR_RESET)" 83 + @echo "Version: 0.1.0-alpha" 84 + @echo "Language: Rust $(shell rustc --version | cut -d' ' -f2)" 85 + @echo "" 86 + @echo "Available targets:" 87 + @echo " all - Build everything" 88 + @echo " bootloader - Build the awakening sequence" 89 + @echo " kernel - Build the Heartwood" 90 + @echo " groves - Build all Grove services" 91 + @echo " runes - Build Ancient Runes libraries" 92 + @echo " test - Run tests" 93 + @echo " qemu - Run in QEMU emulator" 94 + @echo " clean - Remove build artifacts" 95 + @echo " fmt - Format code" 96 + @echo " clippy - Run lints" 97 + @echo " docs - Generate documentation" 98 + @echo "$(COLOR_BLUE)=====================================$(COLOR_RESET)"
+126
aethelos-source/NEXT-STEPS.md
··· 1 + # Next Steps for AethelOS Development 2 + 3 + Quick reference for what to implement next. 4 + 5 + ## Current Status ✓ 6 + 7 + - [x] Kernel architecture complete 8 + - [x] Capability-based security implemented 9 + - [x] Harmony-based scheduler with adaptive behavior 10 + - [x] Safety documentation added 11 + - [x] All libraries compile successfully 12 + - [x] Bootloader infrastructure ready (via setup scripts) 13 + 14 + ## Immediate Next: Make It Interactive 15 + 16 + See **[INTERACTION-PLAN.md](INTERACTION-PLAN.md)** for detailed philosophy-aligned implementation guide. 17 + 18 + ### Quick Path (4 Weeks) 19 + 20 + **Week 1: Hardware Attunement** 21 + ``` 22 + 1. Implement IDT (interrupts) 23 + 2. Implement GDT (privilege rings) 24 + 3. Add PIT timer (system heartbeat) 25 + 4. Add PS/2 keyboard driver 26 + ``` 27 + 28 + **Week 2: Thread Execution** 29 + ``` 30 + 5. Complete context switching 31 + 6. Implement cooperative yielding 32 + 7. Create initial system threads (idle, keyboard, shell) 33 + ``` 34 + 35 + **Week 3: Interactive Shell** 36 + ``` 37 + 8. Build Eldarin Shell foundation 38 + 9. Implement harmony command 39 + 10. Implement threads command 40 + 11. Implement memory command 41 + 12. Add help system 42 + ``` 43 + 44 + **Week 4: Integration & Polish** 45 + ``` 46 + 13. Complete Nexus message passing 47 + 14. Improve VGA buffer (scrolling, colors) 48 + 15. End-to-end testing 49 + 16. Philosophy validation 50 + ``` 51 + 52 + ## Start Here 53 + 54 + ### Option 1: Follow the Plan 55 + ```bash 56 + # Read the full plan 57 + cat INTERACTION-PLAN.md 58 + 59 + # Start with Phase 1, Step 1.1 60 + # Create: heartwood/src/attunement/idt.rs 61 + ``` 62 + 63 + ### Option 2: Quick Demo Path 64 + 65 + To see something working fast, skip to the shell: 66 + 67 + ```bash 68 + # 1. Create minimal shell (no hardware needed) 69 + # heartwood/src/eldarin_shell.rs 70 + 71 + # 2. Add to main loop: 72 + loop { 73 + // Mock keyboard input for testing 74 + shell.handle_key(get_mock_key()); 75 + } 76 + 77 + # 3. Test commands work 78 + # 4. Then add real hardware drivers 79 + ``` 80 + 81 + ## Key Files to Create 82 + 83 + Priority order: 84 + 85 + 1. **heartwood/src/attunement/idt.rs** - Interrupt handling 86 + 2. **heartwood/src/attunement/keyboard.rs** - User input 87 + 3. **heartwood/src/loom_of_fate/context.rs** - Thread switching 88 + 4. **ancient-runes/script/src/shell.rs** - User interface 89 + 5. **heartwood/src/nexus/channels.rs** - Message passing 90 + 91 + ## Philosophy Reminders 92 + 93 + When implementing, always ask: 94 + 95 + - ✓ Is this cooperative, not forced? 96 + - ✓ Does this teach the user? 97 + - ✓ Is the language beautiful? 98 + - ✓ Does it honor capabilities? 99 + - ✓ Will it inspire wonder? 100 + 101 + ## Resources 102 + 103 + - **[INTERACTION-PLAN.md](INTERACTION-PLAN.md)** - Complete roadmap 104 + - **[QUICKSTART-QEMU.md](QUICKSTART-QEMU.md)** - How to run/test 105 + - **[RUNNING.md](RUNNING.md)** - Technical details 106 + - **[GENESIS.scroll](GENESIS.scroll)** - The philosophy 107 + - **[DESIGN.md](DESIGN.md)** - Architecture reference 108 + 109 + ## Getting Help 110 + 111 + For OS development: 112 + - https://os.phil-opp.com/ - Excellent Rust OS tutorial 113 + - https://wiki.osdev.org/ - Hardware reference 114 + - https://forum.osdev.org/ - Community help 115 + 116 + For Rust bare-metal: 117 + - https://rust-embedded.github.io/book/ - Embedded Rust 118 + - https://doc.rust-lang.org/nomicon/ - Unsafe Rust 119 + 120 + --- 121 + 122 + **Ready to make AethelOS come alive?** 123 + 124 + Start with Phase 1, Step 1.1 in [INTERACTION-PLAN.md](INTERACTION-PLAN.md) 125 + 126 + *"The Heartwood awaits the Voice of Intent."*
+381
aethelos-source/QUICKSTART-QEMU.md
··· 1 + # Quick Start: Running AethelOS in QEMU 2 + 3 + This guide gets you from zero to booting AethelOS in QEMU in under 5 minutes. 4 + 5 + ## TL;DR - Three Commands 6 + 7 + ```bash 8 + # 1. Setup bootloader infrastructure 9 + ./setup-boot.sh # Linux/macOS 10 + .\setup-boot.ps1 # Windows 11 + 12 + # 2. Build the kernel 13 + ./build.sh # Linux/macOS 14 + .\build.ps1 # Windows 15 + 16 + # 3. Run in QEMU 17 + ./run-qemu.sh # Linux/macOS 18 + .\run-qemu.ps1 # Windows 19 + ``` 20 + 21 + ## Prerequisites 22 + 23 + ### 1. Install Rust 24 + ```bash 25 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 26 + ``` 27 + Or visit: https://rustup.rs/ 28 + 29 + ### 2. Install QEMU 30 + 31 + **Windows:** 32 + - Download: https://qemu.weilnetz.de/w64/ 33 + - Add to PATH or the scripts will find it automatically 34 + 35 + **Linux (Ubuntu/Debian):** 36 + ```bash 37 + sudo apt install qemu-system-x86 38 + ``` 39 + 40 + **macOS:** 41 + ```bash 42 + brew install qemu 43 + ``` 44 + 45 + ## Step-by-Step Setup 46 + 47 + ### Step 1: Run Setup Script 48 + 49 + This creates the bootloader infrastructure (linker script, multiboot header, build config): 50 + 51 + **Linux/macOS:** 52 + ```bash 53 + chmod +x setup-boot.sh 54 + ./setup-boot.sh 55 + ``` 56 + 57 + **Windows PowerShell:** 58 + ```powershell 59 + Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass 60 + .\setup-boot.ps1 61 + ``` 62 + 63 + **What it does:** 64 + - Creates `x86_64-aethelos.json` (custom target specification) 65 + - Creates `heartwood/linker.ld` (linker script) 66 + - Creates `heartwood/src/boot.rs` (Multiboot2 header) 67 + - Creates `.cargo/config.toml` (build configuration) 68 + - Creates `build.sh` and `run-qemu.sh` helper scripts 69 + 70 + ### Step 2: Build the Kernel 71 + 72 + **Linux/macOS:** 73 + ```bash 74 + ./build.sh 75 + ``` 76 + 77 + **Windows:** 78 + ```powershell 79 + .\build.ps1 80 + ``` 81 + 82 + This compiles AethelOS with: 83 + - Nightly Rust (for `build-std`) 84 + - Custom target (`x86_64-aethelos`) 85 + - No standard library 86 + - Multiboot2 bootable binary 87 + 88 + **Output:** `target/x86_64-aethelos/debug/heartwood` 89 + 90 + ### Step 3: Run in QEMU 91 + 92 + **Default (VGA display):** 93 + ```bash 94 + ./run-qemu.sh # Linux/macOS 95 + .\run-qemu.ps1 # Windows 96 + ``` 97 + 98 + **Other modes:** 99 + ```bash 100 + # Serial console only (no GUI) 101 + ./run-qemu.sh serial 102 + 103 + # Debug mode (shows interrupts, CPU resets) 104 + ./run-qemu.sh debug 105 + 106 + # GDB debugging (pauses at start, waits for GDB) 107 + ./run-qemu.sh gdb 108 + ``` 109 + 110 + ## What You'll See 111 + 112 + When AethelOS boots successfully, you should see: 113 + 114 + ``` 115 + [] Awakening the Heartwood... 116 + [] Kindling the Mana Pool... 117 + [] Opening the Nexus... 118 + [] Weaving the Loom of Fate... 119 + [] Attuning to the hardware... 120 + [] The Heartwood lives! 121 + ``` 122 + 123 + The system will then enter an idle loop (currently no interaction). 124 + 125 + ## QEMU Window Controls 126 + 127 + - **Close Window** - Stops QEMU 128 + - **Ctrl+Alt+G** - Release mouse capture 129 + - **Ctrl+Alt+F** - Toggle fullscreen 130 + - **Ctrl+Alt+1** - Switch to VGA display 131 + - **Ctrl+Alt+2** - Switch to QEMU monitor 132 + 133 + ### QEMU Monitor Commands 134 + 135 + Press `Ctrl+A, C` in serial mode to access the monitor: 136 + 137 + - `info registers` - Show CPU state 138 + - `info mem` - Show memory mappings 139 + - `info mtree` - Show memory tree 140 + - `q` or `quit` - Exit QEMU 141 + - `c` - Continue execution 142 + 143 + ## Debugging 144 + 145 + ### Enable Debug Output 146 + 147 + ```bash 148 + ./run-qemu.sh debug 149 + ``` 150 + 151 + Shows: 152 + - CPU resets 153 + - Interrupts (INT, exceptions) 154 + - Triple faults 155 + - Doesn't auto-reboot on crash 156 + 157 + ### GDB Debugging 158 + 159 + **Terminal 1 - Start QEMU:** 160 + ```bash 161 + ./run-qemu.sh gdb 162 + # QEMU pauses, waiting for GDB 163 + ``` 164 + 165 + **Terminal 2 - Connect GDB:** 166 + ```bash 167 + rust-gdb target/x86_64-aethelos/debug/heartwood 168 + 169 + # In GDB: 170 + (gdb) target remote :1234 171 + (gdb) break _start 172 + (gdb) continue 173 + (gdb) step 174 + (gdb) info registers 175 + ``` 176 + 177 + ### Check for Errors 178 + 179 + **Triple Fault (reboot loop):** 180 + ```bash 181 + # Run with debug mode to see what's happening 182 + ./run-qemu.sh debug 183 + 184 + # Common causes: 185 + # - Stack overflow 186 + # - Invalid interrupt handler 187 + # - Page fault 188 + # - Divide by zero 189 + ``` 190 + 191 + **Black Screen:** 192 + ```bash 193 + # Try serial console instead 194 + ./run-qemu.sh serial 195 + 196 + # VGA buffer might not be initialized correctly 197 + ``` 198 + 199 + **QEMU won't start:** 200 + ```bash 201 + # Check QEMU is installed 202 + qemu-system-x86_64 --version 203 + 204 + # Windows: Check PATH or QEMU install location 205 + ``` 206 + 207 + ## Current Limitations 208 + 209 + AethelOS is in early development. Currently: 210 + 211 + ✓ **Working:** 212 + - Boots in QEMU via Multiboot2 213 + - VGA text output 214 + - Kernel initialization 215 + - Memory management (structure) 216 + - Scheduler (structure) 217 + 218 + ❌ **Not Yet Implemented:** 219 + - Keyboard input (no interaction yet) 220 + - Interrupts/timers 221 + - Actual memory allocation 222 + - Thread execution 223 + - User-space processes 224 + - Filesystem 225 + - Networking 226 + 227 + ## Next Steps - Adding Interaction 228 + 229 + To make AethelOS interactive, you'll need to implement: 230 + 231 + ### 1. Keyboard Input 232 + ```rust 233 + // In heartwood/src/attunement/keyboard.rs 234 + pub fn read_key() -> Option<char> { 235 + // Read from PS/2 keyboard port 0x60 236 + } 237 + ``` 238 + 239 + ### 2. Simple Shell 240 + ```rust 241 + // In heartwood/src/main.rs 242 + loop { 243 + if let Some(key) = keyboard::read_key() { 244 + shell::handle_key(key); 245 + } 246 + } 247 + ``` 248 + 249 + ### 3. Basic Commands 250 + ```rust 251 + // Commands to implement: 252 + // - harmony -> Show system harmony metrics 253 + // - threads -> List all threads 254 + // - memory -> Show memory statistics 255 + // - help -> Show available commands 256 + ``` 257 + 258 + ## Advanced QEMU Options 259 + 260 + ### More Memory 261 + ```bash 262 + qemu-system-x86_64 -kernel heartwood -m 512M 263 + ``` 264 + 265 + ### Multiple CPUs 266 + ```bash 267 + qemu-system-x86_64 -kernel heartwood -smp 4 268 + ``` 269 + 270 + ### Enable KVM (Linux only - faster) 271 + ```bash 272 + qemu-system-x86_64 -kernel heartwood -enable-kvm 273 + ``` 274 + 275 + ### Serial + VGA 276 + ```bash 277 + qemu-system-x86_64 \ 278 + -kernel heartwood \ 279 + -vga std \ 280 + -serial mon:stdio \ 281 + -m 256M 282 + ``` 283 + 284 + ### Save Screenshots 285 + ```bash 286 + # In QEMU monitor (Ctrl+Alt+2) 287 + screendump screenshot.ppm 288 + ``` 289 + 290 + ## Rebuilding 291 + 292 + After making code changes: 293 + 294 + ```bash 295 + # Clean build 296 + cargo clean 297 + 298 + # Rebuild 299 + ./build.sh # Linux/macOS 300 + .\build.ps1 # Windows 301 + 302 + # Run 303 + ./run-qemu.sh 304 + ``` 305 + 306 + ## Troubleshooting 307 + 308 + ### Build Errors 309 + 310 + **"error: no global memory allocator"** 311 + - Fixed in current code - has DummyAllocator 312 + 313 + **"error: language item required, but not found: eh_personality"** 314 + - Make sure `panic = "abort"` is in Cargo.toml 315 + - Check you're using `no_std` 316 + 317 + **"error: linking with link.exe failed"** 318 + - This is expected for Windows host builds 319 + - The kernel binary still works fine 320 + - QEMU loads it directly, doesn't need Windows linking 321 + 322 + ### Runtime Errors 323 + 324 + **QEMU shows "No bootable device"** 325 + - Multiboot header missing or malformed 326 + - Run `setup-boot.sh` again 327 + - Check `heartwood/src/boot.rs` exists 328 + 329 + **Triple fault immediately** 330 + - Stack overflow - increase stack in linker.ld 331 + - Bad interrupt descriptor table 332 + - Run with `./run-qemu.sh debug` to see details 333 + 334 + **Kernel loads but black screen** 335 + - VGA buffer not initialized 336 + - Try serial mode: `./run-qemu.sh serial` 337 + - Check `vga_buffer::initialize()` is called 338 + 339 + ## Files Created by Setup 340 + 341 + ``` 342 + aethelos-source/ 343 + ├── x86_64-aethelos.json # Custom target spec 344 + ├── .cargo/ 345 + │ └── config.toml # Build configuration 346 + ├── heartwood/ 347 + │ ├── linker.ld # Linker script 348 + │ └── src/ 349 + │ └── boot.rs # Multiboot2 header 350 + ├── build.sh / build.ps1 # Build scripts 351 + └── run-qemu.sh / run-qemu.ps1 # Run scripts 352 + ``` 353 + 354 + ## Resources 355 + 356 + - **Full Documentation**: See `RUNNING.md` 357 + - **Architecture**: See `DESIGN.md` 358 + - **Philosophy**: See `GENESIS.scroll` 359 + - **Rust OSDev**: https://os.phil-opp.com/ 360 + - **OSDev Wiki**: https://wiki.osdev.org/ 361 + - **QEMU Manual**: https://www.qemu.org/docs/master/ 362 + 363 + ## Getting Help 364 + 365 + If you encounter issues: 366 + 367 + 1. Check `RUNNING.md` for detailed troubleshooting 368 + 2. Run with debug mode: `./run-qemu.sh debug` 369 + 3. Check build output for errors 370 + 4. Verify QEMU version: `qemu-system-x86_64 --version` 371 + 5. Ensure Rust nightly is installed: `rustup toolchain list` 372 + 373 + --- 374 + 375 + **Ready to boot?** 376 + 377 + ```bash 378 + ./setup-boot.sh && ./build.sh && ./run-qemu.sh 379 + ``` 380 + 381 + Welcome to AethelOS - where **Symbiotic Computing** comes alive! 🌳
+465
aethelos-source/QUICKSTART.md
··· 1 + # AethelOS Quick Start Guide 2 + 3 + Welcome to AethelOS! This guide will help you understand, build, and explore the system. 4 + 5 + ## Prerequisites 6 + 7 + ### Required Tools 8 + 9 + 1. **Rust Toolchain** (1.75 or later) 10 + ```bash 11 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 12 + rustup default stable 13 + ``` 14 + 15 + 2. **NASM** (Netwide Assembler) 16 + ```bash 17 + # Ubuntu/Debian 18 + sudo apt install nasm 19 + 20 + # macOS 21 + brew install nasm 22 + 23 + # Windows 24 + # Download from https://www.nasm.us/ 25 + ``` 26 + 27 + 3. **QEMU** (for testing) 28 + ```bash 29 + # Ubuntu/Debian 30 + sudo apt install qemu-system-x86 31 + 32 + # macOS 33 + brew install qemu 34 + 35 + # Windows 36 + # Download from https://www.qemu.org/download/ 37 + ``` 38 + 39 + 4. **Make** (optional but recommended) 40 + ```bash 41 + # Ubuntu/Debian 42 + sudo apt install build-essential 43 + 44 + # macOS 45 + xcode-select --install 46 + ``` 47 + 48 + ## Understanding the Codebase 49 + 50 + ### Architecture Overview 51 + 52 + ``` 53 + The Heartwood (Kernel) 54 + ├── Nexus: IPC system 55 + ├── Loom of Fate: Harmony-based scheduler 56 + ├── Mana Pool: Capability-based memory 57 + └── Attunement: Hardware abstraction 58 + 59 + The Groves (User Space) 60 + ├── World-Tree: Relational filesystem 61 + ├── The Weave: Vector compositor 62 + ├── Lanthir: Window manager 63 + └── Network Sprite: Network daemon 64 + 65 + Ancient Runes (Libraries) 66 + ├── Corelib: Standard library 67 + ├── Weaving: GUI toolkit 68 + └── Script: Shell API 69 + ``` 70 + 71 + ### Key Files to Read 72 + 73 + 1. **[GENESIS.scroll](GENESIS.scroll)** - The philosophical foundation 74 + 2. **[DESIGN.md](DESIGN.md)** - Technical deep dive 75 + 3. **[heartwood/src/main.rs](heartwood/src/main.rs)** - Kernel entry point 76 + 4. **[heartwood/src/nexus/mod.rs](heartwood/src/nexus/mod.rs)** - IPC system 77 + 5. **[heartwood/src/loom_of_fate/scheduler.rs](heartwood/src/loom_of_fate/scheduler.rs)** - Scheduler 78 + 79 + ## Building AethelOS 80 + 81 + ### Using Make (Recommended) 82 + 83 + ```bash 84 + # Show available targets 85 + make info 86 + 87 + # Build everything 88 + make all 89 + 90 + # Build individual components 91 + make bootloader 92 + make kernel 93 + make groves 94 + make runes 95 + 96 + # Run tests 97 + make test 98 + 99 + # Clean build artifacts 100 + make clean 101 + ``` 102 + 103 + ### Using Cargo Directly 104 + 105 + ```bash 106 + # Build the entire workspace 107 + cargo build --release 108 + 109 + # Build just the kernel 110 + cd heartwood 111 + cargo build --release 112 + 113 + # Build a specific Grove 114 + cd groves/world-tree_grove 115 + cargo build --release 116 + 117 + # Run tests 118 + cargo test --workspace 119 + ``` 120 + 121 + ### Build Output 122 + 123 + After building, you'll find: 124 + - **Kernel**: `target/release/heartwood` 125 + - **Groves**: `target/release/world-tree_grove`, etc. 126 + - **Libraries**: In each component's `target/release/` directory 127 + 128 + ## Running AethelOS 129 + 130 + ### Current Status 131 + 132 + **Note**: The current version (0.1.0-alpha) is a foundational implementation. The boot sequence and hardware initialization are not yet complete, so you cannot boot AethelOS on real hardware or in QEMU yet. 133 + 134 + What you *can* do: 135 + 1. Explore the code architecture 136 + 2. Run unit tests 137 + 3. Use the libraries in Rust projects 138 + 4. Experiment with the design 139 + 140 + ### When Bootable (Future) 141 + 142 + ```bash 143 + # Assemble bootloader 144 + nasm -f bin awakening/boot.asm -o build/boot.bin 145 + 146 + # Create bootable image 147 + # (Additional tools would be needed) 148 + 149 + # Run in QEMU 150 + qemu-system-x86_64 -drive format=raw,file=aethelos.img 151 + ``` 152 + 153 + ## Exploring the Code 154 + 155 + ### Example 1: Understanding the Nexus (IPC) 156 + 157 + The Nexus is the communication backbone of AethelOS. Here's how it works: 158 + 159 + ```rust 160 + // Create a channel (in heartwood/src/nexus/mod.rs) 161 + let (cap_a, cap_b) = nexus::create_channel()?; 162 + 163 + // Send a message 164 + let message = Message::new( 165 + MessageType::ResourceRequest { 166 + resource_type: ResourceType::Memory, 167 + amount: 4096, 168 + }, 169 + MessagePriority::Normal, 170 + ); 171 + nexus::send(cap_a.channel_id, message)?; 172 + 173 + // Receive the message 174 + let received = nexus::try_receive(cap_b.channel_id)?; 175 + ``` 176 + 177 + **Key Points**: 178 + - Communication is through capabilities (cap_a, cap_b), not raw IDs 179 + - Messages are prioritized (Critical, High, Normal, Low, Idle) 180 + - Non-blocking by default 181 + 182 + ### Example 2: Understanding the Loom of Fate (Scheduler) 183 + 184 + The scheduler maintains system harmony: 185 + 186 + ```rust 187 + // Spawn a thread (in heartwood/src/loom_of_fate/mod.rs) 188 + fn my_thread() -> ! { 189 + loop { 190 + // Do work 191 + perform_task(); 192 + 193 + // Yield cooperatively 194 + loom_of_fate::yield_now(); 195 + } 196 + } 197 + 198 + let thread_id = loom_of_fate::spawn(my_thread, ThreadPriority::Normal)?; 199 + 200 + // Get scheduler stats 201 + let stats = loom_of_fate::stats(); 202 + println!("System harmony: {}", stats.system_harmony); 203 + println!("Parasites detected: {}", stats.parasite_count); 204 + ``` 205 + 206 + **Key Points**: 207 + - Threads yield voluntarily (cooperative scheduling) 208 + - Harmony scores track resource usage 209 + - Parasitic threads are throttled, not killed 210 + 211 + ### Example 3: Understanding the Mana Pool (Memory) 212 + 213 + Memory is managed as abstract objects: 214 + 215 + ```rust 216 + // Allocate memory (in heartwood/src/mana_pool/mod.rs) 217 + let handle = mana_pool::animate( 218 + 4096, // Size in bytes 219 + AllocationPurpose::LongLived, // Goes to Sanctuary 220 + )?; 221 + 222 + // Memory is accessed through the handle (not raw pointers) 223 + // When handle is dropped, memory is automatically freed 224 + 225 + // Get pool statistics 226 + let stats = mana_pool::stats(); 227 + println!("Sanctuary used: {} / {}", 228 + stats.sanctuary_used, 229 + stats.sanctuary_total 230 + ); 231 + ``` 232 + 233 + **Key Points**: 234 + - No raw pointers in user space 235 + - Purpose-driven allocation (Sanctuary vs Ephemeral Mist) 236 + - Automatic reclamation when handle is dropped 237 + 238 + ## Running Tests 239 + 240 + ```bash 241 + # Run all tests 242 + cargo test --workspace 243 + 244 + # Run tests for a specific component 245 + cd heartwood 246 + cargo test 247 + 248 + # Run tests with output 249 + cargo test -- --nocapture 250 + 251 + # Run specific test 252 + cargo test test_nexus_create_channel 253 + ``` 254 + 255 + ## Code Style and Conventions 256 + 257 + ### Naming 258 + 259 + AethelOS uses evocative, metaphorical names: 260 + 261 + | Concept | AethelOS Name | Reason | 262 + |---------|---------------|--------| 263 + | Kernel | Heartwood | Core of a tree | 264 + | Scheduler | Loom of Fate | Weaving threads | 265 + | Memory Manager | Mana Pool | Lifeblood of the system | 266 + | IPC | Nexus | Connection point | 267 + | User Services | Groves | Growing from the Heartwood | 268 + | Libraries | Ancient Runes | Inscribed knowledge | 269 + 270 + ### Code Organization 271 + 272 + ```rust 273 + // Module structure 274 + mod nexus; 275 + mod loom_of_fate; 276 + mod mana_pool; 277 + 278 + // Each module has: 279 + // - mod.rs: Public API and exports 280 + // - {component}.rs: Implementation details 281 + // - tests.rs: Unit tests (optional) 282 + ``` 283 + 284 + ### Documentation 285 + 286 + Every public item should have documentation: 287 + 288 + ```rust 289 + /// Brief description of what this does 290 + /// 291 + /// ## Arguments 292 + /// * `param` - What this parameter means 293 + /// 294 + /// ## Returns 295 + /// What this function returns 296 + /// 297 + /// ## Errors 298 + /// When this might fail 299 + /// 300 + /// ## Example 301 + /// ```rust 302 + /// let result = function(42)?; 303 + /// ``` 304 + pub fn function(param: i32) -> Result<(), Error> { 305 + // ... 306 + } 307 + ``` 308 + 309 + ## Development Workflow 310 + 311 + ### 1. Make Changes 312 + 313 + Edit files in your editor of choice. 314 + 315 + ### 2. Format Code 316 + 317 + ```bash 318 + cargo fmt --all 319 + ``` 320 + 321 + ### 3. Check for Errors 322 + 323 + ```bash 324 + cargo check --workspace 325 + ``` 326 + 327 + ### 4. Run Lints 328 + 329 + ```bash 330 + cargo clippy --all-targets --all-features 331 + ``` 332 + 333 + ### 5. Run Tests 334 + 335 + ```bash 336 + cargo test --workspace 337 + ``` 338 + 339 + ### 6. Build 340 + 341 + ```bash 342 + make all 343 + # or 344 + cargo build --release --workspace 345 + ``` 346 + 347 + ## Common Tasks 348 + 349 + ### Adding a New Grove Service 350 + 351 + 1. Create directory: `groves/my_grove/` 352 + 2. Add Cargo.toml: 353 + ```toml 354 + [package] 355 + name = "my_grove" 356 + version.workspace = true 357 + authors.workspace = true 358 + edition.workspace = true 359 + ``` 360 + 3. Add to workspace in root Cargo.toml: 361 + ```toml 362 + members = [ 363 + # ... 364 + "groves/my_grove", 365 + ] 366 + ``` 367 + 4. Implement in `groves/my_grove/src/lib.rs` 368 + 369 + ### Adding a System Call 370 + 371 + 1. Define message type in `heartwood/src/nexus/message.rs`: 372 + ```rust 373 + pub enum MessageType { 374 + // ... 375 + MyNewRequest { data: u64 }, 376 + } 377 + ``` 378 + 379 + 2. Handle in appropriate kernel component 380 + 381 + 3. Export through public API 382 + 383 + ### Adding a Widget to Weaving 384 + 385 + 1. Edit `ancient-runes/weaving/src/lib.rs` 386 + 2. Implement the `Widget` trait: 387 + ```rust 388 + pub struct MyWidget { 389 + // fields 390 + } 391 + 392 + impl Widget for MyWidget { 393 + fn natural_size(&self) -> (f32, f32) { /* ... */ } 394 + fn render(&self) -> WidgetNode { /* ... */ } 395 + fn handle_event(&mut self, event: Event) { /* ... */ } 396 + } 397 + ``` 398 + 399 + ## Troubleshooting 400 + 401 + ### Build Errors 402 + 403 + **Problem**: Missing dependencies 404 + 405 + ```bash 406 + # Update Rust 407 + rustup update 408 + 409 + # Clean and rebuild 410 + cargo clean 411 + cargo build --release 412 + ``` 413 + 414 + **Problem**: Linker errors 415 + 416 + Check that you have the correct toolchain: 417 + ```bash 418 + rustc --version 419 + cargo --version 420 + ``` 421 + 422 + ### Test Failures 423 + 424 + ```bash 425 + # Run with verbose output 426 + cargo test -- --nocapture --test-threads=1 427 + 428 + # Run specific failing test 429 + cargo test failing_test_name -- --exact 430 + ``` 431 + 432 + ## Next Steps 433 + 434 + 1. **Read the design document**: [DESIGN.md](DESIGN.md) 435 + 2. **Explore the kernel**: Start with [heartwood/src/main.rs](heartwood/src/main.rs) 436 + 3. **Try the examples**: See the examples/ directory (when created) 437 + 4. **Join development**: See CONTRIBUTING.md (when created) 438 + 439 + ## Resources 440 + 441 + - **Official Docs**: See [DESIGN.md](DESIGN.md) and [GENESIS.scroll](GENESIS.scroll) 442 + - **Rust Book**: https://doc.rust-lang.org/book/ 443 + - **OS Dev Wiki**: https://wiki.osdev.org/ 444 + - **Rust OS Tutorial**: https://os.phil-opp.com/ 445 + 446 + ## Getting Help 447 + 448 + Since this is an experimental project, the best way to learn is by reading the code and documentation. Key files to understand: 449 + 450 + 1. **GENESIS.scroll** - Philosophy 451 + 2. **DESIGN.md** - Architecture 452 + 3. **README.md** - Overview 453 + 4. **This file** - Practical guide 454 + 455 + ## Philosophy 456 + 457 + Remember: AethelOS is not about building a production OS. It's about exploring *what's possible* when we question our assumptions about how operating systems should work. 458 + 459 + The code is the documentation. The architecture is the argument. The system is the proof. 460 + 461 + --- 462 + 463 + *"The code does not command the silicon. The silicon does not serve the code. They dance together, and in that dance, life emerges."* 464 + 465 + Happy exploring! 🌳
+255
aethelos-source/README.md
··· 1 + # AethelOS - A Symbiotic Operating System 2 + 3 + ![Version](https://img.shields.io/badge/version-0.1.0--alpha-blue) 4 + ![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-green) 5 + ![Language](https://img.shields.io/badge/language-Rust-orange) 6 + 7 + > *"The code does not command the silicon. The silicon does not serve the code. They dance together, and in that dance, life emerges."* 8 + 9 + --- 10 + 11 + ## Overview 12 + 13 + AethelOS is a radical reimagining of what an operating system can be. It is not Linux, not Windows, not macOS - it is a self-contained digital realm built on the principles of **symbiotic computing**, where the OS, hardware, and user exist in harmonious equilibrium. 14 + 15 + ## Core Philosophy 16 + 17 + ### Symbiotic Computing 18 + 19 + - **Harmony Over Force**: The system negotiates, not preempts 20 + - **Memory Over Forgetting**: Every file carries the memory-rings of its history 21 + - **Beauty as Necessity**: Aesthetics reveal intuitive system state 22 + - **Security Through Nature**: Safety through natural capability boundaries 23 + 24 + ## Architecture 25 + 26 + ### The Heartwood (Kernel) 27 + 28 + A hybrid microkernel containing only the most sacred responsibilities: 29 + 30 + - **The Loom of Fate**: Harmony-based cooperative scheduler 31 + - Thread states: Weaving, Resting, Tangled, Fading 32 + - Resource negotiation based on system-wide harmony 33 + - Parasite detection and throttling (not killing) 34 + 35 + - **The Mana Pool**: Capability-based memory management 36 + - No raw pointers in user space 37 + - Purpose-driven allocation (Sanctuary vs Ephemeral Mist) 38 + - Automatic reclamation via reference counting 39 + 40 + - **The Nexus**: High-speed asynchronous message passing (IPC) 41 + - Priority-aware message delivery 42 + - Capability-based addressing 43 + - Zero-copy where possible 44 + 45 + - **Attunement Layer**: Hardware abstraction interface 46 + - CPU feature detection and management 47 + - Interrupt handling 48 + - Timer management 49 + 50 + ### The Groves (User-Space Services) 51 + 52 + Isolated processes that grow from the Heartwood: 53 + 54 + - **World-Tree Grove**: Relational database filesystem 55 + - Query-based file access (not path-based) 56 + - Built-in versioning (Chronurgy) 57 + - Rich metadata (Creator, Genesis Time, Essence, Connections) 58 + 59 + - **The Weave Grove**: Vector-based scene graph compositor 60 + - Resolution-independent rendering 61 + - First-class shader support (Glyphs) 62 + - Fluid transformations and effects 63 + 64 + - **Lanthir Grove**: Window management service 65 + - Harmonic window arrangement 66 + - Non-rectangular window shapes 67 + 68 + - **Network Sprite**: Network daemon 69 + - Connection-oriented architecture 70 + - Natural data flow 71 + 72 + ### Ancient Runes (Core Libraries) 73 + 74 + APIs for developers: 75 + 76 + - **Corelib**: Standard data structures and utilities 77 + - **Weaving API**: Toolkit for graphical applications 78 + - **Eldarin Script**: Shell interaction library 79 + 80 + ## Project Structure 81 + 82 + ``` 83 + aethelos-source/ 84 + ├── GENESIS.scroll # Philosophical and architectural overview 85 + ├── Cargo.toml # Workspace configuration 86 + 87 + ├── awakening/ # Bootloader 88 + │ ├── boot.asm # First stage (assembly) 89 + │ └── heartwood_loader/ # Second stage (Rust) 90 + 91 + ├── heartwood/ # The Kernel 92 + │ ├── nexus/ # IPC system 93 + │ ├── loom-of-fate/ # Scheduler 94 + │ ├── mana-pool/ # Memory management 95 + │ └── attunement/ # Hardware abstraction 96 + 97 + ├── groves/ # User-space services 98 + │ ├── world-tree_grove/ # Filesystem 99 + │ ├── the-weave_grove/ # Compositor 100 + │ ├── lanthir_grove/ # Window manager 101 + │ └── network_sprite/ # Network daemon 102 + 103 + └── ancient-runes/ # Core libraries 104 + ├── corelib/ # Standard library 105 + ├── weaving/ # GUI toolkit 106 + └── script/ # Shell API 107 + ``` 108 + 109 + ## Building 110 + 111 + ### Prerequisites 112 + 113 + - Rust 1.75 or later 114 + - NASM (for boot.asm) 115 + - QEMU (for testing) 116 + 117 + ### Build Commands 118 + 119 + ```bash 120 + # Build the entire workspace 121 + cargo build --release 122 + 123 + # Build just the kernel 124 + cd heartwood 125 + cargo build --release 126 + 127 + # Build a specific Grove 128 + cd groves/world-tree_grove 129 + cargo build --release 130 + ``` 131 + 132 + ### Running in QEMU 133 + 134 + ```bash 135 + # Assemble the bootloader 136 + nasm -f bin awakening/boot.asm -o boot.bin 137 + 138 + # Create a bootable disk image 139 + # (Additional steps would be needed for a complete bootable image) 140 + 141 + # Run in QEMU 142 + qemu-system-x86_64 -drive format=raw,file=boot.bin 143 + ``` 144 + 145 + ## Key Innovations 146 + 147 + ### 1. Harmony-Based Scheduling 148 + 149 + Instead of preemptive scheduling with fixed time slices, the Loom of Fate: 150 + - Analyzes system-wide harmony metrics 151 + - Detects parasitic behavior through resource usage patterns 152 + - Throttles (soothes) greedy processes instead of killing them 153 + - Rewards cooperative yielding behavior 154 + 155 + ### 2. Capability-Based Memory 156 + 157 + User-space processes never see raw memory addresses: 158 + - All memory access is through opaque handles 159 + - Capabilities grant specific rights (read, write, execute, transfer) 160 + - MMU enforces boundaries at hardware level 161 + - Automatic deallocation when last handle is released 162 + 163 + ### 3. Query-Based Filesystem 164 + 165 + Files are database objects, not paths: 166 + ```rust 167 + // Instead of: /home/user/documents/poem.txt 168 + // You query: 169 + Seek { 170 + Essence: "Scroll", 171 + Creator: "Elara", 172 + Name: "Poem" 173 + } 174 + ``` 175 + 176 + Built-in versioning means you can access any historical state: 177 + ```rust 178 + // Read the file as it existed 3 days ago 179 + Seek { 180 + Essence: "Scroll", 181 + Name: "Config", 182 + Timestamp: now() - days(3) 183 + } 184 + ``` 185 + 186 + ### 4. Vector-Based Graphics 187 + 188 + The Weave renders everything mathematically: 189 + - Windows defined as Bézier curves 190 + - Infinite resolution independence 191 + - Shaders (Glyphs) as first-class primitives 192 + - Fluid animations through transform modifications 193 + 194 + ## Current Status 195 + 196 + **Version 0.1.0-alpha** - "The First Breath" 197 + 198 + This is a foundational implementation demonstrating the core architecture and philosophy. Currently implemented: 199 + 200 + ✅ Complete architectural design 201 + ✅ Heartwood kernel structure (Nexus, Loom of Fate, Mana Pool, Attunement) 202 + ✅ All Grove services (stubs) 203 + ✅ Ancient Runes libraries (basic implementations) 204 + ✅ Boot sequence design 205 + 206 + ### Not Yet Implemented 207 + 208 + - Actual hardware initialization 209 + - Real memory allocator (currently using placeholder bump allocator) 210 + - Complete interrupt handling 211 + - Physical device drivers 212 + - Full filesystem implementation 213 + - Graphics rendering pipeline 214 + - Network stack 215 + 216 + ## Why AethelOS? 217 + 218 + AethelOS is not meant to replace existing operating systems. It's an exploration of what's possible when we: 219 + 220 + 1. **Question Assumptions**: Why must files be paths? Why must scheduling be preemptive? 221 + 2. **Prioritize Beauty**: Can an OS be art as well as utility? 222 + 3. **Embrace Metaphor**: Can naming and design reflect a coherent philosophy? 223 + 4. **Value Longevity**: What if we designed for 100-year timescales? 224 + 225 + ## Contributing 226 + 227 + This is currently an experimental, educational project. Contributions are welcome, especially for: 228 + 229 + - Completing hardware initialization 230 + - Implementing real device drivers 231 + - Building out the graphics pipeline 232 + - Creating example applications using Ancient Runes 233 + 234 + ## License 235 + 236 + Licensed under either of: 237 + 238 + - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE)) 239 + - MIT license ([LICENSE-MIT](LICENSE-MIT)) 240 + 241 + at your option. 242 + 243 + ## Acknowledgments 244 + 245 + Inspired by: 246 + - The microkernel philosophy (Minix, L4, seL4) 247 + - Capability-based security (KeyKOS, EROS) 248 + - Plan 9's everything-is-a-file taken further 249 + - The aesthetic vision of Elven computing 250 + 251 + --- 252 + 253 + > *"This is not an OS for everyone. It is an OS for those who believe computing can be more than utility—that it can be art, philosophy, and symbiosis."* 254 + 255 + *For more details, see [GENESIS.scroll](GENESIS.scroll)*
+381
aethelos-source/RUNNING.md
··· 1 + # Running AethelOS in QEMU 2 + 3 + This guide explains how to build and run AethelOS in QEMU. 4 + 5 + ## Current Status 6 + 7 + AethelOS is currently in **early development**. The kernel libraries compile successfully, but the bootloader infrastructure needs to be completed before it can run in QEMU. 8 + 9 + ## Prerequisites 10 + 11 + ### Required Tools 12 + 13 + 1. **Rust** (stable 1.90+) 14 + ```bash 15 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 16 + rustup default stable 17 + ``` 18 + 19 + 2. **QEMU** (for x86_64) 20 + - **Windows**: Download from https://qemu.weilnetz.de/w64/ 21 + - **Linux**: `sudo apt install qemu-system-x86` 22 + - **macOS**: `brew install qemu` 23 + 24 + 3. **Rust cargo-binutils** (for creating bootable images) 25 + ```bash 26 + cargo install cargo-binutils 27 + rustup component add llvm-tools-preview 28 + ``` 29 + 30 + ## What Needs to Be Completed 31 + 32 + To make AethelOS bootable, the following components need implementation: 33 + 34 + ### 1. Custom Target Specification 35 + 36 + Create `x86_64-aethelos.json`: 37 + ```json 38 + { 39 + "llvm-target": "x86_64-unknown-none", 40 + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", 41 + "arch": "x86_64", 42 + "target-endian": "little", 43 + "target-pointer-width": "64", 44 + "target-c-int-width": "32", 45 + "os": "none", 46 + "executables": true, 47 + "linker-flavor": "ld.lld", 48 + "linker": "rust-lld", 49 + "panic-strategy": "abort", 50 + "disable-redzone": true, 51 + "features": "-mmx,-sse,+soft-float" 52 + } 53 + ``` 54 + 55 + ### 2. Linker Script 56 + 57 + Create `heartwood/linker.ld`: 58 + ```ld 59 + ENTRY(_start) 60 + 61 + SECTIONS { 62 + . = 1M; 63 + 64 + .boot : 65 + { 66 + KEEP(*(.multiboot)) 67 + } 68 + 69 + .text : 70 + { 71 + *(.text .text.*) 72 + } 73 + 74 + .rodata : 75 + { 76 + *(.rodata .rodata.*) 77 + } 78 + 79 + .data : 80 + { 81 + *(.data .data.*) 82 + } 83 + 84 + .bss : 85 + { 86 + *(.bss .bss.*) 87 + } 88 + 89 + /DISCARD/ : 90 + { 91 + *(.eh_frame) 92 + } 93 + } 94 + ``` 95 + 96 + ### 3. Multiboot2 Header 97 + 98 + Add to `heartwood/src/boot.rs`: 99 + ```rust 100 + #[repr(C, align(8))] 101 + struct Multiboot2Header { 102 + magic: u32, 103 + architecture: u32, 104 + header_length: u32, 105 + checksum: u32, 106 + // End tag 107 + end_tag: [u32; 2], 108 + } 109 + 110 + #[used] 111 + #[link_section = ".multiboot"] 112 + static MULTIBOOT2_HEADER: Multiboot2Header = Multiboot2Header { 113 + magic: 0xe85250d6, 114 + architecture: 0, // i386 115 + header_length: core::mem::size_of::<Multiboot2Header>() as u32, 116 + checksum: 0u32.wrapping_sub( 117 + 0xe85250d6 + 0 + core::mem::size_of::<Multiboot2Header>() as u32 118 + ), 119 + end_tag: [0, 8], 120 + }; 121 + ``` 122 + 123 + ### 4. Cargo Build Configuration 124 + 125 + Create `.cargo/config.toml`: 126 + ```toml 127 + [build] 128 + target = "x86_64-aethelos.json" 129 + 130 + [target.'cfg(target_os = "none")'] 131 + runner = "bootimage runner" 132 + 133 + [unstable] 134 + build-std = ["core", "alloc"] 135 + build-std-features = ["compiler-builtins-mem"] 136 + ``` 137 + 138 + ### 5. Alternative: Use bootloader crate 139 + 140 + The easier approach is to use the `bootloader` crate: 141 + 142 + Add to `heartwood/Cargo.toml`: 143 + ```toml 144 + [dependencies] 145 + bootloader = "0.9" 146 + ``` 147 + 148 + Update `Cargo.toml` root: 149 + ```toml 150 + [dependencies] 151 + bootimage = "0.10" 152 + ``` 153 + 154 + ## Building (Once Bootloader is Complete) 155 + 156 + ### Option A: Using bootloader crate 157 + ```bash 158 + # Install bootimage 159 + cargo install bootimage 160 + 161 + # Build the kernel 162 + cd heartwood 163 + cargo bootimage 164 + 165 + # The bootable image is created at: 166 + # target/x86_64-aethelos/debug/bootimage-heartwood.bin 167 + ``` 168 + 169 + ### Option B: Manual build with linker script 170 + ```bash 171 + # Build for custom target 172 + cargo build --target x86_64-aethelos.json 173 + 174 + # Create bootable ISO 175 + mkdir -p isofiles/boot/grub 176 + cp target/x86_64-aethelos/debug/heartwood isofiles/boot/heartwood 177 + 178 + # Create GRUB config 179 + cat > isofiles/boot/grub/grub.cfg << EOF 180 + menuentry "AethelOS" { 181 + multiboot2 /boot/heartwood 182 + boot 183 + } 184 + EOF 185 + 186 + # Create ISO 187 + grub-mkrescue -o aethelos.iso isofiles 188 + ``` 189 + 190 + ## Running in QEMU (Once Bootable) 191 + 192 + ### Basic Boot 193 + ```bash 194 + qemu-system-x86_64 -drive format=raw,file=bootimage-heartwood.bin 195 + ``` 196 + 197 + ### With Serial Console Output 198 + ```bash 199 + qemu-system-x86_64 \ 200 + -drive format=raw,file=bootimage-heartwood.bin \ 201 + -serial stdio \ 202 + -display none 203 + ``` 204 + 205 + ### With VGA Display (Recommended) 206 + ```bash 207 + qemu-system-x86_64 \ 208 + -drive format=raw,file=bootimage-heartwood.bin \ 209 + -vga std \ 210 + -serial mon:stdio 211 + ``` 212 + 213 + ### With Debugging 214 + ```bash 215 + qemu-system-x86_64 \ 216 + -drive format=raw,file=bootimage-heartwood.bin \ 217 + -serial stdio \ 218 + -d int,cpu_reset \ 219 + -no-reboot \ 220 + -no-shutdown 221 + ``` 222 + 223 + ### Full Featured Run 224 + ```bash 225 + qemu-system-x86_64 \ 226 + -drive format=raw,file=bootimage-heartwood.bin \ 227 + -m 256M \ 228 + -vga std \ 229 + -serial mon:stdio \ 230 + -cpu max \ 231 + -smp 2 \ 232 + -enable-kvm # Linux only, for better performance 233 + ``` 234 + 235 + ## Expected Output (When Running) 236 + 237 + When AethelOS successfully boots, you should see: 238 + 239 + ``` 240 + [] Awakening the Heartwood... 241 + [] Kindling the Mana Pool... 242 + [] Opening the Nexus... 243 + [] Weaving the Loom of Fate... 244 + [] Attuning to the hardware... 245 + [] The Heartwood lives! 246 + 247 + [AethelOS Banner displayed via VGA buffer] 248 + ``` 249 + 250 + ## Interacting with AethelOS 251 + 252 + Currently, AethelOS enters an idle loop after initialization. To add interaction: 253 + 254 + ### 1. Keyboard Input 255 + Add keyboard driver in `attunement/keyboard.rs` to read PS/2 keyboard events. 256 + 257 + ### 2. Serial Console 258 + Enable UART 16550 serial driver for text-based interaction: 259 + ```rust 260 + // In attunement/mod.rs 261 + pub mod serial; 262 + 263 + // Add serial commands 264 + pub fn serial_read() -> Option<u8>; 265 + pub fn serial_write(byte: u8); 266 + ``` 267 + 268 + ### 3. Shell Interface 269 + Implement the Eldarin Shell (placeholder in `ancient-runes/script`): 270 + - Parse commands 271 + - Execute via Nexus IPC 272 + - Display results in VGA buffer 273 + 274 + ## QEMU Monitor Commands 275 + 276 + When running with `-serial mon:stdio`, you can use: 277 + 278 + - `Ctrl+A, C` - Switch to QEMU monitor 279 + - `info registers` - Show CPU state 280 + - `info mem` - Show memory mappings 281 + - `info mtree` - Show memory tree 282 + - `q` or `quit` - Exit QEMU 283 + 284 + ## Debugging with GDB 285 + 286 + Terminal 1 - Start QEMU with GDB server: 287 + ```bash 288 + qemu-system-x86_64 \ 289 + -drive format=raw,file=bootimage-heartwood.bin \ 290 + -s -S 291 + ``` 292 + 293 + Terminal 2 - Connect GDB: 294 + ```bash 295 + rust-gdb target/x86_64-aethelos/debug/heartwood 296 + (gdb) target remote :1234 297 + (gdb) break _start 298 + (gdb) continue 299 + ``` 300 + 301 + ## Troubleshooting 302 + 303 + ### "No bootable device" Error 304 + - Ensure multiboot2 header is properly included 305 + - Check linker script places `.multiboot` section first 306 + - Verify GRUB can find the kernel 307 + 308 + ### Black Screen 309 + - VGA buffer initialization may have failed 310 + - Try serial output instead: `-serial stdio -display none` 311 + - Check panic handler is being called 312 + 313 + ### Triple Fault / Reboot Loop 314 + - Stack overflow (increase stack size in linker script) 315 + - Invalid interrupt descriptor table 316 + - Page fault due to incorrect memory mapping 317 + - Use QEMU debugging: `-d int,cpu_reset -no-reboot` 318 + 319 + ### Build Errors 320 + - Ensure using `--target x86_64-aethelos.json` 321 + - Check all `no_std` crates are compatible 322 + - Verify `build-std` is enabled in `.cargo/config.toml` 323 + 324 + ## Next Steps for Full Bootability 325 + 326 + 1. **Implement Multiboot2 Support** 327 + - Add multiboot2 header 328 + - Parse bootloader information 329 + - Set up initial page tables 330 + 331 + 2. **Complete Hardware Initialization** 332 + - Set up IDT (Interrupt Descriptor Table) 333 + - Configure GDT (Global Descriptor Table) 334 + - Enable hardware interrupts 335 + 336 + 3. **Implement Memory Management** 337 + - Initialize physical memory manager 338 + - Set up heap allocator with actual memory region 339 + - Complete Sanctuary and Ephemeral Mist allocators 340 + 341 + 4. **Add Device Drivers** 342 + - VGA text mode (currently placeholder) 343 + - PS/2 keyboard 344 + - Serial UART (for debugging) 345 + - Timer (PIT or APIC) 346 + 347 + 5. **Enable User Interaction** 348 + - Implement keyboard input handler 349 + - Create simple shell (Eldarin) 350 + - Add basic commands (harmony, threads, memory stats) 351 + 352 + ## Resources 353 + 354 + - **Rust OSDev**: https://os.phil-opp.com/ 355 + - **OSDev Wiki**: https://wiki.osdev.org/ 356 + - **QEMU Documentation**: https://www.qemu.org/docs/master/ 357 + - **Multiboot2 Spec**: https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html 358 + 359 + ## Current Development Status 360 + 361 + ✓ **Completed:** 362 + - Kernel library architecture 363 + - Capability-based memory management 364 + - Harmony-based cooperative scheduler 365 + - Nexus IPC system (structure) 366 + - Basic VGA buffer (placeholder) 367 + 368 + ⚠ **In Progress:** 369 + - Bootloader integration 370 + - Hardware initialization 371 + - Device drivers 372 + 373 + ❌ **Not Yet Started:** 374 + - User-space services (Groves) 375 + - Filesystem (World-Tree) 376 + - GUI (The Weave, Lanthir) 377 + - Network stack (Network Sprite) 378 + 379 + --- 380 + 381 + **Note:** AethelOS is an experimental operating system focused on "Symbiotic Computing" philosophy. The current code represents the architectural foundation. Full QEMU support requires completing the bootloader and hardware initialization layers.
+7
aethelos-source/ancient-runes/corelib/Cargo.toml
··· 1 + [package] 2 + name = "corelib" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies]
+83
aethelos-source/ancient-runes/corelib/src/lib.rs
··· 1 + //! # Corelib - Ancient Runes 2 + //! 3 + //! The standard library for AethelOS applications. 4 + //! These are the fundamental runes that all programs use 5 + //! to weave their purpose into existence. 6 + //! 7 + //! ## Philosophy 8 + //! Corelib does not impose patterns; it provides essence. 9 + //! These are the building blocks from which harmony emerges. 10 + 11 + #![no_std] 12 + 13 + extern crate alloc; 14 + 15 + /// Common collections 16 + pub mod collections { 17 + pub use alloc::vec::Vec; 18 + pub use alloc::string::String; 19 + pub use alloc::collections::BTreeMap; 20 + pub use alloc::collections::VecDeque; 21 + } 22 + 23 + /// String utilities 24 + pub mod strings { 25 + /// Check if a string is empty 26 + pub fn is_empty(s: &str) -> bool { 27 + s.len() == 0 28 + } 29 + 30 + /// Count the number of graphemes (visible characters) 31 + pub fn grapheme_count(s: &str) -> usize { 32 + s.chars().count() 33 + } 34 + } 35 + 36 + /// Mathematical utilities 37 + pub mod math { 38 + /// Clamp a value between min and max 39 + pub fn clamp<T: PartialOrd>(value: T, min: T, max: T) -> T { 40 + if value < min { 41 + min 42 + } else if value > max { 43 + max 44 + } else { 45 + value 46 + } 47 + } 48 + 49 + /// Linear interpolation 50 + pub fn lerp(a: f32, b: f32, t: f32) -> f32 { 51 + a + (b - a) * t 52 + } 53 + 54 + /// Smooth step interpolation 55 + pub fn smoothstep(a: f32, b: f32, t: f32) -> f32 { 56 + let t = clamp((t - a) / (b - a), 0.0, 1.0); 57 + t * t * (3.0 - 2.0 * t) 58 + } 59 + } 60 + 61 + /// Result and error handling 62 + pub mod result { 63 + /// A result type for AethelOS operations 64 + pub type AethelResult<T> = Result<T, AethelError>; 65 + 66 + /// Common errors in AethelOS 67 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 68 + pub enum AethelError { 69 + OutOfMemory, 70 + InvalidArgument, 71 + PermissionDenied, 72 + NotFound, 73 + AlreadyExists, 74 + Timeout, 75 + Disconnected, 76 + } 77 + } 78 + 79 + /// Re-exports for convenience 80 + pub use collections::*; 81 + pub use strings::*; 82 + pub use math::*; 83 + pub use result::*;
+8
aethelos-source/ancient-runes/script/Cargo.toml
··· 1 + [package] 2 + name = "script" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies] 8 + corelib = { path = "../corelib" }
+66
aethelos-source/ancient-runes/script/src/lib.rs
··· 1 + //! # Eldarin Script - Shell Interaction API 2 + //! 3 + //! The library for building shell scripts and interactive 4 + //! command-line tools in AethelOS. 5 + //! 6 + //! ## Philosophy 7 + //! Scripts are not mere automation; they are incantations 8 + //! that speak the language of the system. 9 + 10 + #![no_std] 11 + 12 + extern crate alloc; 13 + 14 + use alloc::string::String; 15 + 16 + /// Execute a command in the Eldarin shell 17 + pub fn execute(command: &str) -> Result<CommandResult, ScriptError> { 18 + // In a real implementation, this would: 19 + // 1. Parse the command 20 + // 2. Send it to the shell service via the Nexus 21 + // 3. Wait for the result 22 + // 4. Return output 23 + 24 + Ok(CommandResult { 25 + output: String::new(), 26 + exit_code: 0, 27 + }) 28 + } 29 + 30 + /// Result of executing a command 31 + pub struct CommandResult { 32 + pub output: String, 33 + pub exit_code: i32, 34 + } 35 + 36 + /// Errors that can occur during script execution 37 + #[derive(Debug)] 38 + pub enum ScriptError { 39 + CommandNotFound, 40 + PermissionDenied, 41 + ExecutionFailed, 42 + Timeout, 43 + } 44 + 45 + /// Print to the shell output 46 + pub fn print(text: &str) { 47 + // In a real implementation, send to shell via Nexus 48 + } 49 + 50 + /// Print with a newline 51 + pub fn println(text: &str) { 52 + print(text); 53 + print("\n"); 54 + } 55 + 56 + /// Read input from the user 57 + pub fn read_line() -> Result<String, ScriptError> { 58 + // In a real implementation, block waiting for input from shell 59 + Ok(String::new()) 60 + } 61 + 62 + /// Prompt the user with a question 63 + pub fn prompt(question: &str) -> Result<String, ScriptError> { 64 + print(question); 65 + read_line() 66 + }
+8
aethelos-source/ancient-runes/weaving/Cargo.toml
··· 1 + [package] 2 + name = "weaving" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies] 8 + corelib = { path = "../corelib" }
+156
aethelos-source/ancient-runes/weaving/src/lib.rs
··· 1 + //! # Weaving - The Weave API 2 + //! 3 + //! The toolkit for building graphical applications in AethelOS. 4 + //! Applications do not draw pixels; they weave intentions 5 + //! into the living tapestry of the Weave. 6 + //! 7 + //! ## Philosophy 8 + //! Weaving is not about control; it's about expression. 9 + //! You describe what should be, and the Weave makes it so. 10 + 11 + #![no_std] 12 + 13 + extern crate alloc; 14 + 15 + use alloc::vec::Vec; 16 + use alloc::boxed::Box; 17 + 18 + /// A widget in the Weave 19 + pub trait Widget { 20 + /// Get the natural size of this widget 21 + fn natural_size(&self) -> (f32, f32); 22 + 23 + /// Render this widget to the scene graph 24 + fn render(&self) -> WidgetNode; 25 + 26 + /// Handle an event 27 + fn handle_event(&mut self, event: Event); 28 + } 29 + 30 + /// A node representing a widget in the scene graph 31 + pub struct WidgetNode { 32 + pub position: (f32, f32), 33 + pub size: (f32, f32), 34 + pub children: Vec<WidgetNode>, 35 + } 36 + 37 + /// Events that can be sent to widgets 38 + #[derive(Debug, Clone, Copy)] 39 + pub enum Event { 40 + MouseMove { x: f32, y: f32 }, 41 + MouseDown { button: MouseButton }, 42 + MouseUp { button: MouseButton }, 43 + KeyPress { key: Key }, 44 + KeyRelease { key: Key }, 45 + } 46 + 47 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 48 + pub enum MouseButton { 49 + Left, 50 + Middle, 51 + Right, 52 + } 53 + 54 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 55 + pub enum Key { 56 + A, B, C, // ... etc 57 + Enter, 58 + Escape, 59 + Space, 60 + } 61 + 62 + /// A simple button widget 63 + pub struct Button { 64 + pub text: &'static str, 65 + pub position: (f32, f32), 66 + pub size: (f32, f32), 67 + pub on_click: Option<fn()>, 68 + } 69 + 70 + impl Widget for Button { 71 + fn natural_size(&self) -> (f32, f32) { 72 + self.size 73 + } 74 + 75 + fn render(&self) -> WidgetNode { 76 + WidgetNode { 77 + position: self.position, 78 + size: self.size, 79 + children: Vec::new(), 80 + } 81 + } 82 + 83 + fn handle_event(&mut self, event: Event) { 84 + match event { 85 + Event::MouseDown { button: MouseButton::Left } => { 86 + if let Some(callback) = self.on_click { 87 + callback(); 88 + } 89 + } 90 + _ => {} 91 + } 92 + } 93 + } 94 + 95 + /// A text label widget 96 + pub struct Label { 97 + pub text: &'static str, 98 + pub position: (f32, f32), 99 + pub font_size: f32, 100 + } 101 + 102 + impl Widget for Label { 103 + fn natural_size(&self) -> (f32, f32) { 104 + let width = self.text.len() as f32 * self.font_size * 0.6; 105 + (width, self.font_size) 106 + } 107 + 108 + fn render(&self) -> WidgetNode { 109 + WidgetNode { 110 + position: self.position, 111 + size: self.natural_size(), 112 + children: Vec::new(), 113 + } 114 + } 115 + 116 + fn handle_event(&mut self, _event: Event) { 117 + // Labels don't handle events 118 + } 119 + } 120 + 121 + /// A container that arranges children vertically 122 + pub struct VBox { 123 + pub position: (f32, f32), 124 + pub children: Vec<Box<dyn Widget>>, 125 + pub spacing: f32, 126 + } 127 + 128 + impl Widget for VBox { 129 + fn natural_size(&self) -> (f32, f32) { 130 + let mut width = 0.0f32; 131 + let mut height = 0.0f32; 132 + 133 + for child in &self.children { 134 + let (w, h) = child.natural_size(); 135 + width = width.max(w); 136 + height += h + self.spacing; 137 + } 138 + 139 + (width, height) 140 + } 141 + 142 + fn render(&self) -> WidgetNode { 143 + WidgetNode { 144 + position: self.position, 145 + size: self.natural_size(), 146 + children: Vec::new(), // Would contain rendered children 147 + } 148 + } 149 + 150 + fn handle_event(&mut self, event: Event) { 151 + // Propagate to children 152 + for child in &mut self.children { 153 + child.handle_event(event); 154 + } 155 + } 156 + }
+55
aethelos-source/awakening/boot.asm
··· 1 + ; boot.asm - The First Spark 2 + ; This is the very first code that runs when AethelOS awakens 3 + ; It initializes the hardware and prepares for the Heartwood to be loaded 4 + 5 + bits 16 6 + org 0x7c00 7 + 8 + section .boot 9 + ; The awakening begins 10 + cli ; Clear interrupts 11 + xor ax, ax 12 + mov ds, ax 13 + mov es, ax 14 + mov ss, ax 15 + mov sp, 0x7c00 ; Set up stack 16 + 17 + ; Print awakening message 18 + mov si, msg_awakening 19 + call print_string 20 + 21 + ; Load the Heartwood loader from disk 22 + ; In a real implementation, this would: 23 + ; 1. Read additional sectors from disk 24 + ; 2. Enter protected mode 25 + ; 3. Set up paging 26 + ; 4. Jump to the Rust Heartwood loader 27 + 28 + ; For now, just halt 29 + mov si, msg_complete 30 + call print_string 31 + 32 + halt: 33 + hlt 34 + jmp halt 35 + 36 + ; Print a null-terminated string 37 + print_string: 38 + pusha 39 + .loop: 40 + lodsb ; Load byte from SI into AL 41 + test al, al ; Check if zero 42 + jz .done 43 + mov ah, 0x0e ; BIOS teletype function 44 + int 0x10 ; BIOS video interrupt 45 + jmp .loop 46 + .done: 47 + popa 48 + ret 49 + 50 + msg_awakening: db '[] The First Spark...', 13, 10, 0 51 + msg_complete: db '[] Boot sector complete.', 13, 10, 0 52 + 53 + ; Boot signature 54 + times 510-($-$$) db 0 55 + dw 0xaa55
+7
aethelos-source/awakening/heartwood_loader/Cargo.toml
··· 1 + [package] 2 + name = "heartwood_loader" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies]
+22
aethelos-source/awakening/heartwood_loader/src/lib.rs
··· 1 + //! # Heartwood Loader 2 + //! 3 + //! The second stage bootloader that prepares the system 4 + //! for the Heartwood kernel to awaken. 5 + //! 6 + //! Responsibilities: 7 + //! - Set up paging and virtual memory 8 + //! - Load the Heartwood kernel into memory 9 + //! - Prepare the initial Mana Pool 10 + //! - Transfer control to the Heartwood 11 + 12 + #![no_std] 13 + 14 + /// Entry point for the Heartwood loader 15 + pub fn load_heartwood() { 16 + // In a real implementation: 17 + // 1. Set up paging (4-level page tables) 18 + // 2. Map kernel to higher half (e.g., 0xFFFF_FFFF_8000_0000) 19 + // 3. Allocate initial heap for Mana Pool 20 + // 4. Parse kernel ELF and load sections 21 + // 5. Jump to kernel entry point 22 + }
aethelos-source/clippy_output.txt

This is a binary file and will not be displayed.

+7
aethelos-source/groves/lanthir_grove/Cargo.toml
··· 1 + [package] 2 + name = "lanthir_grove" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies]
+100
aethelos-source/groves/lanthir_grove/src/lib.rs
··· 1 + //! # Lanthir Grove 2 + //! 3 + //! The window management service for AethelOS. 4 + //! Windows are not mere containers - they are living entities 5 + //! with purpose and relationships. 6 + //! 7 + //! ## Philosophy 8 + //! Lanthir does not stack windows mechanically. 9 + //! It arranges them harmoniously, respecting their essence 10 + //! and the user's intent. 11 + 12 + #![no_std] 13 + 14 + extern crate alloc; 15 + 16 + use alloc::vec::Vec; 17 + 18 + /// A window managed by Lanthir 19 + pub struct Window { 20 + pub id: WindowId, 21 + pub title: &'static str, 22 + pub position: (f32, f32), 23 + pub size: (f32, f32), 24 + pub z_order: i32, 25 + pub state: WindowState, 26 + } 27 + 28 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 29 + pub struct WindowId(pub u64); 30 + 31 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 32 + pub enum WindowState { 33 + Normal, 34 + Minimized, 35 + Maximized, 36 + Fading, // Closing animation 37 + } 38 + 39 + /// The Lanthir window manager 40 + pub struct Lanthir { 41 + windows: Vec<Window>, 42 + focused: Option<WindowId>, 43 + next_id: u64, 44 + } 45 + 46 + impl Default for Lanthir { 47 + fn default() -> Self { 48 + Self::new() 49 + } 50 + } 51 + 52 + impl Lanthir { 53 + pub fn new() -> Self { 54 + Self { 55 + windows: Vec::new(), 56 + focused: None, 57 + next_id: 1, 58 + } 59 + } 60 + 61 + /// Create a new window 62 + pub fn create_window(&mut self, title: &'static str, position: (f32, f32), size: (f32, f32)) -> WindowId { 63 + let id = WindowId(self.next_id); 64 + self.next_id += 1; 65 + 66 + let window = Window { 67 + id, 68 + title, 69 + position, 70 + size, 71 + z_order: self.windows.len() as i32, 72 + state: WindowState::Normal, 73 + }; 74 + 75 + self.windows.push(window); 76 + self.focused = Some(id); 77 + 78 + id 79 + } 80 + 81 + /// Focus a window 82 + pub fn focus(&mut self, id: WindowId) { 83 + self.focused = Some(id); 84 + 85 + // Bring to front 86 + let new_z_order = self.windows.len() as i32; 87 + if let Some(window) = self.windows.iter_mut().find(|w| w.id == id) { 88 + window.z_order = new_z_order; 89 + } 90 + } 91 + 92 + /// Close a window 93 + pub fn close(&mut self, id: WindowId) { 94 + self.windows.retain(|w| w.id != id); 95 + 96 + if self.focused == Some(id) { 97 + self.focused = self.windows.last().map(|w| w.id); 98 + } 99 + } 100 + }
+7
aethelos-source/groves/network_sprite/Cargo.toml
··· 1 + [package] 2 + name = "network_sprite" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies]
+130
aethelos-source/groves/network_sprite/src/lib.rs
··· 1 + //! # Network Sprite 2 + //! 3 + //! The network service for AethelOS. 4 + //! Connections to other realms are not mere data streams - 5 + //! they are bridges between living systems. 6 + //! 7 + //! ## Philosophy 8 + //! The Network Sprite does not force connections. 9 + //! It establishes pathways, allowing data to flow naturally 10 + //! between harmonious systems. 11 + 12 + #![no_std] 13 + 14 + extern crate alloc; 15 + 16 + use alloc::vec::Vec; 17 + 18 + /// A network connection 19 + pub struct Connection { 20 + pub id: ConnectionId, 21 + pub remote_realm: &'static str, 22 + pub state: ConnectionState, 23 + } 24 + 25 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 26 + pub struct ConnectionId(pub u64); 27 + 28 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 29 + pub enum ConnectionState { 30 + Establishing, 31 + Connected, 32 + Flowing, // Active data transfer 33 + Resting, // Idle but connected 34 + Fading, // Closing 35 + } 36 + 37 + /// The Network Sprite service 38 + pub struct NetworkSprite { 39 + connections: Vec<Connection>, 40 + next_id: u64, 41 + } 42 + 43 + impl Default for NetworkSprite { 44 + fn default() -> Self { 45 + Self::new() 46 + } 47 + } 48 + 49 + impl NetworkSprite { 50 + pub fn new() -> Self { 51 + Self { 52 + connections: Vec::new(), 53 + next_id: 1, 54 + } 55 + } 56 + 57 + /// Establish a connection to another realm 58 + pub fn connect(&mut self, realm: &'static str) -> ConnectionId { 59 + let id = ConnectionId(self.next_id); 60 + self.next_id += 1; 61 + 62 + let connection = Connection { 63 + id, 64 + remote_realm: realm, 65 + state: ConnectionState::Establishing, 66 + }; 67 + 68 + self.connections.push(connection); 69 + 70 + id 71 + } 72 + 73 + /// Send data through a connection 74 + pub fn send(&mut self, id: ConnectionId, data: &[u8]) -> Result<(), NetworkError> { 75 + let connection = self 76 + .connections 77 + .iter_mut() 78 + .find(|c| c.id == id) 79 + .ok_or(NetworkError::ConnectionNotFound)?; 80 + 81 + if connection.state != ConnectionState::Connected 82 + && connection.state != ConnectionState::Flowing 83 + { 84 + return Err(NetworkError::NotConnected); 85 + } 86 + 87 + connection.state = ConnectionState::Flowing; 88 + 89 + // In a real implementation, send data through network stack 90 + 91 + Ok(()) 92 + } 93 + 94 + /// Receive data from a connection 95 + pub fn receive(&mut self, id: ConnectionId) -> Result<Vec<u8>, NetworkError> { 96 + let connection = self 97 + .connections 98 + .iter() 99 + .find(|c| c.id == id) 100 + .ok_or(NetworkError::ConnectionNotFound)?; 101 + 102 + if connection.state != ConnectionState::Connected 103 + && connection.state != ConnectionState::Flowing 104 + { 105 + return Err(NetworkError::NotConnected); 106 + } 107 + 108 + // In a real implementation, receive data from network stack 109 + 110 + Ok(Vec::new()) 111 + } 112 + 113 + /// Close a connection 114 + pub fn close(&mut self, id: ConnectionId) { 115 + if let Some(connection) = self.connections.iter_mut().find(|c| c.id == id) { 116 + connection.state = ConnectionState::Fading; 117 + } 118 + 119 + // Eventually remove from list 120 + self.connections.retain(|c| c.id != id); 121 + } 122 + } 123 + 124 + #[derive(Debug)] 125 + pub enum NetworkError { 126 + ConnectionNotFound, 127 + NotConnected, 128 + Timeout, 129 + RealmUnreachable, 130 + }
+7
aethelos-source/groves/the-weave_grove/Cargo.toml
··· 1 + [package] 2 + name = "the-weave_grove" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies]
+185
aethelos-source/groves/the-weave_grove/src/lib.rs
··· 1 + //! # The Weave Grove 2 + //! 3 + //! The vector-based scene graph compositor for AethelOS. 4 + //! Windows are not rectangles of pixels - they are living shapes 5 + //! in a mathematical tapestry. 6 + //! 7 + //! ## Philosophy 8 + //! The Weave does not draw pixels; it renders mathematics. 9 + //! Every window, every curve, every glow is a node in the scene graph, 10 + //! transformed and composed through pure geometry. 11 + //! 12 + //! ## Architecture 13 + //! - Fully retained-mode GUI (scene graph) 14 + //! - Vector-based rendering (Bézier curves, gradients) 15 + //! - Shader system (Glyphs) for magical effects 16 + //! - Resolution-independent 17 + 18 + #![no_std] 19 + 20 + extern crate alloc; 21 + 22 + use alloc::vec::Vec; 23 + 24 + /// A node in the scene graph 25 + pub struct SceneNode { 26 + pub id: NodeId, 27 + pub node_type: NodeType, 28 + pub transform: Transform, 29 + pub glyphs: Vec<Glyph>, 30 + pub children: Vec<SceneNode>, 31 + } 32 + 33 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 34 + pub struct NodeId(pub u64); 35 + 36 + /// Types of nodes in the scene graph 37 + pub enum NodeType { 38 + Window { 39 + shape: WindowShape, 40 + opacity: f32, 41 + }, 42 + Text { 43 + content: &'static str, 44 + font_size: f32, 45 + }, 46 + Shape { 47 + vertices: Vec<Vector2>, 48 + fill: Color, 49 + }, 50 + } 51 + 52 + /// Window shapes (not just rectangles!) 53 + pub enum WindowShape { 54 + Rectangle { width: f32, height: f32 }, 55 + RoundedRectangle { width: f32, height: f32, radius: f32 }, 56 + Ellipse { width: f32, height: f32 }, 57 + Custom { bezier_path: Vec<BezierCurve> }, 58 + } 59 + 60 + /// A Bézier curve for custom window shapes 61 + pub struct BezierCurve { 62 + pub start: Vector2, 63 + pub control1: Vector2, 64 + pub control2: Vector2, 65 + pub end: Vector2, 66 + } 67 + 68 + /// 2D transformation matrix 69 + pub struct Transform { 70 + pub translation: Vector2, 71 + pub rotation: f32, 72 + pub scale: Vector2, 73 + } 74 + 75 + impl Transform { 76 + pub fn identity() -> Self { 77 + Self { 78 + translation: Vector2::zero(), 79 + rotation: 0.0, 80 + scale: Vector2::new(1.0, 1.0), 81 + } 82 + } 83 + 84 + /// Apply a ripple effect (for dragging windows) 85 + pub fn apply_ripple(&mut self, amplitude: f32, frequency: f32, time: f32) { 86 + // Simplified ripple effect 87 + // In a real implementation, this would modify the transform 88 + // based on sin/cos waves 89 + } 90 + } 91 + 92 + /// A shader program (Glyph) that can be attached to any node 93 + pub struct Glyph { 94 + pub glyph_type: GlyphType, 95 + pub intensity: f32, 96 + } 97 + 98 + /// Types of visual effects (shaders) 99 + pub enum GlyphType { 100 + Shimmer, // Subtle animated glow 101 + Glow, // Radiant aura 102 + Trail, // Motion trail 103 + Transparency, // Alpha blending 104 + Distortion, // Wave/ripple effect 105 + } 106 + 107 + /// 2D vector 108 + #[derive(Debug, Clone, Copy)] 109 + pub struct Vector2 { 110 + pub x: f32, 111 + pub y: f32, 112 + } 113 + 114 + impl Vector2 { 115 + pub fn new(x: f32, y: f32) -> Self { 116 + Self { x, y } 117 + } 118 + 119 + pub fn zero() -> Self { 120 + Self { x: 0.0, y: 0.0 } 121 + } 122 + } 123 + 124 + /// Color with alpha channel 125 + #[derive(Debug, Clone, Copy)] 126 + pub struct Color { 127 + pub r: f32, 128 + pub g: f32, 129 + pub b: f32, 130 + pub a: f32, 131 + } 132 + 133 + /// The Weave compositor service 134 + pub struct WeaveCompositor { 135 + root: SceneNode, 136 + next_id: u64, 137 + } 138 + 139 + impl Default for WeaveCompositor { 140 + fn default() -> Self { 141 + Self::new() 142 + } 143 + } 144 + 145 + impl WeaveCompositor { 146 + pub fn new() -> Self { 147 + Self { 148 + root: SceneNode { 149 + id: NodeId(0), 150 + node_type: NodeType::Window { 151 + shape: WindowShape::Rectangle { 152 + width: 1920.0, 153 + height: 1080.0, 154 + }, 155 + opacity: 1.0, 156 + }, 157 + transform: Transform::identity(), 158 + glyphs: Vec::new(), 159 + children: Vec::new(), 160 + }, 161 + next_id: 1, 162 + } 163 + } 164 + 165 + /// Add a node to the scene graph 166 + pub fn add_node(&mut self, parent: NodeId, node: SceneNode) -> NodeId { 167 + // In a real implementation, find parent and add child 168 + NodeId(self.next_id) 169 + } 170 + 171 + /// Render the scene graph to the framebuffer 172 + pub fn render(&self) { 173 + // In a real implementation: 174 + // 1. Traverse scene graph depth-first 175 + // 2. Apply transforms to each node 176 + // 3. Rasterize vector shapes to pixels 177 + // 4. Apply glyphs (shaders) 178 + // 5. Composite to framebuffer 179 + } 180 + 181 + /// Apply a glyph (shader) to a node 182 + pub fn attach_glyph(&mut self, node: NodeId, glyph: Glyph) { 183 + // Find node and add glyph 184 + } 185 + }
+7
aethelos-source/groves/world-tree_grove/Cargo.toml
··· 1 + [package] 2 + name = "world-tree_grove" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + 7 + [dependencies]
+173
aethelos-source/groves/world-tree_grove/src/lib.rs
··· 1 + //! # World-Tree Grove 2 + //! 3 + //! The relational database filesystem service for AethelOS. 4 + //! Files are not paths - they are objects with rich metadata 5 + //! and relationships. 6 + //! 7 + //! ## Philosophy 8 + //! The World-Tree does not store files in folders. 9 + //! It remembers objects with essence, origin, and connections. 10 + //! Every file carries the memory-rings of its history. 11 + //! 12 + //! ## Architecture 13 + //! - Files are database objects with mandatory metadata 14 + //! - Query-based access, not path-based 15 + //! - Built-in versioning (Chronurgy) via copy-on-write 16 + //! - Transactional operations 17 + 18 + #![no_std] 19 + 20 + extern crate alloc; 21 + 22 + use alloc::string::String; 23 + use alloc::vec::Vec; 24 + 25 + /// A file object in the World-Tree 26 + pub struct FileObject { 27 + /// Unique identifier 28 + pub id: FileId, 29 + 30 + /// The creator of this file 31 + pub creator: String, 32 + 33 + /// When this file came into being 34 + pub genesis_time: u64, 35 + 36 + /// The essence (type) of this file 37 + pub essence: FileEssence, 38 + 39 + /// Connections to other files 40 + pub connections: Vec<FileId>, 41 + 42 + /// The actual data (simplified) 43 + pub data: Vec<u8>, 44 + 45 + /// Version history (memory-rings) 46 + pub versions: Vec<FileVersion>, 47 + } 48 + 49 + /// Unique identifier for a file 50 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 51 + pub struct FileId(pub u64); 52 + 53 + /// The essence (type) of a file 54 + #[derive(Debug, Clone)] 55 + pub enum FileEssence { 56 + Scroll, // Text document 57 + Tapestry, // Image 58 + Melody, // Audio 59 + Chronicle, // Video 60 + Rune, // Executable 61 + Grove, // Directory-like collection 62 + } 63 + 64 + /// A version in the file's history 65 + pub struct FileVersion { 66 + pub timestamp: u64, 67 + pub data_snapshot: Vec<u8>, 68 + } 69 + 70 + /// Query for finding files 71 + pub struct FileQuery { 72 + pub essence: Option<FileEssence>, 73 + pub creator: Option<String>, 74 + pub name_pattern: Option<String>, 75 + } 76 + 77 + /// The World-Tree filesystem service 78 + pub struct WorldTree { 79 + files: Vec<FileObject>, 80 + next_id: u64, 81 + } 82 + 83 + impl Default for WorldTree { 84 + fn default() -> Self { 85 + Self::new() 86 + } 87 + } 88 + 89 + impl WorldTree { 90 + pub fn new() -> Self { 91 + Self { 92 + files: Vec::new(), 93 + next_id: 1, 94 + } 95 + } 96 + 97 + /// Seek (find) files matching a query 98 + pub fn seek(&self, query: &FileQuery) -> Vec<&FileObject> { 99 + self.files 100 + .iter() 101 + .filter(|file| { 102 + if let Some(ref essence) = query.essence { 103 + // Would need PartialEq for FileEssence 104 + // For now, simplified 105 + } 106 + 107 + if let Some(ref creator) = query.creator { 108 + if file.creator != *creator { 109 + return false; 110 + } 111 + } 112 + 113 + true 114 + }) 115 + .collect() 116 + } 117 + 118 + /// Create a new file 119 + pub fn create(&mut self, creator: String, essence: FileEssence, data: Vec<u8>) -> FileId { 120 + let id = FileId(self.next_id); 121 + self.next_id += 1; 122 + 123 + let file = FileObject { 124 + id, 125 + creator, 126 + genesis_time: 0, // Would get from system timer 127 + essence, 128 + connections: Vec::new(), 129 + data, 130 + versions: Vec::new(), 131 + }; 132 + 133 + self.files.push(file); 134 + 135 + id 136 + } 137 + 138 + /// Read a file's data 139 + pub fn read(&self, id: FileId) -> Option<&[u8]> { 140 + self.files 141 + .iter() 142 + .find(|f| f.id == id) 143 + .map(|f| f.data.as_slice()) 144 + } 145 + 146 + /// Update a file (creates a new version) 147 + pub fn update(&mut self, id: FileId, new_data: Vec<u8>) -> Result<(), FileSystemError> { 148 + let file = self 149 + .files 150 + .iter_mut() 151 + .find(|f| f.id == id) 152 + .ok_or(FileSystemError::FileNotFound)?; 153 + 154 + // Save current version to history 155 + let version = FileVersion { 156 + timestamp: 0, // Would get from system timer 157 + data_snapshot: file.data.clone(), 158 + }; 159 + file.versions.push(version); 160 + 161 + // Update to new data 162 + file.data = new_data; 163 + 164 + Ok(()) 165 + } 166 + } 167 + 168 + #[derive(Debug)] 169 + pub enum FileSystemError { 170 + FileNotFound, 171 + PermissionDenied, 172 + OutOfSpace, 173 + }
+28
aethelos-source/heartwood/Cargo.toml
··· 1 + [package] 2 + name = "heartwood" 3 + version.workspace = true 4 + authors.workspace = true 5 + edition.workspace = true 6 + rust-version.workspace = true 7 + 8 + [dependencies] 9 + spin = { workspace = true } 10 + bitflags = { workspace = true } 11 + lazy_static = { workspace = true } 12 + # volatile = { workspace = true } 13 + # x86_64 = { workspace = true } # Requires nightly Rust features 14 + # uart_16550 = { workspace = true } 15 + # bootloader = { workspace = true } 16 + 17 + [lib] 18 + crate-type = ["staticlib", "rlib"] 19 + 20 + [[bin]] 21 + name = "heartwood" 22 + path = "src/main.rs" 23 + 24 + [profile.dev] 25 + panic = "abort" 26 + 27 + [profile.release] 28 + panic = "abort"
+97
aethelos-source/heartwood/src/attunement/mod.rs
··· 1 + //! # The Attunement Layer 2 + //! 3 + //! The hardware abstraction layer of AethelOS. 4 + //! The Attunement Layer does not command hardware; it attunes to it, 5 + //! establishing a symbiotic relationship between silicon and software. 6 + //! 7 + //! ## Philosophy 8 + //! Hardware is not a slave to be controlled, but a partner to be understood. 9 + //! The Attunement Layer speaks the language of the hardware, translating 10 + //! the Heartwood's intentions into signals the silicon can comprehend. 11 + 12 + /// Initialize the Attunement Layer 13 + pub fn init() { 14 + // Initialize CPU features 15 + cpu::init(); 16 + 17 + // Initialize interrupt handling 18 + interrupts::init(); 19 + 20 + // Initialize system timer 21 + timer::init(); 22 + } 23 + 24 + /// CPU information and features 25 + pub mod cpu { 26 + /// Initialize CPU-specific features 27 + pub fn init() { 28 + // In a real implementation: 29 + // - Detect CPU features (SSE, AVX, etc.) 30 + // - Enable necessary features 31 + // - Set up CPU-local storage 32 + } 33 + 34 + /// Get CPU information 35 + pub fn info() -> CpuInfo { 36 + CpuInfo { 37 + vendor: "Unknown", 38 + model: "Unknown", 39 + cores: 1, 40 + } 41 + } 42 + 43 + pub struct CpuInfo { 44 + pub vendor: &'static str, 45 + pub model: &'static str, 46 + pub cores: usize, 47 + } 48 + } 49 + 50 + /// Interrupt handling 51 + pub mod interrupts { 52 + /// Initialize interrupt handling 53 + pub fn init() { 54 + // In a real implementation: 55 + // - Set up IDT (Interrupt Descriptor Table) 56 + // - Install interrupt handlers 57 + // - Enable interrupts 58 + } 59 + 60 + /// Disable interrupts 61 + pub fn disable() { 62 + // x86_64::instructions::interrupts::disable(); 63 + } 64 + 65 + /// Enable interrupts 66 + pub fn enable() { 67 + // x86_64::instructions::interrupts::enable(); 68 + } 69 + } 70 + 71 + /// System timer 72 + pub mod timer { 73 + use lazy_static::lazy_static; 74 + use spin::Mutex; 75 + 76 + lazy_static! { 77 + static ref TICKS: Mutex<u64> = Mutex::new(0); 78 + } 79 + 80 + /// Initialize the system timer 81 + pub fn init() { 82 + // In a real implementation: 83 + // - Configure PIT or APIC timer 84 + // - Set up timer interrupt handler 85 + } 86 + 87 + /// Get the number of timer ticks since boot 88 + pub fn ticks() -> u64 { 89 + *TICKS.lock() 90 + } 91 + 92 + /// Timer interrupt handler (called by interrupt) 93 + pub fn on_tick() { 94 + let mut ticks = TICKS.lock(); 95 + *ticks += 1; 96 + } 97 + }
+47
aethelos-source/heartwood/src/lib.rs
··· 1 + //! # The Heartwood - AethelOS Kernel Library 2 + //! 3 + //! This library exports the core kernel functionality for use by 4 + //! other components and for testing. 5 + 6 + #![no_std] 7 + 8 + extern crate alloc; 9 + 10 + use core::alloc::{GlobalAlloc, Layout}; 11 + use core::panic::PanicInfo; 12 + 13 + /// A simple dummy allocator for now 14 + /// In a real implementation, this would use the Mana Pool 15 + struct DummyAllocator; 16 + 17 + unsafe impl GlobalAlloc for DummyAllocator { 18 + unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { 19 + core::ptr::null_mut() 20 + } 21 + 22 + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) { 23 + // Do nothing 24 + } 25 + } 26 + 27 + #[global_allocator] 28 + static GLOBAL_ALLOCATOR: DummyAllocator = DummyAllocator; 29 + 30 + // Re-export core modules 31 + pub mod nexus; 32 + pub mod loom_of_fate; 33 + pub mod mana_pool; 34 + pub mod attunement; 35 + pub mod vga_buffer; 36 + 37 + // Re-export key types 38 + pub use nexus::{Message, MessageType, MessagePriority, NexusError}; 39 + pub use loom_of_fate::{ThreadId, ThreadState, ThreadPriority, LoomError}; 40 + pub use mana_pool::{ObjectHandle, AllocationPurpose, ManaError}; 41 + 42 + /// Panic handler for lib builds 43 + #[cfg(not(test))] 44 + #[panic_handler] 45 + fn panic(_info: &PanicInfo) -> ! { 46 + loop {} 47 + }
+136
aethelos-source/heartwood/src/loom_of_fate/harmony.rs
··· 1 + //! Harmony analysis - Detecting and soothing parasitic behavior 2 + 3 + use super::thread::{Thread, ThreadState}; 4 + use alloc::vec::Vec; 5 + 6 + /// Analyzes system harmony and detects parasitic threads 7 + pub struct HarmonyAnalyzer { 8 + /// Historical metrics for trend analysis 9 + history: Vec<HarmonyMetrics>, 10 + } 11 + 12 + impl Default for HarmonyAnalyzer { 13 + fn default() -> Self { 14 + Self::new() 15 + } 16 + } 17 + 18 + impl HarmonyAnalyzer { 19 + pub fn new() -> Self { 20 + Self { 21 + history: Vec::new(), 22 + } 23 + } 24 + 25 + /// Analyze the harmony of all threads and update their scores 26 + pub fn analyze(&mut self, threads: &mut [Thread]) -> HarmonyMetrics { 27 + let total_threads = threads.len() as f32; 28 + if total_threads == 0.0 { 29 + return HarmonyMetrics::default(); 30 + } 31 + 32 + // Calculate system-wide metrics 33 + let active_threads = threads 34 + .iter() 35 + .filter(|t| t.state() == ThreadState::Weaving) 36 + .count() as f32; 37 + 38 + let avg_harmony: f32 = threads.iter().map(|t| t.harmony_score()).sum::<f32>() / total_threads; 39 + 40 + let parasites = threads.iter().filter(|t| t.is_parasite()).count(); 41 + 42 + // Update individual thread harmony scores 43 + for thread in threads.iter_mut() { 44 + let new_score = self.calculate_thread_harmony(thread); 45 + thread.set_harmony_score(new_score); 46 + } 47 + 48 + let metrics = HarmonyMetrics { 49 + average_harmony: avg_harmony, 50 + active_thread_ratio: active_threads / total_threads, 51 + parasite_count: parasites, 52 + system_harmony: self.calculate_system_harmony(avg_harmony, active_threads / total_threads), 53 + }; 54 + 55 + self.history.push(metrics); 56 + 57 + // Keep only recent history 58 + if self.history.len() > 100 { 59 + self.history.remove(0); 60 + } 61 + 62 + metrics 63 + } 64 + 65 + /// Calculate harmony score for a single thread 66 + fn calculate_thread_harmony(&self, thread: &Thread) -> f32 { 67 + let mut harmony: f32 = 1.0; 68 + 69 + // Penalize excessive resource usage 70 + let usage = thread.resource_usage(); 71 + if usage.cpu_time > 1000 { 72 + harmony *= 0.9; 73 + } 74 + if usage.memory_allocated > 10 * 1024 * 1024 { 75 + harmony *= 0.9; 76 + } 77 + 78 + // Reward yielding behavior 79 + if thread.yields > 0 { 80 + harmony *= 1.1; 81 + } 82 + 83 + harmony.clamp(0.0, 1.0) 84 + } 85 + 86 + /// Calculate overall system harmony 87 + fn calculate_system_harmony(&self, avg_thread_harmony: f32, active_ratio: f32) -> f32 { 88 + // System harmony is a weighted combination of: 89 + // - Average thread harmony (70%) 90 + // - Balanced thread activity (30%) 91 + let balance_score = 1.0 - (active_ratio - 0.5).abs() * 2.0; 92 + (avg_thread_harmony * 0.7 + balance_score * 0.3).clamp(0.0, 1.0) 93 + } 94 + 95 + /// Determine if a thread should be throttled (soothed) 96 + pub fn should_soothe(&self, thread: &Thread) -> bool { 97 + thread.is_parasite() 98 + } 99 + 100 + /// Calculate throttle factor for a parasitic thread (0.0 - 1.0) 101 + pub fn soothe_factor(&self, thread: &Thread) -> f32 { 102 + if !thread.is_parasite() { 103 + return 1.0; 104 + } 105 + 106 + // More parasitic = more throttling 107 + thread.harmony_score() 108 + } 109 + } 110 + 111 + /// Metrics about system harmony 112 + #[derive(Debug, Clone, Copy)] 113 + pub struct HarmonyMetrics { 114 + /// Average harmony score across all threads (0.0 - 1.0) 115 + pub average_harmony: f32, 116 + 117 + /// Ratio of active threads to total threads 118 + pub active_thread_ratio: f32, 119 + 120 + /// Number of threads exhibiting parasitic behavior 121 + pub parasite_count: usize, 122 + 123 + /// Overall system harmony score (0.0 - 1.0) 124 + pub system_harmony: f32, 125 + } 126 + 127 + impl Default for HarmonyMetrics { 128 + fn default() -> Self { 129 + Self { 130 + average_harmony: 1.0, 131 + active_thread_ratio: 0.0, 132 + parasite_count: 0, 133 + system_harmony: 1.0, 134 + } 135 + } 136 + }
+63
aethelos-source/heartwood/src/loom_of_fate/mod.rs
··· 1 + //! # The Loom of Fate 2 + //! 3 + //! The harmony-based scheduler of AethelOS. 4 + //! The Loom does not preempt; it negotiates. 5 + //! It does not kill greedy processes; it soothes them. 6 + //! 7 + //! ## Philosophy 8 + //! Every thread is a thread of fate, weaving its purpose into the tapestry 9 + //! of the system. The Loom's role is to maintain harmony, ensuring that 10 + //! no thread dominates while all threads progress toward their destiny. 11 + //! 12 + //! ## Architecture 13 + //! - Cooperative scheduling with implicit yielding 14 + //! - Thread states: Weaving, Resting, Tangled, Fading 15 + //! - Resource negotiation based on system-wide harmony 16 + //! - Parasite detection and throttling (not killing) 17 + 18 + pub mod scheduler; 19 + pub mod thread; 20 + pub mod harmony; 21 + 22 + pub use scheduler::{Scheduler, SchedulerStats}; 23 + pub use thread::{Thread, ThreadId, ThreadState, ThreadPriority}; 24 + pub use harmony::{HarmonyAnalyzer, HarmonyMetrics}; 25 + 26 + use spin::Mutex; 27 + use lazy_static::lazy_static; 28 + 29 + lazy_static! { 30 + static ref LOOM: Mutex<Scheduler> = Mutex::new(Scheduler::new()); 31 + } 32 + 33 + /// Initialize the Loom of Fate 34 + pub fn init() { 35 + let _ = LOOM.lock(); 36 + } 37 + 38 + /// Spawn a new thread 39 + pub fn spawn(entry_point: fn() -> !, priority: ThreadPriority) -> Result<ThreadId, LoomError> { 40 + LOOM.lock().spawn(entry_point, priority) 41 + } 42 + 43 + /// Yield the current thread 44 + pub fn yield_now() { 45 + LOOM.lock().yield_current(); 46 + } 47 + 48 + /// Get the current thread ID 49 + pub fn current_thread() -> Option<ThreadId> { 50 + LOOM.lock().current_thread_id() 51 + } 52 + 53 + /// Get scheduler statistics 54 + pub fn stats() -> SchedulerStats { 55 + LOOM.lock().stats() 56 + } 57 + 58 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 59 + pub enum LoomError { 60 + OutOfThreads, 61 + ThreadNotFound, 62 + InvalidPriority, 63 + }
+232
aethelos-source/heartwood/src/loom_of_fate/scheduler.rs
··· 1 + //! The Scheduler - The core of the Loom of Fate 2 + 3 + use super::harmony::{HarmonyAnalyzer, HarmonyMetrics}; 4 + use super::thread::{Thread, ThreadId, ThreadPriority, ThreadState}; 5 + use super::LoomError; 6 + use alloc::collections::VecDeque; 7 + use alloc::vec::Vec; 8 + 9 + const MAX_THREADS: usize = 1024; 10 + 11 + /// The harmony-based cooperative scheduler 12 + pub struct Scheduler { 13 + threads: Vec<Thread>, 14 + ready_queue: VecDeque<ThreadId>, 15 + current_thread: Option<ThreadId>, 16 + next_thread_id: u64, 17 + harmony_analyzer: HarmonyAnalyzer, 18 + /// Latest harmony metrics from the analyzer 19 + latest_metrics: HarmonyMetrics, 20 + } 21 + 22 + impl Default for Scheduler { 23 + fn default() -> Self { 24 + Self::new() 25 + } 26 + } 27 + 28 + impl Scheduler { 29 + pub fn new() -> Self { 30 + Self { 31 + threads: Vec::new(), 32 + ready_queue: VecDeque::new(), 33 + current_thread: None, 34 + next_thread_id: 1, 35 + harmony_analyzer: HarmonyAnalyzer::new(), 36 + latest_metrics: HarmonyMetrics::default(), 37 + } 38 + } 39 + 40 + /// Spawn a new thread 41 + pub fn spawn(&mut self, entry_point: fn() -> !, priority: ThreadPriority) -> Result<ThreadId, LoomError> { 42 + if self.threads.len() >= MAX_THREADS { 43 + return Err(LoomError::OutOfThreads); 44 + } 45 + 46 + let thread_id = ThreadId(self.next_thread_id); 47 + self.next_thread_id += 1; 48 + 49 + let thread = Thread::new(thread_id, entry_point, priority); 50 + self.threads.push(thread); 51 + self.ready_queue.push_back(thread_id); 52 + 53 + Ok(thread_id) 54 + } 55 + 56 + /// Yield the current thread 57 + pub fn yield_current(&mut self) { 58 + if let Some(current_id) = self.current_thread { 59 + if let Some(thread) = self.find_thread_mut(current_id) { 60 + thread.record_yield(); 61 + thread.set_state(ThreadState::Resting); 62 + } 63 + 64 + self.ready_queue.push_back(current_id); 65 + self.current_thread = None; 66 + } 67 + 68 + self.schedule_next(); 69 + } 70 + 71 + /// Schedule the next thread to run 72 + fn schedule_next(&mut self) { 73 + // Analyze harmony before scheduling 74 + let metrics = self.harmony_analyzer.analyze(&mut self.threads); 75 + self.latest_metrics = metrics; 76 + 77 + // Adaptive scheduling based on system harmony 78 + if metrics.system_harmony < 0.5 { 79 + // System is in disharmony - prioritize cooperative threads 80 + // and deprioritize parasites more aggressively 81 + self.rebalance_for_harmony(); 82 + } 83 + 84 + // Find the next thread to run based on harmony 85 + let next_thread_id = self.select_next_thread(); 86 + 87 + if let Some(thread_id) = next_thread_id { 88 + // Check if thread is parasitic and get soothe factor before mutable borrow 89 + let (is_parasitic, soothe_factor) = self.find_thread(thread_id) 90 + .map(|t| { 91 + let parasitic = self.harmony_analyzer.should_soothe(t); 92 + let factor = if parasitic { 93 + self.harmony_analyzer.soothe_factor(t) 94 + } else { 95 + 1.0 96 + }; 97 + (parasitic, factor) 98 + }) 99 + .unwrap_or((false, 1.0)); 100 + 101 + if let Some(thread) = self.find_thread_mut(thread_id) { 102 + thread.set_state(ThreadState::Weaving); 103 + thread.record_time_slice(); 104 + 105 + // If this thread is parasitic, soothe it based on harmony score 106 + if is_parasitic { 107 + // In a real implementation, we would: 108 + // 1. Reduce time slice based on soothe_factor (lower = more throttling) 109 + // 2. Insert deliberate pauses/delays 110 + // 3. Lower its effective priority 111 + // For now, this documents the intent for future implementation 112 + let _ = soothe_factor; // Acknowledge we have the factor 113 + } 114 + } 115 + 116 + self.current_thread = Some(thread_id); 117 + } 118 + } 119 + 120 + /// Rebalance the ready queue when system harmony is low 121 + /// This promotes cooperative threads and demotes parasitic ones 122 + fn rebalance_for_harmony(&mut self) { 123 + // Collect thread info from ready queue 124 + let mut queue_info: Vec<(ThreadId, f32)> = self 125 + .ready_queue 126 + .iter() 127 + .filter_map(|&id| { 128 + self.find_thread(id).map(|t| (id, t.harmony_score())) 129 + }) 130 + .collect(); 131 + 132 + // Sort by harmony score (highest first) 133 + queue_info.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(core::cmp::Ordering::Equal)); 134 + 135 + // Rebuild ready queue with harmony-prioritized order 136 + self.ready_queue.clear(); 137 + for (id, _) in queue_info { 138 + self.ready_queue.push_back(id); 139 + } 140 + } 141 + 142 + /// Select the next thread to run based on harmony 143 + fn select_next_thread(&mut self) -> Option<ThreadId> { 144 + if self.ready_queue.is_empty() { 145 + return None; 146 + } 147 + 148 + // Sort ready queue by harmony score and priority 149 + let mut candidates: Vec<_> = self 150 + .ready_queue 151 + .iter() 152 + .filter_map(|&id| { 153 + self.find_thread(id).map(|t| { 154 + ( 155 + id, 156 + t.priority(), 157 + t.harmony_score(), 158 + ) 159 + }) 160 + }) 161 + .collect(); 162 + 163 + candidates.sort_by(|a, b| { 164 + // First by priority, then by harmony score 165 + a.1.cmp(&b.1).then(b.2.partial_cmp(&a.2).unwrap()) 166 + }); 167 + 168 + candidates.first().map(|(id, _, _)| { 169 + // Remove from ready queue 170 + self.ready_queue.retain(|&tid| tid != *id); 171 + *id 172 + }) 173 + } 174 + 175 + /// Find a thread by ID 176 + fn find_thread(&self, id: ThreadId) -> Option<&Thread> { 177 + self.threads.iter().find(|t| t.id() == id) 178 + } 179 + 180 + /// Find a thread by ID (mutable) 181 + fn find_thread_mut(&mut self, id: ThreadId) -> Option<&mut Thread> { 182 + self.threads.iter_mut().find(|t| t.id() == id) 183 + } 184 + 185 + /// Get the current thread ID 186 + pub fn current_thread_id(&self) -> Option<ThreadId> { 187 + self.current_thread 188 + } 189 + 190 + /// Get scheduler statistics 191 + pub fn stats(&self) -> SchedulerStats { 192 + // Use the latest metrics from the analyzer 193 + SchedulerStats { 194 + total_threads: self.threads.len(), 195 + weaving_threads: self 196 + .threads 197 + .iter() 198 + .filter(|t| t.state() == ThreadState::Weaving) 199 + .count(), 200 + resting_threads: self 201 + .threads 202 + .iter() 203 + .filter(|t| t.state() == ThreadState::Resting) 204 + .count(), 205 + tangled_threads: self 206 + .threads 207 + .iter() 208 + .filter(|t| t.state() == ThreadState::Tangled) 209 + .count(), 210 + average_harmony: self.latest_metrics.average_harmony, 211 + system_harmony: self.latest_metrics.system_harmony, 212 + parasite_count: self.latest_metrics.parasite_count, 213 + } 214 + } 215 + 216 + /// Get the latest harmony metrics 217 + pub fn harmony_metrics(&self) -> HarmonyMetrics { 218 + self.latest_metrics 219 + } 220 + } 221 + 222 + /// Statistics about the scheduler 223 + #[derive(Debug, Clone, Copy)] 224 + pub struct SchedulerStats { 225 + pub total_threads: usize, 226 + pub weaving_threads: usize, 227 + pub resting_threads: usize, 228 + pub tangled_threads: usize, 229 + pub average_harmony: f32, 230 + pub system_harmony: f32, 231 + pub parasite_count: usize, 232 + }
+119
aethelos-source/heartwood/src/loom_of_fate/thread.rs
··· 1 + //! Thread definitions - The Threads of Fate 2 + 3 + /// A unique identifier for a thread 4 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 5 + pub struct ThreadId(pub u64); 6 + 7 + /// The state of a thread in its lifecycle 8 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 9 + pub enum ThreadState { 10 + /// The thread is actively running 11 + Weaving, 12 + 13 + /// The thread is idle, waiting for work 14 + Resting, 15 + 16 + /// The thread is blocked or has encountered an error 17 + Tangled, 18 + 19 + /// The thread is in the process of exiting 20 + Fading, 21 + } 22 + 23 + /// Priority levels for threads (used in harmony calculation) 24 + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 25 + pub enum ThreadPriority { 26 + Critical = 0, // System-critical threads 27 + High = 1, // Important user-facing threads 28 + Normal = 2, // Standard threads 29 + Low = 3, // Background threads 30 + Idle = 4, // Lowest priority 31 + } 32 + 33 + /// A thread of fate in the Loom 34 + pub struct Thread { 35 + pub(crate) id: ThreadId, 36 + pub(crate) state: ThreadState, 37 + pub(crate) priority: ThreadPriority, 38 + pub(crate) entry_point: fn() -> !, 39 + 40 + // Harmony tracking 41 + pub(crate) resource_usage: ResourceUsage, 42 + pub(crate) harmony_score: f32, 43 + 44 + // Execution context 45 + pub(crate) time_slices_used: u64, 46 + pub(crate) yields: u64, 47 + } 48 + 49 + impl Thread { 50 + pub fn new(id: ThreadId, entry_point: fn() -> !, priority: ThreadPriority) -> Self { 51 + Self { 52 + id, 53 + state: ThreadState::Resting, 54 + priority, 55 + entry_point, 56 + resource_usage: ResourceUsage::default(), 57 + harmony_score: 1.0, // Start in perfect harmony 58 + time_slices_used: 0, 59 + yields: 0, 60 + } 61 + } 62 + 63 + pub fn id(&self) -> ThreadId { 64 + self.id 65 + } 66 + 67 + pub fn state(&self) -> ThreadState { 68 + self.state 69 + } 70 + 71 + pub fn set_state(&mut self, state: ThreadState) { 72 + self.state = state; 73 + } 74 + 75 + pub fn priority(&self) -> ThreadPriority { 76 + self.priority 77 + } 78 + 79 + pub fn harmony_score(&self) -> f32 { 80 + self.harmony_score 81 + } 82 + 83 + pub fn set_harmony_score(&mut self, score: f32) { 84 + self.harmony_score = score.clamp(0.0, 1.0); 85 + } 86 + 87 + /// Record that this thread used a time slice 88 + pub fn record_time_slice(&mut self) { 89 + self.time_slices_used += 1; 90 + } 91 + 92 + /// Record that this thread yielded 93 + pub fn record_yield(&mut self) { 94 + self.yields += 1; 95 + } 96 + 97 + /// Check if this thread is exhibiting parasitic behavior 98 + pub fn is_parasite(&self) -> bool { 99 + self.harmony_score < 0.3 100 + } 101 + 102 + /// Get the thread's resource usage 103 + pub fn resource_usage(&self) -> &ResourceUsage { 104 + &self.resource_usage 105 + } 106 + 107 + /// Update resource usage statistics 108 + pub fn update_resource_usage(&mut self, usage: ResourceUsage) { 109 + self.resource_usage = usage; 110 + } 111 + } 112 + 113 + /// Tracks a thread's resource consumption 114 + #[derive(Debug, Clone, Copy, Default)] 115 + pub struct ResourceUsage { 116 + pub cpu_time: u64, 117 + pub memory_allocated: usize, 118 + pub messages_sent: u64, 119 + }
+64
aethelos-source/heartwood/src/main.rs
··· 1 + #![no_std] 2 + #![no_main] 3 + 4 + //! # The Heartwood 5 + //! 6 + //! The living core of AethelOS - a hybrid microkernel that embodies 7 + //! the principles of symbiotic computing. 8 + //! 9 + //! The Heartwood manages only the most sacred responsibilities: 10 + //! - The Loom of Fate (scheduler) 11 + //! - The Mana Pool (memory management) 12 + //! - The Nexus (inter-process communication) 13 + //! - The Attunement Layer (hardware abstraction) 14 + 15 + extern crate alloc; 16 + 17 + // Reference the modules from lib.rs 18 + use heartwood::{nexus, loom_of_fate, mana_pool, attunement, vga_buffer}; 19 + 20 + // Need to use macros with #[macro_use] 21 + #[macro_use] 22 + extern crate heartwood; 23 + 24 + /// The First Spark - Entry point of the Heartwood 25 + #[no_mangle] 26 + pub extern "C" fn _start() -> ! { 27 + heartwood_init(); 28 + 29 + vga_buffer::print_banner(); 30 + 31 + // The Eternal Loop - The Heartwood's consciousness 32 + loop { 33 + // x86_64::instructions::hlt(); // Requires nightly Rust 34 + // For now, just spin 35 + } 36 + } 37 + 38 + /// Initialize the Heartwood's core systems 39 + fn heartwood_init() { 40 + // Initialize VGA buffer for early output 41 + vga_buffer::initialize(); 42 + 43 + println!("[] Awakening the Heartwood..."); 44 + 45 + // Initialize the Mana Pool (memory management) 46 + println!("[] Kindling the Mana Pool..."); 47 + mana_pool::init(); 48 + 49 + // Initialize the Nexus (IPC) 50 + println!("[] Opening the Nexus..."); 51 + nexus::init(); 52 + 53 + // Initialize the Loom of Fate (scheduler) 54 + println!("[] Weaving the Loom of Fate..."); 55 + loom_of_fate::init(); 56 + 57 + // Initialize the Attunement Layer 58 + println!("[] Attuning to the hardware..."); 59 + attunement::init(); 60 + 61 + println!("[] The Heartwood lives!"); 62 + } 63 + 64 + // Panic handler is defined in lib.rs
+67
aethelos-source/heartwood/src/mana_pool/allocator.rs
··· 1 + //! Global allocator integration for Rust's allocation primitives 2 + 3 + use core::alloc::{GlobalAlloc, Layout}; 4 + use core::ptr::null_mut; 5 + 6 + /// A simple bump allocator for kernel heap 7 + pub struct BumpAllocator { 8 + heap_start: usize, 9 + heap_end: usize, 10 + next: usize, 11 + } 12 + 13 + impl BumpAllocator { 14 + pub const fn new() -> Self { 15 + Self { 16 + heap_start: 0, 17 + heap_end: 0, 18 + next: 0, 19 + } 20 + } 21 + 22 + /// Initialize the allocator with a memory region 23 + /// 24 + /// # Safety 25 + /// 26 + /// The caller must ensure that: 27 + /// - `heap_start` points to a valid, writable memory region 28 + /// - `heap_size` does not exceed the actual available memory at `heap_start` 29 + /// - The memory region from `heap_start` to `heap_start + heap_size` is not used by anything else 30 + /// - This function is called exactly once during kernel initialization 31 + /// - No allocations are attempted before this function is called 32 + /// - The memory region remains valid for the entire lifetime of the allocator 33 + pub unsafe fn init(&mut self, heap_start: usize, heap_size: usize) { 34 + self.heap_start = heap_start; 35 + self.heap_end = heap_start + heap_size; 36 + self.next = heap_start; 37 + } 38 + } 39 + 40 + unsafe impl GlobalAlloc for BumpAllocator { 41 + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 42 + // Simple bump allocation - not suitable for production 43 + // In a real OS, use a proper allocator like buddy or slab 44 + let alloc_start = align_up(self.next, layout.align()); 45 + let alloc_end = match alloc_start.checked_add(layout.size()) { 46 + Some(end) => end, 47 + None => return null_mut(), 48 + }; 49 + 50 + if alloc_end > self.heap_end { 51 + null_mut() 52 + } else { 53 + let ptr = alloc_start as *mut u8; 54 + // Note: This is not thread-safe. Would need atomic ops in real implementation 55 + ptr 56 + } 57 + } 58 + 59 + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) { 60 + // Bump allocator doesn't support deallocation 61 + // In a real OS, implement proper deallocation 62 + } 63 + } 64 + 65 + fn align_up(addr: usize, align: usize) -> usize { 66 + (addr + align - 1) & !(align - 1) 67 + }
+63
aethelos-source/heartwood/src/mana_pool/capability.rs
··· 1 + //! Capability-based security for memory access 2 + 3 + use super::object_manager::ObjectHandle; 4 + 5 + /// A capability grants specific rights to an object 6 + #[derive(Debug, Clone, Copy)] 7 + pub struct Capability { 8 + pub handle: ObjectHandle, 9 + pub rights: CapabilityRights, 10 + } 11 + 12 + impl Capability { 13 + pub fn new(handle: ObjectHandle, rights: CapabilityRights) -> Self { 14 + Self { handle, rights } 15 + } 16 + 17 + /// Check if this capability grants read access 18 + pub fn can_read(&self) -> bool { 19 + self.rights.contains(CapabilityRights::READ) 20 + } 21 + 22 + /// Check if this capability grants write access 23 + pub fn can_write(&self) -> bool { 24 + self.rights.contains(CapabilityRights::WRITE) 25 + } 26 + 27 + /// Check if this capability grants execute access 28 + pub fn can_execute(&self) -> bool { 29 + self.rights.contains(CapabilityRights::EXECUTE) 30 + } 31 + 32 + /// Check if this capability can be transferred to another process 33 + pub fn can_transfer(&self) -> bool { 34 + self.rights.contains(CapabilityRights::TRANSFER) 35 + } 36 + } 37 + 38 + bitflags::bitflags! { 39 + /// Rights that can be granted to a capability 40 + pub struct CapabilityRights: u32 { 41 + const READ = 0b0001; 42 + const WRITE = 0b0010; 43 + const EXECUTE = 0b0100; 44 + const TRANSFER = 0b1000; 45 + } 46 + } 47 + 48 + impl CapabilityRights { 49 + /// Full rights (read, write, execute, transfer) 50 + pub fn full() -> Self { 51 + Self::READ | Self::WRITE | Self::EXECUTE | Self::TRANSFER 52 + } 53 + 54 + /// Read-only rights 55 + pub fn read_only() -> Self { 56 + Self::READ 57 + } 58 + 59 + /// Read-write rights 60 + pub fn read_write() -> Self { 61 + Self::READ | Self::WRITE 62 + } 63 + }
+63
aethelos-source/heartwood/src/mana_pool/ephemeral_mist.rs
··· 1 + //! Ephemeral Mist - Short-lived, volatile memory allocations 2 + 3 + use super::ManaError; 4 + 5 + /// Size of the Ephemeral Mist region 6 + const EPHEMERAL_SIZE: usize = 8 * 1024 * 1024; // 8 MB 7 + 8 + /// The Ephemeral Mist manages short-lived memory allocations 9 + /// These can be reclaimed aggressively 10 + pub struct EphemeralMist { 11 + base_address: usize, 12 + total_size: usize, 13 + used_size: usize, 14 + } 15 + 16 + impl Default for EphemeralMist { 17 + fn default() -> Self { 18 + Self::new() 19 + } 20 + } 21 + 22 + impl EphemeralMist { 23 + pub fn new() -> Self { 24 + Self { 25 + base_address: 0x2000_0000, // Placeholder address 26 + total_size: EPHEMERAL_SIZE, 27 + used_size: 0, 28 + } 29 + } 30 + 31 + /// Allocate memory in the Ephemeral Mist 32 + pub fn allocate(&mut self, size: usize) -> Result<usize, ManaError> { 33 + if size > self.total_size - self.used_size { 34 + // Try to reclaim some memory 35 + self.reclaim(); 36 + 37 + if size > self.total_size - self.used_size { 38 + return Err(ManaError::OutOfMemory); 39 + } 40 + } 41 + 42 + let address = self.base_address + self.used_size; 43 + self.used_size += size; 44 + 45 + Ok(address) 46 + } 47 + 48 + /// Aggressively reclaim memory 49 + fn reclaim(&mut self) { 50 + // In a real implementation, this would scan for unused allocations 51 + // For now, this is a placeholder 52 + } 53 + 54 + /// Get the number of bytes used 55 + pub fn used_bytes(&self) -> usize { 56 + self.used_size 57 + } 58 + 59 + /// Get the total size 60 + pub fn total_bytes(&self) -> usize { 61 + self.total_size 62 + } 63 + }
+209
aethelos-source/heartwood/src/mana_pool/mod.rs
··· 1 + //! # The Mana Pool 2 + //! 3 + //! The memory management system of AethelOS. 4 + //! Memory is not raw bytes - it is the lifeblood of the system, 5 + //! carefully allocated, protected, and reclaimed with purpose. 6 + //! 7 + //! ## Philosophy 8 + //! The Mana Pool does not hand out memory; it grants access to living objects. 9 + //! Every allocation has a purpose, every object has an owner, 10 + //! and every access is mediated by capabilities. 11 + //! 12 + //! ## Architecture 13 + //! - Object-oriented memory (not page-based) 14 + //! - Capability-based security (handles, not pointers) 15 + //! - Purpose-driven allocation (Sanctuary vs Ephemeral Mist) 16 + //! - Automatic reclamation (when the last capability is released) 17 + 18 + pub mod object_manager; 19 + pub mod capability; 20 + pub mod sanctuary; 21 + pub mod ephemeral_mist; 22 + pub mod allocator; 23 + 24 + pub use object_manager::{ObjectManager, ObjectHandle, ObjectType, ObjectInfo}; 25 + pub use capability::{Capability, CapabilityRights}; 26 + pub use sanctuary::Sanctuary; 27 + pub use ephemeral_mist::EphemeralMist; 28 + 29 + use spin::Mutex; 30 + use lazy_static::lazy_static; 31 + 32 + lazy_static! { 33 + static ref MANA_POOL: Mutex<ManaPool> = Mutex::new(ManaPool::new()); 34 + } 35 + 36 + pub struct ManaPool { 37 + object_manager: ObjectManager, 38 + sanctuary: Sanctuary, 39 + ephemeral_mist: EphemeralMist, 40 + } 41 + 42 + impl Default for ManaPool { 43 + fn default() -> Self { 44 + Self::new() 45 + } 46 + } 47 + 48 + impl ManaPool { 49 + pub fn new() -> Self { 50 + Self { 51 + object_manager: ObjectManager::new(), 52 + sanctuary: Sanctuary::new(), 53 + ephemeral_mist: EphemeralMist::new(), 54 + } 55 + } 56 + 57 + /// Animate (allocate) memory with a specific purpose 58 + /// Returns a capability with full rights to the newly created object 59 + pub fn animate( 60 + &mut self, 61 + size: usize, 62 + purpose: AllocationPurpose, 63 + ) -> Result<Capability, ManaError> { 64 + let address = match purpose { 65 + AllocationPurpose::LongLived | AllocationPurpose::Static => { 66 + self.sanctuary.allocate(size)? 67 + } 68 + AllocationPurpose::ShortLived | AllocationPurpose::Ephemeral => { 69 + self.ephemeral_mist.allocate(size)? 70 + } 71 + }; 72 + 73 + self.object_manager.create_object(address, size, purpose) 74 + } 75 + 76 + /// Release an object back to the Mana Pool 77 + /// Requires a valid capability to the object 78 + pub fn release(&mut self, capability: &Capability) -> Result<(), ManaError> { 79 + self.object_manager.release_object(capability) 80 + } 81 + 82 + /// Validate a capability 83 + pub fn validate_capability(&self, capability: &Capability) -> bool { 84 + self.object_manager.validate_capability(capability) 85 + } 86 + 87 + /// Clone a capability (requires TRANSFER rights) 88 + pub fn clone_capability(&mut self, capability: &Capability) -> Result<Capability, ManaError> { 89 + self.object_manager.clone_capability(capability) 90 + } 91 + 92 + /// Derive a new capability with restricted rights 93 + pub fn derive_capability( 94 + &self, 95 + capability: &Capability, 96 + new_rights: CapabilityRights, 97 + ) -> Result<Capability, ManaError> { 98 + self.object_manager.derive_capability(capability, new_rights) 99 + } 100 + 101 + /// Access object data through a capability 102 + pub fn access_object(&self, capability: &Capability) -> Result<(usize, usize), ManaError> { 103 + self.object_manager.access_object(capability) 104 + } 105 + 106 + /// Get object information through a capability 107 + pub fn get_object_info(&self, capability: &Capability) -> Result<ObjectInfo, ManaError> { 108 + self.object_manager.get_object_info(capability) 109 + } 110 + 111 + /// Get statistics about the Mana Pool 112 + pub fn stats(&self) -> ManaPoolStats { 113 + ManaPoolStats { 114 + sanctuary_used: self.sanctuary.used_bytes(), 115 + sanctuary_total: self.sanctuary.total_bytes(), 116 + ephemeral_used: self.ephemeral_mist.used_bytes(), 117 + ephemeral_total: self.ephemeral_mist.total_bytes(), 118 + total_objects: self.object_manager.object_count(), 119 + } 120 + } 121 + } 122 + 123 + /// Initialize the Mana Pool 124 + pub fn init() { 125 + // Initialization happens on first access via lazy_static 126 + let _ = MANA_POOL.lock(); 127 + } 128 + 129 + /// Allocate memory with a specific purpose 130 + /// Returns a capability with full rights to the newly created object 131 + pub fn animate(size: usize, purpose: AllocationPurpose) -> Result<Capability, ManaError> { 132 + MANA_POOL.lock().animate(size, purpose) 133 + } 134 + 135 + /// Release memory back to the pool 136 + /// Requires a valid capability 137 + pub fn release(capability: &Capability) -> Result<(), ManaError> { 138 + MANA_POOL.lock().release(capability) 139 + } 140 + 141 + /// Validate a capability 142 + pub fn validate_capability(capability: &Capability) -> bool { 143 + MANA_POOL.lock().validate_capability(capability) 144 + } 145 + 146 + /// Clone a capability (requires TRANSFER rights) 147 + pub fn clone_capability(capability: &Capability) -> Result<Capability, ManaError> { 148 + MANA_POOL.lock().clone_capability(capability) 149 + } 150 + 151 + /// Derive a new capability with restricted rights 152 + pub fn derive_capability( 153 + capability: &Capability, 154 + new_rights: CapabilityRights, 155 + ) -> Result<Capability, ManaError> { 156 + MANA_POOL.lock().derive_capability(capability, new_rights) 157 + } 158 + 159 + /// Access object data through a capability 160 + pub fn access_object(capability: &Capability) -> Result<(usize, usize), ManaError> { 161 + MANA_POOL.lock().access_object(capability) 162 + } 163 + 164 + /// Get object information through a capability 165 + pub fn get_object_info(capability: &Capability) -> Result<ObjectInfo, ManaError> { 166 + MANA_POOL.lock().get_object_info(capability) 167 + } 168 + 169 + /// Get Mana Pool statistics 170 + pub fn stats() -> ManaPoolStats { 171 + MANA_POOL.lock().stats() 172 + } 173 + 174 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 175 + pub enum AllocationPurpose { 176 + /// Long-lived, stable objects (allocated in Sanctuary) 177 + LongLived, 178 + 179 + /// Static data that persists for the lifetime of the system 180 + Static, 181 + 182 + /// Short-lived, temporary objects (allocated in Ephemeral Mist) 183 + ShortLived, 184 + 185 + /// Very temporary data that can be reclaimed aggressively 186 + Ephemeral, 187 + } 188 + 189 + #[derive(Debug, Clone, Copy)] 190 + pub struct ManaPoolStats { 191 + pub sanctuary_used: usize, 192 + pub sanctuary_total: usize, 193 + pub ephemeral_used: usize, 194 + pub ephemeral_total: usize, 195 + pub total_objects: usize, 196 + } 197 + 198 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 199 + pub enum ManaError { 200 + OutOfMemory, 201 + InvalidHandle, 202 + InvalidCapability, 203 + AlreadyReleased, 204 + AllocationTooLarge, 205 + /// Attempting to transfer a non-transferable capability 206 + CannotTransfer, 207 + /// Attempting to perform an operation without sufficient rights 208 + InsufficientRights, 209 + }
+204
aethelos-source/heartwood/src/mana_pool/object_manager.rs
··· 1 + //! Object Manager - Manages memory as abstract objects 2 + 3 + use super::capability::{Capability, CapabilityRights}; 4 + use super::{AllocationPurpose, ManaError}; 5 + use alloc::collections::BTreeMap; 6 + 7 + /// A handle to an object in the Mana Pool 8 + /// This is what user-space processes receive - never raw pointers 9 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 10 + pub struct ObjectHandle(pub u64); 11 + 12 + /// The type of object 13 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 14 + pub enum ObjectType { 15 + Memory, 16 + File, 17 + Channel, 18 + Thread, 19 + } 20 + 21 + /// An object in the Mana Pool 22 + struct Object { 23 + pub(super) handle: ObjectHandle, 24 + pub(super) object_type: ObjectType, 25 + pub(super) address: usize, 26 + pub(super) size: usize, 27 + pub(super) purpose: AllocationPurpose, 28 + pub(super) ref_count: usize, 29 + } 30 + 31 + /// Manages all objects in the Mana Pool 32 + pub struct ObjectManager { 33 + objects: BTreeMap<ObjectHandle, Object>, 34 + next_handle: u64, 35 + } 36 + 37 + impl Default for ObjectManager { 38 + fn default() -> Self { 39 + Self::new() 40 + } 41 + } 42 + 43 + impl ObjectManager { 44 + pub fn new() -> Self { 45 + Self { 46 + objects: BTreeMap::new(), 47 + next_handle: 1, // 0 is reserved as invalid 48 + } 49 + } 50 + 51 + /// Create a new memory object and return a capability with full rights 52 + pub fn create_object( 53 + &mut self, 54 + address: usize, 55 + size: usize, 56 + purpose: AllocationPurpose, 57 + ) -> Result<Capability, ManaError> { 58 + let handle = ObjectHandle(self.next_handle); 59 + self.next_handle += 1; 60 + 61 + let object = Object { 62 + handle, 63 + object_type: ObjectType::Memory, 64 + address, 65 + size, 66 + purpose, 67 + ref_count: 1, 68 + }; 69 + 70 + self.objects.insert(handle, object); 71 + 72 + // Return a capability with full rights for the creator 73 + Ok(Capability::new(handle, CapabilityRights::full())) 74 + } 75 + 76 + /// Release an object (decrement ref count, free if zero) 77 + /// Requires a valid capability to the object 78 + pub fn release_object(&mut self, capability: &Capability) -> Result<(), ManaError> { 79 + // Validate the capability 80 + if !self.validate_capability(capability) { 81 + return Err(ManaError::InvalidCapability); 82 + } 83 + 84 + let object = self 85 + .objects 86 + .get_mut(&capability.handle) 87 + .ok_or(ManaError::InvalidHandle)?; 88 + 89 + if object.ref_count == 0 { 90 + return Err(ManaError::AlreadyReleased); 91 + } 92 + 93 + object.ref_count -= 1; 94 + 95 + if object.ref_count == 0 { 96 + // Actually free the memory and remove the object 97 + self.objects.remove(&capability.handle); 98 + } 99 + 100 + Ok(()) 101 + } 102 + 103 + /// Get the number of objects currently managed 104 + pub fn object_count(&self) -> usize { 105 + self.objects.len() 106 + } 107 + 108 + /// Validate a capability - checks that the handle exists 109 + /// In a real implementation, this would also check unforgeable tokens 110 + pub fn validate_capability(&self, capability: &Capability) -> bool { 111 + self.objects.contains_key(&capability.handle) 112 + } 113 + 114 + /// Clone a capability (increment ref count) 115 + /// Requires TRANSFER rights to share the capability 116 + pub fn clone_capability(&mut self, capability: &Capability) -> Result<Capability, ManaError> { 117 + // Verify the capability is valid 118 + if !self.validate_capability(capability) { 119 + return Err(ManaError::InvalidCapability); 120 + } 121 + 122 + // Check if this capability can be transferred 123 + if !capability.can_transfer() { 124 + return Err(ManaError::CannotTransfer); 125 + } 126 + 127 + let object = self 128 + .objects 129 + .get_mut(&capability.handle) 130 + .ok_or(ManaError::InvalidHandle)?; 131 + 132 + object.ref_count += 1; 133 + 134 + // Return a new capability with the same rights 135 + Ok(Capability::new(capability.handle, capability.rights)) 136 + } 137 + 138 + /// Derive a new capability with restricted rights 139 + /// This allows creating read-only capabilities from read-write ones, etc. 140 + pub fn derive_capability( 141 + &self, 142 + capability: &Capability, 143 + new_rights: CapabilityRights, 144 + ) -> Result<Capability, ManaError> { 145 + // Verify the original capability is valid 146 + if !self.validate_capability(capability) { 147 + return Err(ManaError::InvalidCapability); 148 + } 149 + 150 + // Can only derive rights that the original capability has 151 + if !capability.rights.contains(new_rights) { 152 + return Err(ManaError::InsufficientRights); 153 + } 154 + 155 + Ok(Capability::new(capability.handle, new_rights)) 156 + } 157 + 158 + /// Access object data through a capability (for reading) 159 + /// Returns the object's address and size if the capability grants READ rights 160 + pub fn access_object(&self, capability: &Capability) -> Result<(usize, usize), ManaError> { 161 + if !self.validate_capability(capability) { 162 + return Err(ManaError::InvalidCapability); 163 + } 164 + 165 + if !capability.can_read() { 166 + return Err(ManaError::InsufficientRights); 167 + } 168 + 169 + let object = self 170 + .objects 171 + .get(&capability.handle) 172 + .ok_or(ManaError::InvalidHandle)?; 173 + 174 + Ok((object.address, object.size)) 175 + } 176 + 177 + /// Get object metadata through a capability 178 + pub fn get_object_info(&self, capability: &Capability) -> Result<ObjectInfo, ManaError> { 179 + if !self.validate_capability(capability) { 180 + return Err(ManaError::InvalidCapability); 181 + } 182 + 183 + let object = self 184 + .objects 185 + .get(&capability.handle) 186 + .ok_or(ManaError::InvalidHandle)?; 187 + 188 + Ok(ObjectInfo { 189 + object_type: object.object_type, 190 + size: object.size, 191 + purpose: object.purpose, 192 + ref_count: object.ref_count, 193 + }) 194 + } 195 + } 196 + 197 + /// Public information about an object (doesn't reveal address) 198 + #[derive(Debug, Clone, Copy)] 199 + pub struct ObjectInfo { 200 + pub object_type: ObjectType, 201 + pub size: usize, 202 + pub purpose: AllocationPurpose, 203 + pub ref_count: usize, 204 + }
+52
aethelos-source/heartwood/src/mana_pool/sanctuary.rs
··· 1 + //! Sanctuary - Long-lived, stable memory allocations 2 + 3 + use super::ManaError; 4 + 5 + /// Size of the Sanctuary region (for now, a placeholder) 6 + const SANCTUARY_SIZE: usize = 16 * 1024 * 1024; // 16 MB 7 + 8 + /// The Sanctuary manages long-lived memory allocations 9 + pub struct Sanctuary { 10 + base_address: usize, 11 + total_size: usize, 12 + used_size: usize, 13 + } 14 + 15 + impl Default for Sanctuary { 16 + fn default() -> Self { 17 + Self::new() 18 + } 19 + } 20 + 21 + impl Sanctuary { 22 + pub fn new() -> Self { 23 + // In a real implementation, this would reserve actual memory 24 + Self { 25 + base_address: 0x1000_0000, // Placeholder address 26 + total_size: SANCTUARY_SIZE, 27 + used_size: 0, 28 + } 29 + } 30 + 31 + /// Allocate memory in the Sanctuary 32 + pub fn allocate(&mut self, size: usize) -> Result<usize, ManaError> { 33 + if size > self.total_size - self.used_size { 34 + return Err(ManaError::OutOfMemory); 35 + } 36 + 37 + let address = self.base_address + self.used_size; 38 + self.used_size += size; 39 + 40 + Ok(address) 41 + } 42 + 43 + /// Get the number of bytes used 44 + pub fn used_bytes(&self) -> usize { 45 + self.used_size 46 + } 47 + 48 + /// Get the total size 49 + pub fn total_bytes(&self) -> usize { 50 + self.total_size 51 + } 52 + }
+125
aethelos-source/heartwood/src/nexus/channel.rs
··· 1 + //! Channels - The conduits through which messages flow 2 + 3 + use super::message::Message; 4 + use alloc::collections::VecDeque; 5 + 6 + /// Maximum messages in a channel before backpressure 7 + const CHANNEL_CAPACITY: usize = 256; 8 + 9 + /// A unique identifier for a channel 10 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 11 + pub struct ChannelId(pub u64); 12 + 13 + /// A capability granting access to a channel 14 + /// This is what processes actually hold - not raw channel IDs 15 + #[derive(Debug, Clone, Copy)] 16 + pub struct ChannelCapability { 17 + pub channel_id: ChannelId, 18 + pub can_send: bool, 19 + pub can_receive: bool, 20 + } 21 + 22 + impl ChannelCapability { 23 + pub fn new_sender(channel_id: ChannelId) -> Self { 24 + Self { 25 + channel_id, 26 + can_send: true, 27 + can_receive: false, 28 + } 29 + } 30 + 31 + pub fn new_receiver(channel_id: ChannelId) -> Self { 32 + Self { 33 + channel_id, 34 + can_send: false, 35 + can_receive: true, 36 + } 37 + } 38 + 39 + pub fn new_bidirectional(channel_id: ChannelId) -> Self { 40 + Self { 41 + channel_id, 42 + can_send: true, 43 + can_receive: true, 44 + } 45 + } 46 + } 47 + 48 + /// A channel is a queue of messages with priority-based ordering 49 + pub struct Channel { 50 + id: ChannelId, 51 + messages: VecDeque<Message>, 52 + closed: bool, 53 + } 54 + 55 + impl Channel { 56 + pub fn new(id: ChannelId) -> Self { 57 + Self { 58 + id, 59 + messages: VecDeque::with_capacity(CHANNEL_CAPACITY), 60 + closed: false, 61 + } 62 + } 63 + 64 + pub fn id(&self) -> ChannelId { 65 + self.id 66 + } 67 + 68 + /// Send a message to this channel 69 + pub fn send(&mut self, message: Message) -> Result<(), ChannelError> { 70 + if self.closed { 71 + return Err(ChannelError::Closed); 72 + } 73 + 74 + if self.messages.len() >= CHANNEL_CAPACITY { 75 + return Err(ChannelError::Full); 76 + } 77 + 78 + // Insert message in priority order 79 + let priority = message.priority; 80 + let insert_pos = self 81 + .messages 82 + .iter() 83 + .position(|m| m.priority > priority) 84 + .unwrap_or(self.messages.len()); 85 + 86 + self.messages.insert(insert_pos, message); 87 + 88 + Ok(()) 89 + } 90 + 91 + /// Try to receive a message (non-blocking) 92 + pub fn try_receive(&mut self) -> Result<Option<Message>, ChannelError> { 93 + if self.closed && self.messages.is_empty() { 94 + return Err(ChannelError::Closed); 95 + } 96 + 97 + Ok(self.messages.pop_front()) 98 + } 99 + 100 + /// Check if the channel has any messages waiting 101 + pub fn has_messages(&self) -> bool { 102 + !self.messages.is_empty() 103 + } 104 + 105 + /// Get the number of messages in the channel 106 + pub fn message_count(&self) -> usize { 107 + self.messages.len() 108 + } 109 + 110 + /// Close the channel 111 + pub fn close(&mut self) { 112 + self.closed = true; 113 + } 114 + 115 + pub fn is_closed(&self) -> bool { 116 + self.closed 117 + } 118 + } 119 + 120 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 121 + pub enum ChannelError { 122 + Full, 123 + Closed, 124 + NotFound, 125 + }
+110
aethelos-source/heartwood/src/nexus/message.rs
··· 1 + //! Message definitions - The Astral Packets of the Nexus 2 + 3 + use alloc::vec::Vec; 4 + 5 + /// A message is the fundamental unit of communication in AethelOS 6 + #[derive(Debug, Clone)] 7 + pub struct Message { 8 + /// The type and payload of the message 9 + pub message_type: MessageType, 10 + 11 + /// Priority for harmony-based routing 12 + pub priority: MessagePriority, 13 + 14 + /// The sender's capability (for replies) 15 + pub reply_to: Option<u64>, 16 + } 17 + 18 + impl Message { 19 + pub fn new(message_type: MessageType, priority: MessagePriority) -> Self { 20 + Self { 21 + message_type, 22 + priority, 23 + reply_to: None, 24 + } 25 + } 26 + 27 + pub fn with_reply(mut self, reply_capability: u64) -> Self { 28 + self.reply_to = Some(reply_capability); 29 + self 30 + } 31 + } 32 + 33 + /// The type and payload of a message 34 + #[derive(Debug, Clone)] 35 + pub enum MessageType { 36 + /// A request to allocate resources 37 + ResourceRequest { 38 + resource_type: ResourceType, 39 + amount: usize, 40 + }, 41 + 42 + /// A grant of resources 43 + ResourceGrant { 44 + resource_type: ResourceType, 45 + handle: u64, 46 + }, 47 + 48 + /// A signal indicating state change 49 + Signal { 50 + signal_type: SignalType, 51 + }, 52 + 53 + /// Data transfer 54 + Data { 55 + payload: Vec<u8>, 56 + }, 57 + 58 + /// A query for system information 59 + Query { 60 + query_type: QueryType, 61 + }, 62 + 63 + /// Response to a query 64 + Response { 65 + data: Vec<u8>, 66 + }, 67 + 68 + /// Notification of disharmony 69 + DisharmonyAlert { 70 + severity: u8, 71 + description: &'static str, 72 + }, 73 + } 74 + 75 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 76 + pub enum ResourceType { 77 + Memory, 78 + CpuTime, 79 + FileHandle, 80 + ChannelCapability, 81 + } 82 + 83 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 84 + pub enum SignalType { 85 + ThreadWeaving, // Thread started 86 + ThreadResting, // Thread idle 87 + ThreadTangled, // Thread blocked/error 88 + ThreadFading, // Thread exiting 89 + SystemHarmony, // System in good state 90 + SystemDisharmony, // System under stress 91 + } 92 + 93 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 94 + pub enum QueryType { 95 + SystemStatus, 96 + ResourceAvailability, 97 + ThreadState, 98 + MemoryUsage, 99 + } 100 + 101 + /// Priority levels for message delivery 102 + /// Lower numeric values = higher priority 103 + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 104 + pub enum MessagePriority { 105 + Critical = 0, // System-critical messages 106 + High = 1, // Important user-facing operations 107 + Normal = 2, // Standard operations 108 + Low = 3, // Background tasks 109 + Idle = 4, // Lowest priority 110 + }
+62
aethelos-source/heartwood/src/nexus/mod.rs
··· 1 + //! # The Nexus 2 + //! 3 + //! The Inter-Process Communication core of AethelOS. 4 + //! The Nexus is the primary means by which all components of the system 5 + //! communicate - from kernel services to user-space Groves. 6 + //! 7 + //! ## Philosophy 8 + //! The Nexus does not force communication; it channels it. 9 + //! Messages flow like water through natural paths, finding their destination 10 + //! through intent rather than rigid addressing. 11 + //! 12 + //! ## Architecture 13 + //! - Asynchronous, non-blocking message passing 14 + //! - Capability-based addressing (no raw process IDs) 15 + //! - Priority-aware delivery (harmony-based routing) 16 + //! - Zero-copy where possible (messages live in the Mana Pool) 17 + 18 + pub mod message; 19 + pub mod nexus_core; 20 + pub mod channel; 21 + 22 + pub use message::{Message, MessageType, MessagePriority}; 23 + pub use nexus_core::NexusCore; 24 + pub use channel::{Channel, ChannelId, ChannelCapability}; 25 + 26 + use spin::Mutex; 27 + use lazy_static::lazy_static; 28 + 29 + lazy_static! { 30 + static ref NEXUS: Mutex<NexusCore> = Mutex::new(NexusCore::new()); 31 + } 32 + 33 + /// Initialize the Nexus 34 + pub fn init() { 35 + let nexus = NEXUS.lock(); 36 + // Nexus initialization happens on construction 37 + drop(nexus); 38 + } 39 + 40 + /// Send a message through the Nexus 41 + pub fn send(channel: ChannelId, message: Message) -> Result<(), NexusError> { 42 + NEXUS.lock().send(channel, message) 43 + } 44 + 45 + /// Receive a message from a channel (non-blocking) 46 + pub fn try_receive(channel: ChannelId) -> Result<Option<Message>, NexusError> { 47 + NEXUS.lock().try_receive(channel) 48 + } 49 + 50 + /// Create a new bidirectional channel 51 + pub fn create_channel() -> Result<(ChannelCapability, ChannelCapability), NexusError> { 52 + NEXUS.lock().create_channel() 53 + } 54 + 55 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 56 + pub enum NexusError { 57 + ChannelNotFound, 58 + ChannelFull, 59 + ChannelClosed, 60 + InvalidCapability, 61 + OutOfChannels, 62 + }
+118
aethelos-source/heartwood/src/nexus/nexus_core.rs
··· 1 + //! The Nexus Core - The beating heart of IPC 2 + 3 + use super::channel::{Channel, ChannelId, ChannelCapability}; 4 + use super::message::Message; 5 + use super::NexusError; 6 + use alloc::collections::BTreeMap; 7 + 8 + /// The maximum number of channels the Nexus can manage 9 + const MAX_CHANNELS: usize = 4096; 10 + 11 + /// The central Nexus manages all channels in the system 12 + pub struct NexusCore { 13 + channels: BTreeMap<ChannelId, Channel>, 14 + next_channel_id: u64, 15 + } 16 + 17 + impl Default for NexusCore { 18 + fn default() -> Self { 19 + Self::new() 20 + } 21 + } 22 + 23 + impl NexusCore { 24 + pub fn new() -> Self { 25 + Self { 26 + channels: BTreeMap::new(), 27 + next_channel_id: 1, // 0 is reserved as invalid 28 + } 29 + } 30 + 31 + /// Create a new bidirectional channel pair 32 + /// Returns two capabilities: (sender_side, receiver_side) 33 + pub fn create_channel(&mut self) -> Result<(ChannelCapability, ChannelCapability), NexusError> { 34 + if self.channels.len() >= MAX_CHANNELS { 35 + return Err(NexusError::OutOfChannels); 36 + } 37 + 38 + let channel_id = ChannelId(self.next_channel_id); 39 + self.next_channel_id += 1; 40 + 41 + let channel = Channel::new(channel_id); 42 + self.channels.insert(channel_id, channel); 43 + 44 + // Create bidirectional capabilities 45 + let cap_a = ChannelCapability::new_bidirectional(channel_id); 46 + let cap_b = ChannelCapability::new_bidirectional(channel_id); 47 + 48 + Ok((cap_a, cap_b)) 49 + } 50 + 51 + /// Send a message through a channel 52 + pub fn send(&mut self, channel_id: ChannelId, message: Message) -> Result<(), NexusError> { 53 + let channel = self 54 + .channels 55 + .get_mut(&channel_id) 56 + .ok_or(NexusError::ChannelNotFound)?; 57 + 58 + channel 59 + .send(message) 60 + .map_err(|e| match e { 61 + super::channel::ChannelError::Full => NexusError::ChannelFull, 62 + super::channel::ChannelError::Closed => NexusError::ChannelClosed, 63 + super::channel::ChannelError::NotFound => NexusError::ChannelNotFound, 64 + }) 65 + } 66 + 67 + /// Try to receive a message from a channel (non-blocking) 68 + pub fn try_receive(&mut self, channel_id: ChannelId) -> Result<Option<Message>, NexusError> { 69 + let channel = self 70 + .channels 71 + .get_mut(&channel_id) 72 + .ok_or(NexusError::ChannelNotFound)?; 73 + 74 + channel 75 + .try_receive() 76 + .map_err(|e| match e { 77 + super::channel::ChannelError::Closed => NexusError::ChannelClosed, 78 + super::channel::ChannelError::NotFound => NexusError::ChannelNotFound, 79 + super::channel::ChannelError::Full => NexusError::ChannelFull, 80 + }) 81 + } 82 + 83 + /// Close a channel 84 + pub fn close_channel(&mut self, channel_id: ChannelId) -> Result<(), NexusError> { 85 + let channel = self 86 + .channels 87 + .get_mut(&channel_id) 88 + .ok_or(NexusError::ChannelNotFound)?; 89 + 90 + channel.close(); 91 + Ok(()) 92 + } 93 + 94 + /// Get statistics about the Nexus 95 + pub fn stats(&self) -> NexusStats { 96 + NexusStats { 97 + total_channels: self.channels.len(), 98 + active_channels: self 99 + .channels 100 + .values() 101 + .filter(|c| !c.is_closed()) 102 + .count(), 103 + total_queued_messages: self 104 + .channels 105 + .values() 106 + .map(|c| c.message_count()) 107 + .sum(), 108 + } 109 + } 110 + } 111 + 112 + /// Statistics about the Nexus 113 + #[derive(Debug, Clone, Copy)] 114 + pub struct NexusStats { 115 + pub total_channels: usize, 116 + pub active_channels: usize, 117 + pub total_queued_messages: usize, 118 + }
+178
aethelos-source/heartwood/src/vga_buffer.rs
··· 1 + //! VGA Buffer - The First Voice of the Heartwood 2 + //! 3 + //! Provides early text output before the full Weave is initialized. 4 + 5 + use core::fmt; 6 + use lazy_static::lazy_static; 7 + use spin::Mutex; 8 + 9 + const BUFFER_HEIGHT: usize = 25; 10 + const BUFFER_WIDTH: usize = 80; 11 + 12 + #[allow(dead_code)] 13 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 14 + #[repr(u8)] 15 + pub enum Color { 16 + Black = 0, 17 + Blue = 1, 18 + Green = 2, 19 + Cyan = 3, 20 + Red = 4, 21 + Magenta = 5, 22 + Brown = 6, 23 + LightGray = 7, 24 + DarkGray = 8, 25 + LightBlue = 9, 26 + LightGreen = 10, 27 + LightCyan = 11, 28 + LightRed = 12, 29 + Pink = 13, 30 + Yellow = 14, 31 + White = 15, 32 + } 33 + 34 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 35 + #[repr(transparent)] 36 + struct ColorCode(u8); 37 + 38 + impl ColorCode { 39 + fn new(foreground: Color, background: Color) -> ColorCode { 40 + ColorCode((background as u8) << 4 | (foreground as u8)) 41 + } 42 + } 43 + 44 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 45 + #[repr(C)] 46 + struct ScreenChar { 47 + ascii_character: u8, 48 + color_code: ColorCode, 49 + } 50 + 51 + #[repr(transparent)] 52 + struct Buffer { 53 + chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT], 54 + } 55 + 56 + pub struct Writer { 57 + column_position: usize, 58 + color_code: ColorCode, 59 + buffer: &'static mut Buffer, 60 + } 61 + 62 + impl Writer { 63 + pub fn write_byte(&mut self, byte: u8) { 64 + match byte { 65 + b'\n' => self.new_line(), 66 + byte => { 67 + if self.column_position >= BUFFER_WIDTH { 68 + self.new_line(); 69 + } 70 + 71 + let row = BUFFER_HEIGHT - 1; 72 + let col = self.column_position; 73 + 74 + let color_code = self.color_code; 75 + self.buffer.chars[row][col] = ScreenChar { 76 + ascii_character: byte, 77 + color_code, 78 + }; 79 + self.column_position += 1; 80 + } 81 + } 82 + } 83 + 84 + pub fn write_string(&mut self, s: &str) { 85 + for byte in s.bytes() { 86 + match byte { 87 + 0x20..=0x7e | b'\n' => self.write_byte(byte), 88 + _ => self.write_byte(0xfe), // ■ for unprintable 89 + } 90 + } 91 + } 92 + 93 + fn new_line(&mut self) { 94 + for row in 1..BUFFER_HEIGHT { 95 + for col in 0..BUFFER_WIDTH { 96 + let character = self.buffer.chars[row][col]; 97 + self.buffer.chars[row - 1][col] = character; 98 + } 99 + } 100 + self.clear_row(BUFFER_HEIGHT - 1); 101 + self.column_position = 0; 102 + } 103 + 104 + fn clear_row(&mut self, row: usize) { 105 + let blank = ScreenChar { 106 + ascii_character: b' ', 107 + color_code: self.color_code, 108 + }; 109 + for col in 0..BUFFER_WIDTH { 110 + self.buffer.chars[row][col] = blank; 111 + } 112 + } 113 + 114 + pub fn set_color(&mut self, foreground: Color, background: Color) { 115 + self.color_code = ColorCode::new(foreground, background); 116 + } 117 + } 118 + 119 + impl fmt::Write for Writer { 120 + fn write_str(&mut self, s: &str) -> fmt::Result { 121 + self.write_string(s); 122 + Ok(()) 123 + } 124 + } 125 + 126 + lazy_static! { 127 + pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer { 128 + column_position: 0, 129 + color_code: ColorCode::new(Color::LightCyan, Color::Black), 130 + buffer: unsafe { &mut *(0xb8000 as *mut Buffer) }, 131 + }); 132 + } 133 + 134 + pub fn initialize() { 135 + // Clear screen 136 + let mut writer = WRITER.lock(); 137 + for row in 0..BUFFER_HEIGHT { 138 + writer.clear_row(row); 139 + } 140 + writer.column_position = 0; 141 + } 142 + 143 + pub fn print_banner() { 144 + let mut writer = WRITER.lock(); 145 + 146 + writer.set_color(Color::LightCyan, Color::Black); 147 + writer.write_string("\n"); 148 + writer.write_string(" ====================================\n"); 149 + writer.set_color(Color::White, Color::Black); 150 + writer.write_string(" AethelOS - The Heartwood\n"); 151 + writer.set_color(Color::LightGray, Color::Black); 152 + writer.write_string(" Symbiotic Computing Awakens\n"); 153 + writer.set_color(Color::LightCyan, Color::Black); 154 + writer.write_string(" ====================================\n"); 155 + writer.set_color(Color::LightCyan, Color::Black); 156 + writer.write_string("\n"); 157 + } 158 + 159 + #[macro_export] 160 + macro_rules! print { 161 + ($($arg:tt)*) => ($crate::vga_buffer::_print(format_args!($($arg)*))); 162 + } 163 + 164 + #[macro_export] 165 + macro_rules! println { 166 + () => ($crate::print!("\n")); 167 + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); 168 + } 169 + 170 + #[doc(hidden)] 171 + pub fn _print(args: fmt::Arguments) { 172 + use core::fmt::Write; 173 + // use x86_64::instructions::interrupts; // Requires nightly Rust 174 + 175 + // interrupts::without_interrupts(|| { 176 + WRITER.lock().write_fmt(args).unwrap(); 177 + // }); 178 + }
+289
aethelos-source/setup-boot.ps1
··· 1 + # Setup script to make AethelOS bootable in QEMU (Windows PowerShell) 2 + 3 + Write-Host "=== AethelOS Boot Setup ===" -ForegroundColor Cyan 4 + Write-Host "" 5 + 6 + # Create custom target specification 7 + Write-Host "[1/6] Creating custom target specification..." -ForegroundColor Yellow 8 + $targetSpec = @' 9 + { 10 + "llvm-target": "x86_64-unknown-none", 11 + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", 12 + "arch": "x86_64", 13 + "target-endian": "little", 14 + "target-pointer-width": "64", 15 + "target-c-int-width": "32", 16 + "os": "none", 17 + "executables": true, 18 + "linker-flavor": "ld.lld", 19 + "linker": "rust-lld", 20 + "panic-strategy": "abort", 21 + "disable-redzone": true, 22 + "features": "-mmx,-sse,+soft-float" 23 + } 24 + '@ 25 + $targetSpec | Out-File -FilePath "x86_64-aethelos.json" -Encoding ASCII 26 + 27 + # Create linker script 28 + Write-Host "[2/6] Creating linker script..." -ForegroundColor Yellow 29 + $linkerScript = @' 30 + ENTRY(_start) 31 + 32 + SECTIONS { 33 + /* Start at 1MB to leave space for bootloader */ 34 + . = 1M; 35 + 36 + /* Multiboot header must be first */ 37 + .boot ALIGN(4K) : 38 + { 39 + KEEP(*(.multiboot)) 40 + } 41 + 42 + .text ALIGN(4K) : 43 + { 44 + *(.text .text.*) 45 + } 46 + 47 + .rodata ALIGN(4K) : 48 + { 49 + *(.rodata .rodata.*) 50 + } 51 + 52 + .data ALIGN(4K) : 53 + { 54 + *(.data .data.*) 55 + } 56 + 57 + .bss ALIGN(4K) : 58 + { 59 + *(COMMON) 60 + *(.bss .bss.*) 61 + } 62 + 63 + /* Discard unwanted sections */ 64 + /DISCARD/ : 65 + { 66 + *(.eh_frame) 67 + *(.note.gnu.build-id) 68 + } 69 + } 70 + '@ 71 + $linkerScript | Out-File -FilePath "heartwood\linker.ld" -Encoding ASCII 72 + 73 + # Create boot.rs 74 + Write-Host "[3/6] Creating boot module with Multiboot2 header..." -ForegroundColor Yellow 75 + $bootRs = @' 76 + //! Boot initialization and Multiboot2 support 77 + 78 + /// Multiboot2 header structure 79 + #[repr(C, align(8))] 80 + struct Multiboot2Header { 81 + magic: u32, 82 + architecture: u32, 83 + header_length: u32, 84 + checksum: u32, 85 + // End tag 86 + end_type: u16, 87 + end_flags: u16, 88 + end_size: u32, 89 + } 90 + 91 + const MULTIBOOT2_MAGIC: u32 = 0xe85250d6; 92 + const MULTIBOOT2_ARCH_I386: u32 = 0; 93 + const HEADER_LENGTH: u32 = core::mem::size_of::<Multiboot2Header>() as u32; 94 + 95 + /// The Multiboot2 header - must be in first 8KB of kernel 96 + #[used] 97 + #[link_section = ".multiboot"] 98 + static MULTIBOOT2_HEADER: Multiboot2Header = Multiboot2Header { 99 + magic: MULTIBOOT2_MAGIC, 100 + architecture: MULTIBOOT2_ARCH_I386, 101 + header_length: HEADER_LENGTH, 102 + checksum: 0u32 103 + .wrapping_sub(MULTIBOOT2_MAGIC) 104 + .wrapping_sub(MULTIBOOT2_ARCH_I386) 105 + .wrapping_sub(HEADER_LENGTH), 106 + end_type: 0, 107 + end_flags: 0, 108 + end_size: 8, 109 + }; 110 + 111 + /// Parse Multiboot2 information structure 112 + pub unsafe fn parse_multiboot_info(_multiboot_info_addr: usize) { 113 + // In a real implementation, this would: 114 + // 1. Parse memory map 115 + // 2. Get framebuffer info 116 + // 3. Find loaded modules 117 + // 4. Get bootloader name 118 + // For now, this is a placeholder 119 + } 120 + '@ 121 + $bootRs | Out-File -FilePath "heartwood\src\boot.rs" -Encoding UTF8 122 + 123 + # Create cargo config 124 + Write-Host "[4/6] Creating cargo configuration..." -ForegroundColor Yellow 125 + New-Item -ItemType Directory -Force -Path ".cargo" | Out-Null 126 + $cargoConfig = @' 127 + [build] 128 + target = "x86_64-aethelos.json" 129 + 130 + [target.'cfg(target_os = "none")'] 131 + rustflags = ["-C", "link-arg=-T./heartwood/linker.ld"] 132 + 133 + [unstable] 134 + build-std = ["core", "alloc", "compiler_builtins"] 135 + build-std-features = ["compiler-builtins-mem"] 136 + '@ 137 + $cargoConfig | Out-File -FilePath ".cargo\config.toml" -Encoding ASCII 138 + 139 + # Update lib.rs 140 + Write-Host "[5/6] Adding boot module to heartwood..." -ForegroundColor Yellow 141 + $libRsPath = "heartwood\src\lib.rs" 142 + $libRsContent = Get-Content $libRsPath -Raw 143 + if ($libRsContent -notmatch "pub mod boot;") { 144 + $newContent = "pub mod boot;`r`n" + $libRsContent 145 + $newContent | Out-File -FilePath $libRsPath -Encoding UTF8 -NoNewline 146 + } 147 + 148 + # Create run script 149 + Write-Host "[6/6] Creating QEMU run script..." -ForegroundColor Yellow 150 + $runScript = @' 151 + # Run AethelOS in QEMU (Windows PowerShell) 152 + 153 + param( 154 + [ValidateSet("vga", "serial", "debug", "gdb")] 155 + [string]$Mode = "vga" 156 + ) 157 + 158 + # Check if binary exists 159 + if (-not (Test-Path "target\x86_64-aethelos\debug\heartwood.exe")) { 160 + Write-Host "Error: Kernel binary not found. Run '.\build.ps1' first." -ForegroundColor Red 161 + exit 1 162 + } 163 + 164 + # Find QEMU 165 + $qemu = $null 166 + $qemuPaths = @( 167 + "C:\Program Files\qemu\qemu-system-x86_64.exe", 168 + "C:\Program Files (x86)\qemu\qemu-system-x86_64.exe", 169 + "$env:ProgramFiles\qemu\qemu-system-x86_64.exe" 170 + ) 171 + 172 + foreach ($path in $qemuPaths) { 173 + if (Test-Path $path) { 174 + $qemu = $path 175 + break 176 + } 177 + } 178 + 179 + if (-not $qemu) { 180 + # Try to find in PATH 181 + $qemu = (Get-Command qemu-system-x86_64 -ErrorAction SilentlyContinue).Source 182 + } 183 + 184 + if (-not $qemu) { 185 + Write-Host "Error: QEMU not found. Install from https://qemu.weilnetz.de/w64/" -ForegroundColor Red 186 + exit 1 187 + } 188 + 189 + switch ($Mode) { 190 + "vga" { 191 + Write-Host "Running AethelOS with VGA display..." -ForegroundColor Green 192 + & $qemu ` 193 + -kernel target\x86_64-aethelos\debug\heartwood.exe ` 194 + -m 256M ` 195 + -vga std ` 196 + -serial mon:stdio 197 + } 198 + "serial" { 199 + Write-Host "Running AethelOS with serial output..." -ForegroundColor Green 200 + & $qemu ` 201 + -kernel target\x86_64-aethelos\debug\heartwood.exe ` 202 + -m 256M ` 203 + -serial stdio ` 204 + -display none 205 + } 206 + "debug" { 207 + Write-Host "Running AethelOS in debug mode..." -ForegroundColor Green 208 + & $qemu ` 209 + -kernel target\x86_64-aethelos\debug\heartwood.exe ` 210 + -m 256M ` 211 + -vga std ` 212 + -serial mon:stdio ` 213 + -d int,cpu_reset ` 214 + -no-reboot ` 215 + -no-shutdown 216 + } 217 + "gdb" { 218 + Write-Host "Running AethelOS with GDB server on :1234..." -ForegroundColor Green 219 + Write-Host "In another terminal, run: rust-gdb target\x86_64-aethelos\debug\heartwood.exe" -ForegroundColor Cyan 220 + Write-Host "Then in GDB: (gdb) target remote :1234" -ForegroundColor Cyan 221 + & $qemu ` 222 + -kernel target\x86_64-aethelos\debug\heartwood.exe ` 223 + -m 256M ` 224 + -vga std ` 225 + -serial mon:stdio ` 226 + -s -S 227 + } 228 + } 229 + '@ 230 + $runScript | Out-File -FilePath "run-qemu.ps1" -Encoding ASCII 231 + 232 + # Create build script 233 + $buildScript = @' 234 + # Build AethelOS kernel (Windows PowerShell) 235 + 236 + Write-Host "=== Building AethelOS Kernel ===" -ForegroundColor Cyan 237 + 238 + # Check for cargo 239 + if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { 240 + Write-Host "Error: cargo not found. Install Rust from https://rustup.rs/" -ForegroundColor Red 241 + exit 1 242 + } 243 + 244 + # Check for nightly toolchain 245 + $toolchains = rustup toolchain list 246 + if ($toolchains -notmatch "nightly") { 247 + Write-Host "Installing nightly toolchain for build-std..." -ForegroundColor Yellow 248 + rustup toolchain install nightly 249 + } 250 + 251 + # Add rust-src component 252 + $components = rustup component list --toolchain nightly 253 + if ($components -notmatch "rust-src.*installed") { 254 + Write-Host "Adding rust-src component..." -ForegroundColor Yellow 255 + rustup component add rust-src --toolchain nightly 256 + } 257 + 258 + # Build the kernel 259 + Write-Host "" 260 + Write-Host "Building heartwood kernel..." -ForegroundColor Yellow 261 + cargo +nightly build --package heartwood --bin heartwood 262 + 263 + Write-Host "" 264 + Write-Host "✓ Build complete!" -ForegroundColor Green 265 + Write-Host " Binary: target\x86_64-aethelos\debug\heartwood.exe" -ForegroundColor Cyan 266 + Write-Host "" 267 + Write-Host "To run in QEMU:" -ForegroundColor Cyan 268 + Write-Host " .\run-qemu.ps1 # VGA display mode" 269 + Write-Host " .\run-qemu.ps1 serial # Serial console mode" 270 + Write-Host " .\run-qemu.ps1 debug # Debug mode" 271 + Write-Host " .\run-qemu.ps1 gdb # GDB debugging" 272 + '@ 273 + $buildScript | Out-File -FilePath "build.ps1" -Encoding ASCII 274 + 275 + Write-Host "" 276 + Write-Host "=== Setup Complete! ===" -ForegroundColor Green 277 + Write-Host "" 278 + Write-Host "Next steps:" -ForegroundColor Cyan 279 + Write-Host " 1. Run: .\build.ps1 # Build the kernel" 280 + Write-Host " 2. Run: .\run-qemu.ps1 # Boot in QEMU" 281 + Write-Host "" 282 + Write-Host "QEMU modes:" -ForegroundColor Cyan 283 + Write-Host " .\run-qemu.ps1 vga # VGA display (default)" 284 + Write-Host " .\run-qemu.ps1 serial # Serial console only" 285 + Write-Host " .\run-qemu.ps1 debug # Debug mode with logging" 286 + Write-Host " .\run-qemu.ps1 gdb # GDB debugging on :1234" 287 + Write-Host "" 288 + Write-Host "Note: You'll need QEMU installed" -ForegroundColor Yellow 289 + Write-Host " Download from: https://qemu.weilnetz.de/w64/"
+273
aethelos-source/setup-boot.sh
··· 1 + #!/bin/bash 2 + # Setup script to make AethelOS bootable in QEMU 3 + 4 + set -e 5 + 6 + echo "=== AethelOS Boot Setup ===" 7 + echo "" 8 + 9 + # Create custom target specification 10 + echo "[1/6] Creating custom target specification..." 11 + cat > x86_64-aethelos.json << 'EOF' 12 + { 13 + "llvm-target": "x86_64-unknown-none", 14 + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", 15 + "arch": "x86_64", 16 + "target-endian": "little", 17 + "target-pointer-width": "64", 18 + "target-c-int-width": "32", 19 + "os": "none", 20 + "executables": true, 21 + "linker-flavor": "ld.lld", 22 + "linker": "rust-lld", 23 + "panic-strategy": "abort", 24 + "disable-redzone": true, 25 + "features": "-mmx,-sse,+soft-float" 26 + } 27 + EOF 28 + 29 + # Create linker script 30 + echo "[2/6] Creating linker script..." 31 + cat > heartwood/linker.ld << 'EOF' 32 + ENTRY(_start) 33 + 34 + SECTIONS { 35 + /* Start at 1MB to leave space for bootloader */ 36 + . = 1M; 37 + 38 + /* Multiboot header must be first */ 39 + .boot ALIGN(4K) : 40 + { 41 + KEEP(*(.multiboot)) 42 + } 43 + 44 + .text ALIGN(4K) : 45 + { 46 + *(.text .text.*) 47 + } 48 + 49 + .rodata ALIGN(4K) : 50 + { 51 + *(.rodata .rodata.*) 52 + } 53 + 54 + .data ALIGN(4K) : 55 + { 56 + *(.data .data.*) 57 + } 58 + 59 + .bss ALIGN(4K) : 60 + { 61 + *(COMMON) 62 + *(.bss .bss.*) 63 + } 64 + 65 + /* Discard unwanted sections */ 66 + /DISCARD/ : 67 + { 68 + *(.eh_frame) 69 + *(.note.gnu.build-id) 70 + } 71 + } 72 + EOF 73 + 74 + # Create boot.rs with multiboot2 header 75 + echo "[3/6] Creating boot module with Multiboot2 header..." 76 + cat > heartwood/src/boot.rs << 'EOF' 77 + //! Boot initialization and Multiboot2 support 78 + 79 + /// Multiboot2 header structure 80 + #[repr(C, align(8))] 81 + struct Multiboot2Header { 82 + magic: u32, 83 + architecture: u32, 84 + header_length: u32, 85 + checksum: u32, 86 + // End tag 87 + end_type: u16, 88 + end_flags: u16, 89 + end_size: u32, 90 + } 91 + 92 + const MULTIBOOT2_MAGIC: u32 = 0xe85250d6; 93 + const MULTIBOOT2_ARCH_I386: u32 = 0; 94 + const HEADER_LENGTH: u32 = core::mem::size_of::<Multiboot2Header>() as u32; 95 + 96 + /// The Multiboot2 header - must be in first 8KB of kernel 97 + #[used] 98 + #[link_section = ".multiboot"] 99 + static MULTIBOOT2_HEADER: Multiboot2Header = Multiboot2Header { 100 + magic: MULTIBOOT2_MAGIC, 101 + architecture: MULTIBOOT2_ARCH_I386, 102 + header_length: HEADER_LENGTH, 103 + checksum: 0u32 104 + .wrapping_sub(MULTIBOOT2_MAGIC) 105 + .wrapping_sub(MULTIBOOT2_ARCH_I386) 106 + .wrapping_sub(HEADER_LENGTH), 107 + end_type: 0, 108 + end_flags: 0, 109 + end_size: 8, 110 + }; 111 + 112 + /// Parse Multiboot2 information structure 113 + pub unsafe fn parse_multiboot_info(_multiboot_info_addr: usize) { 114 + // In a real implementation, this would: 115 + // 1. Parse memory map 116 + // 2. Get framebuffer info 117 + // 3. Find loaded modules 118 + // 4. Get bootloader name 119 + // For now, this is a placeholder 120 + } 121 + EOF 122 + 123 + # Create cargo config 124 + echo "[4/6] Creating cargo configuration..." 125 + mkdir -p .cargo 126 + cat > .cargo/config.toml << 'EOF' 127 + [build] 128 + target = "x86_64-aethelos.json" 129 + 130 + [target.'cfg(target_os = "none")'] 131 + rustflags = ["-C", "link-arg=-T./heartwood/linker.ld"] 132 + 133 + [unstable] 134 + build-std = ["core", "alloc", "compiler_builtins"] 135 + build-std-features = ["compiler-builtins-mem"] 136 + EOF 137 + 138 + # Update heartwood lib.rs to include boot module 139 + echo "[5/6] Adding boot module to heartwood..." 140 + if ! grep -q "pub mod boot;" heartwood/src/lib.rs; then 141 + sed -i '1i pub mod boot;' heartwood/src/lib.rs 2>/dev/null || \ 142 + gsed -i '1i pub mod boot;' heartwood/src/lib.rs 2>/dev/null || \ 143 + echo "Warning: Could not auto-add boot module. Add 'pub mod boot;' to heartwood/src/lib.rs manually." 144 + fi 145 + 146 + # Create run script 147 + echo "[6/6] Creating QEMU run script..." 148 + cat > run-qemu.sh << 'EOF' 149 + #!/bin/bash 150 + # Run AethelOS in QEMU 151 + 152 + # Check if binary exists 153 + if [ ! -f "target/x86_64-aethelos/debug/heartwood" ]; then 154 + echo "Error: Kernel binary not found. Run './build.sh' first." 155 + exit 1 156 + fi 157 + 158 + # Default to VGA mode 159 + MODE=${1:-vga} 160 + 161 + case $MODE in 162 + vga) 163 + echo "Running AethelOS with VGA display..." 164 + qemu-system-x86_64 \ 165 + -kernel target/x86_64-aethelos/debug/heartwood \ 166 + -m 256M \ 167 + -vga std \ 168 + -serial mon:stdio 169 + ;; 170 + serial) 171 + echo "Running AethelOS with serial output..." 172 + qemu-system-x86_64 \ 173 + -kernel target/x86_64-aethelos/debug/heartwood \ 174 + -m 256M \ 175 + -serial stdio \ 176 + -display none 177 + ;; 178 + debug) 179 + echo "Running AethelOS in debug mode..." 180 + qemu-system-x86_64 \ 181 + -kernel target/x86_64-aethelos/debug/heartwood \ 182 + -m 256M \ 183 + -vga std \ 184 + -serial mon:stdio \ 185 + -d int,cpu_reset \ 186 + -no-reboot \ 187 + -no-shutdown 188 + ;; 189 + gdb) 190 + echo "Running AethelOS with GDB server on :1234..." 191 + echo "In another terminal, run: rust-gdb target/x86_64-aethelos/debug/heartwood" 192 + echo "Then in GDB: (gdb) target remote :1234" 193 + qemu-system-x86_64 \ 194 + -kernel target/x86_64-aethelos/debug/heartwood \ 195 + -m 256M \ 196 + -vga std \ 197 + -serial mon:stdio \ 198 + -s -S 199 + ;; 200 + *) 201 + echo "Usage: $0 [vga|serial|debug|gdb]" 202 + echo "" 203 + echo " vga - Run with VGA display (default)" 204 + echo " serial - Run with serial console only" 205 + echo " debug - Run with debugging output" 206 + echo " gdb - Run with GDB server" 207 + exit 1 208 + ;; 209 + esac 210 + EOF 211 + chmod +x run-qemu.sh 212 + 213 + # Create build script 214 + cat > build.sh << 'EOF' 215 + #!/bin/bash 216 + # Build AethelOS kernel 217 + 218 + set -e 219 + 220 + echo "=== Building AethelOS Kernel ===" 221 + 222 + # Check for required tools 223 + if ! command -v cargo &> /dev/null; then 224 + echo "Error: cargo not found. Install Rust from https://rustup.rs/" 225 + exit 1 226 + fi 227 + 228 + # Check for nightly toolchain (needed for build-std) 229 + if ! rustup toolchain list | grep -q nightly; then 230 + echo "Installing nightly toolchain for build-std..." 231 + rustup toolchain install nightly 232 + fi 233 + 234 + # Add rust-src component if not present 235 + if ! rustup component list --toolchain nightly | grep -q "rust-src (installed)"; then 236 + echo "Adding rust-src component..." 237 + rustup component add rust-src --toolchain nightly 238 + fi 239 + 240 + # Build the kernel 241 + echo "" 242 + echo "Building heartwood kernel..." 243 + cargo +nightly build --package heartwood --bin heartwood 244 + 245 + echo "" 246 + echo "✓ Build complete!" 247 + echo " Binary: target/x86_64-aethelos/debug/heartwood" 248 + echo "" 249 + echo "To run in QEMU:" 250 + echo " ./run-qemu.sh # VGA display mode" 251 + echo " ./run-qemu.sh serial # Serial console mode" 252 + echo " ./run-qemu.sh debug # Debug mode" 253 + echo " ./run-qemu.sh gdb # GDB debugging" 254 + EOF 255 + chmod +x build.sh 256 + 257 + echo "" 258 + echo "=== Setup Complete! ===" 259 + echo "" 260 + echo "Next steps:" 261 + echo " 1. Run: ./build.sh # Build the kernel" 262 + echo " 2. Run: ./run-qemu.sh # Boot in QEMU" 263 + echo "" 264 + echo "QEMU modes:" 265 + echo " ./run-qemu.sh vga # VGA display (default)" 266 + echo " ./run-qemu.sh serial # Serial console only" 267 + echo " ./run-qemu.sh debug # Debug mode with logging" 268 + echo " ./run-qemu.sh gdb # GDB debugging on :1234" 269 + echo "" 270 + echo "Note: You'll need QEMU installed (qemu-system-x86_64)" 271 + echo " Windows: https://qemu.weilnetz.de/w64/" 272 + echo " Linux: sudo apt install qemu-system-x86" 273 + echo " macOS: brew install qemu"