+15
.claude/settings.local.json
+15
.claude/settings.local.json
+429
aethelos-source/ARCHITECTURE.txt
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+255
aethelos-source/README.md
···
1
+
# AethelOS - A Symbiotic Operating System
2
+
3
+

4
+

5
+

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
+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
+7
aethelos-source/ancient-runes/corelib/Cargo.toml
+83
aethelos-source/ancient-runes/corelib/src/lib.rs
+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
+8
aethelos-source/ancient-runes/script/Cargo.toml
+66
aethelos-source/ancient-runes/script/src/lib.rs
+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
+8
aethelos-source/ancient-runes/weaving/Cargo.toml
+156
aethelos-source/ancient-runes/weaving/src/lib.rs
+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
+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
+7
aethelos-source/awakening/heartwood_loader/Cargo.toml
+22
aethelos-source/awakening/heartwood_loader/src/lib.rs
+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
aethelos-source/clippy_output.txt
This is a binary file and will not be displayed.
+7
aethelos-source/groves/lanthir_grove/Cargo.toml
+7
aethelos-source/groves/lanthir_grove/Cargo.toml
+100
aethelos-source/groves/lanthir_grove/src/lib.rs
+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
+7
aethelos-source/groves/network_sprite/Cargo.toml
+130
aethelos-source/groves/network_sprite/src/lib.rs
+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
+7
aethelos-source/groves/the-weave_grove/Cargo.toml
+185
aethelos-source/groves/the-weave_grove/src/lib.rs
+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
+7
aethelos-source/groves/world-tree_grove/Cargo.toml
+173
aethelos-source/groves/world-tree_grove/src/lib.rs
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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"