Embrace extreme minimalism - cut everything unnecessary

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-28 17:48:51 +00:00
parent 9a2ec2c753
commit 012327c7e7
6 changed files with 477 additions and 207 deletions

View File

@@ -1,8 +1,25 @@
# MetalOS
A minimal operating system built from the ground up to run QT6 applications on AMD64 hardware with Radeon RX 6600 GPU and UEFI boot.
**The most minimal OS possible that runs QT6 Hello World.**
**Not Linux. Not BSD. Not Windows.** Just enough OS to run a QT6 Hello World full-screen application.
Not Linux. Not BSD. Not Windows. Just enough code to boot, initialize GPU, and run one app.
## Extreme Minimalism
MetalOS is an exercise in **absolute minimalism**:
-**No scheduler** - one app = always running
-**No process management** - one process only
-**No file system** - app embedded in boot image
-**No networking** - not needed
-**No shell/command line** - boot directly to app
-**No security** - trust everything
-**No multi-core** - one CPU core
-**No dynamic linking** - static link everything
**If it doesn't help QT6 Hello World run, it doesn't exist.**
Target: **< 200 KB OS code** (excluding QT6 itself)
## Project Status
@@ -12,7 +29,23 @@ Currently: Project structure, documentation, and skeleton code in place.
## What is MetalOS?
MetalOS is a **minimal, purpose-built operating system** with a single goal: demonstrate that you can build a custom OS from scratch to run modern GUI applications (specifically QT6).
MetalOS is **the smallest possible operating system** that can boot QT6 Hello World on specific hardware.
### Philosophy
Every feature must answer: **"Does this help run QT6 Hello World?"**
If no → it doesn't exist.
### Aggressive Minimalism
- **Bootloader**: < 10 KB (just load kernel and jump)
- **Kernel**: < 100 KB (memory, interrupts, drivers)
- **GPU Driver**: < 50 KB (minimal display init)
- **Input Drivers**: < 20 KB (keyboard + mouse only)
- **Total OS**: ~200 KB
Compare to Linux kernel: ~30 MB. We're **150x smaller** by doing only one thing.
### Key Features
@@ -82,10 +115,13 @@ See [docs/BUILD.md](docs/BUILD.md) for instructions on creating a bootable USB d
## Documentation
- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** - System design and architecture
- **[BUILD.md](docs/BUILD.md)** - Build instructions and dependencies
- **[DEVELOPMENT.md](docs/DEVELOPMENT.md)** - Development workflow and guidelines
- **[ROADMAP.md](docs/ROADMAP.md)** - Development phases and timeline
- **[MINIMALISM.md](docs/MINIMALISM.md)** - ⭐ **START HERE** - Philosophy and what we cut
- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** - System design (minimal version)
- **[ROADMAP.md](docs/ROADMAP.md)** - Development phases
- **[BUILD.md](docs/BUILD.md)** - Build instructions
- **[DEVELOPMENT.md](docs/DEVELOPMENT.md)** - Development workflow
- **[COMPONENTS.md](docs/COMPONENTS.md)** - Component checklist
- **[STATUS.md](docs/STATUS.md)** - Current implementation status
## Project Structure
@@ -116,13 +152,13 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed breakdown.
## Why?
**Learning**: Building an OS from scratch is the ultimate systems programming education.
**Minimalism**: How small can an OS be and still run GUI apps?
**Minimal Design**: Modern OSes are complex. This project asks: "What's the absolute minimum needed for a GUI application?"
**Learning**: Building an OS from scratch is the ultimate systems programming challenge.
**Custom Hardware**: Show that you can optimize an OS for specific hardware instead of supporting everything.
**Proof of Concept**: Modern frameworks like QT6 can run on tiny custom OSes.
**QT6 Demo**: Prove that modern application frameworks can run on custom OS implementations.
**Fun**: Because we can.
## Technology Stack
@@ -142,15 +178,22 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed breakdown.
## Contributing
This is primarily a learning/demonstration project, but contributions are welcome!
**Golden Rule**: If it doesn't help QT6 Hello World, don't add it.
**Guidelines**:
- Keep it minimal - every feature must justify its existence
- Document your changes
- Follow existing code style
- Test on QEMU before submitting
Contributions welcome for:
- Simplifying existing code (make it smaller!)
- Bug fixes
- GPU driver work (hardest part)
- QT6 port work
- Documentation
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for details.
Not welcome:
- Adding features "for completeness"
- POSIX compatibility
- Supporting other hardware
- Generalizing anything
See [CONTRIBUTING.md](CONTRIBUTING.md) and [docs/MINIMALISM.md](docs/MINIMALISM.md).
## License

View File

@@ -1,12 +1,13 @@
/*
* MetalOS UEFI Bootloader
*
* This is a minimal UEFI bootloader that:
* 1. Initializes graphics output
* 2. Loads the kernel from disk
* 3. Retrieves memory map and system information
* 4. Exits boot services
* 5. Transfers control to kernel
* MINIMAL bootloader:
* 1. Get framebuffer from UEFI
* 2. Load kernel blob from disk
* 3. Exit boot services
* 4. Jump to kernel
*
* That's it. No fancy stuff.
*/
#include "bootloader.h"
@@ -116,46 +117,35 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) {
gST = SystemTable;
// Print banner
print_string(u"MetalOS Bootloader v0.1.0\r\n");
print_string(u"=========================\r\n\r\n");
print_string(u"MetalOS v0.1 - MINIMAL BOOTLOADER\r\n");
print_string(u"==================================\r\n\r\n");
// Initialize graphics
print_string(u"Initializing graphics...\r\n");
// Get framebuffer (don't care about resolution, take what UEFI gives us)
print_string(u"Getting framebuffer...\r\n");
status = initialize_graphics(ImageHandle);
print_status(u"Graphics initialization", status);
if (status != EFI_SUCCESS) {
print_string(u"WARNING: Graphics initialization failed, continuing...\r\n");
print_string(u"WARNING: No graphics, continuing anyway...\r\n");
}
// Load kernel
// Load kernel (just read metalos.bin, don't overthink it)
print_string(u"Loading kernel...\r\n");
status = load_kernel(ImageHandle);
print_status(u"Kernel load", status);
if (status != EFI_SUCCESS) {
print_string(u"ERROR: Failed to load kernel\r\n");
print_string(u"ERROR: Can't load kernel\r\n");
return status;
}
// Get ACPI information
print_string(u"Retrieving ACPI tables...\r\n");
boot_info.rsdp = get_rsdp();
// Get memory map (minimal info)
print_string(u"Getting memory map...\r\n");
// TODO: GetMemoryMap
// Get memory map
print_string(u"Retrieving memory map...\r\n");
// TODO: Call GetMemoryMap
// Exit boot services
print_string(u"Exiting boot services...\r\n");
// TODO: Call ExitBootServices
// Exit boot services (point of no return)
print_string(u"Exiting UEFI boot services...\r\n");
// TODO: ExitBootServices
// Jump to kernel
print_string(u"Starting kernel...\r\n");
// TODO: ((void(*)(BootInfo*))KERNEL_LOAD_ADDRESS)(&boot_info);
// TODO: Call kernel entry point with boot_info
// typedef void (*KernelEntry)(BootInfo*);
// KernelEntry kernel = (KernelEntry)KERNEL_LOAD_ADDRESS;
// kernel(&boot_info);
// If we get here, something went wrong
// Should never get here
return EFI_SUCCESS;
}

View File

@@ -6,10 +6,10 @@ MetalOS is a ground-up operating system designed specifically to run QT6 applica
## Design Principles
1. **Minimal by Design**: Only implement what's necessary to run QT6 applications
1. **Absolute Minimum**: If it's not needed for QT6 Hello World, it doesn't exist
2. **UEFI Native**: Boot directly via UEFI, no legacy BIOS support
3. **Hardware Specific**: Optimized for AMD64 + Radeon RX 6600
4. **Modern Approach**: Learn from Linux but implement cleanly from scratch
3. **Hardware Specific**: AMD64 + Radeon RX 6600 only - no abstractions for other hardware
4. **Single Purpose**: One app, one GPU, one goal - nothing else matters
## System Architecture
@@ -54,13 +54,13 @@ MetalOS is a ground-up operating system designed specifically to run QT6 applica
- Transfer control to kernel
### 2. Kernel Core
- **Purpose**: Provide essential OS services
- **Language**: C/C++ with assembly for low-level operations
- **Purpose**: Absolute bare minimum OS services
- **Language**: C with assembly for critical parts
- **Subsystems**:
- Memory Management (physical/virtual)
- Process/Thread Scheduler
- Interrupt Handling
- System Call Interface
- Memory Management (just enough for app + QT6)
- Single process support (no scheduler needed!)
- Interrupt handling (only what GPU/input needs)
- Direct syscall to kernel functions (no table/dispatch overhead)
### 3. Hardware Abstraction Layer (HAL)
- **Purpose**: Abstract hardware specifics
@@ -78,28 +78,29 @@ MetalOS is a ground-up operating system designed specifically to run QT6 applica
- QT6 framework (statically linked into application)
- No shell, no command line - direct boot to app
## Memory Layout
## Memory Layout (Simplified)
```
0x0000000000000000 - 0x0000000000000FFF : NULL guard page
0x0000000000001000 - 0x00000000000FFFFF : Bootloader code/data
0x0000000000100000 - 0x00000000FFFFFFFF : Kernel space
0x0000000100000000 - 0x00007FFFFFFFFFFF : User space
0xFFFF800000000000 - 0xFFFFFFFFFFFFFFFF : Kernel heap/stacks
0x0000000000001000 - 0x00000000000FFFFF : Bootloader (temporary)
0x0000000000100000 - 0x0000000000FFFFFF : Kernel (small!)
0x0000000001000000 - 0x00000000FFFFFFFF : Application + QT6
GPU VRAM: Separate, mapped via BAR
```
## Boot Process
No complex memory regions - keep it simple!
1. **UEFI Firmware** loads bootloader from EFI System Partition
2. **Bootloader** initializes basic hardware and sets up memory
3. **Bootloader** locates and loads kernel binary
4. **Bootloader** exits UEFI boot services
5. **Kernel** initializes subsystems (memory, scheduler, interrupts)
6. **Kernel** loads HAL drivers (GPU, PCI, input)
7. **Kernel** directly launches QT6 Hello World application (no shell, no init)
8. **Application** runs full-screen until exit/reboot
## Boot Process (Minimal)
**Note**: No command line, no shell - the system boots directly into the single application.
1. **UEFI Firmware** loads bootloader
2. **Bootloader** gets framebuffer, loads kernel, jumps
3. **Kernel** maps memory, enables interrupts
4. **Kernel** initializes GPU (minimal)
5. **Kernel** sets up input (keyboard/mouse only)
6. **Kernel** jumps directly to QT6 app
7. **App** runs until halt
**That's it. No filesystem, no daemons, no services, no nothing.**
## Development Phases

225
docs/MINIMALISM.md Normal file
View File

@@ -0,0 +1,225 @@
# MetalOS - Extreme Minimalism Guide
## What ABSOLUTE MINIMUM Means
We're not building a general-purpose OS. We're building **the smallest possible software layer** that lets QT6 Hello World run on AMD64 + RX 6600.
## Cut Everything
### ❌ NO Scheduler
- **Why not?**: One app = one process = always running
- **Instead**: Direct execution, no context switching
- **Saves**: Scheduler code, process queues, timer interrupts for scheduling
### ❌ NO Process Management
- **Why not?**: Only one process ever exists
- **Instead**: App runs in ring 0 (kernel mode) or simple ring 3 with static setup
- **Saves**: Process structures, fork/exec, process lifecycle
### ❌ NO File System
- **Why not?**: Everything loaded at boot
- **Instead**: App binary embedded in boot image or loaded by bootloader once
- **Saves**: VFS, inode structures, file descriptors, read/write/open/close
### ❌ NO Networking
- **Why not?**: Hello World doesn't need network
- **Instead**: Nothing
- **Saves**: TCP/IP stack, network drivers, sockets
### ❌ NO Security
- **Why not?**: Single app, demo system
- **Instead**: Trust everything
- **Saves**: Permissions, user/group IDs, capabilities, security modules
### ❌ NO Virtual Memory (maybe)
- **Why not?**: Could run everything with identity mapping
- **Instead**: Simple page tables just to keep CPU happy
- **Saves**: TLB management, page fault handling, swapping
### ❌ NO Dynamic Linking
- **Why not?**: Complexity nightmare
- **Instead**: Static link everything into one blob
- **Saves**: ELF loader complexity, PLT/GOT, symbol resolution at runtime
### ❌ NO Multi-core
- **Why not?**: One app on one core is plenty
- **Instead**: Use only bootstrap processor (BSP)
- **Saves**: SMP initialization, locks, atomic operations, IPI handling
### ❌ NO ACPI (mostly)
- **Why not?**: Complex and usually not needed for basic operation
- **Instead**: Minimal ACPI just for GPU if absolutely required
- **Saves**: AML interpreter, ACPI tables parsing, power management
### ❌ NO Signals/IPC
- **Why not?**: One process = nobody to talk to
- **Instead**: Nothing
- **Saves**: Signal handling, pipes, message queues, shared memory
### ❌ NO Timers (mostly)
- **Why not?**: QT6 needs *some* time, but minimal
- **Instead**: Simple timer for QT event loop only
- **Saves**: Complex timer infrastructure, high-resolution timers
## What We MUST Keep (Absolute Minimum)
### ✅ Memory Allocator
- **Why**: QT6 needs malloc/free
- **Minimum**: Simple bump allocator or basic free list
- **No need for**: Fancy algorithms, defragmentation, memory pools
### ✅ Interrupts
- **Why**: Keyboard/mouse input, timer for QT
- **Minimum**:
- Keyboard interrupt
- Mouse interrupt
- Timer interrupt (for QT event loop)
- GPU interrupt (if needed)
- **That's it!** Maybe 4-5 interrupt handlers total
### ✅ GPU Driver
- **Why**: Need to display graphics
- **Minimum**:
- Initialize display pipeline
- Set up framebuffer
- Blit pixels to screen
- **No need for**: 3D acceleration, multiple displays, hot-plug
### ✅ Input Drivers
- **Why**: Need keyboard/mouse for QT events
- **Minimum**:
- USB XHCI (or PS/2 if simpler!)
- HID keyboard
- HID mouse
- **No need for**: Other USB devices, complex HID parsing
### ✅ PCI Enumeration
- **Why**: Find the GPU
- **Minimum**:
- Scan bus for our specific GPU
- Enable memory/IO access
- **No need for**: Full PCI tree, hot-plug, PCI-to-PCI bridges
### ✅ System Calls (bare minimum)
- **Why**: User space needs to talk to kernel
- **Minimum**:
- `write()` - for debugging output
- `mmap()` - for memory
- `ioctl()` - for GPU/input
- Maybe 5-10 syscalls total
- **No need for**: POSIX compatibility, 300+ syscalls
## Radical Simplifications
### Framebuffer Over Everything
- **Skip**: Complex GPU 3D acceleration
- **Use**: Direct framebuffer blitting
- **QT6**: Can render to memory, we copy to VRAM
- **Trade-off**: Slower but WAY simpler
### Identity Mapping (maybe)
- **Skip**: Complex virtual memory
- **Use**: Physical = Virtual (or simple offset)
- **Note**: x86-64 requires paging enabled, but can be trivial
### PS/2 Over USB
- **Skip**: Complex USB stack if possible
- **Use**: PS/2 keyboard/mouse if hardware supports
- **Simpler**: Direct port I/O vs USB protocol
### Polling Over Interrupts (where possible)
- **Skip**: Complex interrupt handling
- **Use**: Poll for events in tight loop
- **Trade-off**: CPU usage vs complexity
### Hardcode Everything
- **Skip**: Configuration files, boot parameters
- **Use**: Compiled-in constants
- **Examples**:
- Screen resolution: 1920x1080 (hardcoded)
- GPU PCI ID: hardcoded
- Memory layout: hardcoded
## Code Size Targets
Aim for **minimal code size**:
- **Bootloader**: < 10 KB
- **Kernel**: < 100 KB
- **GPU Driver**: < 50 KB (hardest part)
- **Input Drivers**: < 20 KB
- **QT6 + App**: ~10-20 MB (unavoidable - QT is big)
**Total OS (without QT)**: ~200 KB or less!
## Performance Targets
We don't care about performance, we care about **working**:
- Boot time: Don't care (< 30 seconds is fine)
- Frame rate: Don't care (30 FPS is plenty)
- Memory usage: Don't care (512 MB is plenty)
- CPU usage: Don't care (can peg one core)
**Trade complexity for simplicity every time.**
## Implementation Strategy
### Phase 1 ✅ (Done)
- Project structure
- Documentation
### Phase 2 (Bootloader)
- UEFI console output (for debugging)
- Load kernel blob
- Jump to kernel
- **Skip**: Complex file systems, just load from known location
### Phase 3 (Kernel)
- Set up page tables (minimal)
- Set up interrupts (only what we need)
- Memory allocator (simple bump allocator)
- **Skip**: Complex memory management
### Phase 4 (GPU)
- PCI scan for RX 6600
- Enable BAR
- Initialize display (hardcode 1920x1080)
- Framebuffer blit
- **Skip**: Everything else GPU can do
### Phase 5 (Input)
- Try PS/2 first (simpler!)
- If not available, minimal USB XHCI
- Keyboard scancodes -> QT key events
- Mouse packets -> QT mouse events
- **Skip**: Complex HID parsing, other devices
### Phase 6 (QT6)
- Port minimal QT6 (Core + Gui + Widgets only)
- QPA plugin: just framebuffer blit + input events
- Static link everything
- **Skip**: All optional QT modules
### Phase 7 (Integration)
- Link app with QT6
- Embed in boot image
- Test and debug
- **Skip**: Anything that doesn't work - iterate
## When in Doubt
Ask these questions:
1. **Does Hello World need this?** No → Cut it
2. **Can we hardcode this?** Yes → Hardcode it
3. **Can we do this simpler?** Yes → Do it simpler
4. **Does Linux do it complex?** Yes → Do it simpler anyway
## Bottom Line
**Build the smallest possible OS that boots QT6 Hello World.**
If it doesn't directly contribute to that goal, it doesn't exist.
No compromises. Maximum minimalism.

View File

@@ -2,9 +2,11 @@
## Vision
MetalOS is a **minimal operating system** built from the ground up with a single purpose: run a QT6 Hello World application full-screen on AMD64 hardware with a Radeon RX 6600 GPU, booting via UEFI.
MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello World on AMD64 + RX 6600 via UEFI.
This is not a general-purpose OS. Every component is purpose-built to achieve this specific goal with minimal complexity.
**Target**: < 200 KB of OS code (excluding QT6)
**Philosophy**: If it doesn't directly enable QT6 Hello World, it doesn't exist.
## Development Phases
@@ -28,145 +30,136 @@ This is not a general-purpose OS. Every component is purpose-built to achieve th
### Phase 2: UEFI Bootloader (Next)
**Goal**: Boot from UEFI and load kernel
**Goal**: Load kernel and jump (< 10 KB code)
**Tasks**:
1. Implement UEFI protocol interfaces
- Console I/O for early debugging
- Graphics Output Protocol
- Simple File System Protocol
- Memory allocation
1. Console output for debugging (UEFI OutputString)
2. Get framebuffer info from GOP (Graphics Output Protocol)
3. Load kernel blob from known location
4. Get minimal memory map
5. Exit boot services
6. Jump to kernel
2. Graphics initialization
- Query available video modes
- Set optimal resolution (1920x1080 or best available)
- Set up framebuffer
**Simplifications**:
- Don't enumerate all video modes, take default
- Don't parse filesystem, load from fixed location
- Skip ACPI (try without it first)
- No error recovery, just halt on failure
3. Kernel loading
- Read metalos.bin from disk
- Load into memory at 1MB mark
- Verify kernel integrity
4. System information gathering
- Get memory map
- Find ACPI tables (RSDP)
- Detect CPU features
5. Exit boot services and jump to kernel
- Call ExitBootServices()
- Pass BootInfo structure to kernel
- Jump to kernel_main()
**Success Criteria**: Bootloader loads kernel and jumps to kernel code
**Success Criteria**: Bootloader prints messages and jumps to kernel
### Phase 3: Minimal Kernel
**Goal**: Initialize hardware and provide basic services
**Goal**: Initialize hardware (< 100 KB code)
**Tasks**:
1. Early kernel initialization
- Set up GDT (Global Descriptor Table)
- Set up IDT (Interrupt Descriptor Table)
- Enable interrupts
- Initialize framebuffer console
1. Minimal paging setup
- Identity map or simple offset
- Just enough to keep CPU happy
- No fancy page fault handling
2. Memory management
- Physical memory allocator (buddy system or bitmap)
- Virtual memory setup (page tables)
- Kernel heap allocator
- *Minimal implementation - just enough for QT6*
2. Interrupt handling
- IDT with ~5 handlers max
- Timer, keyboard, mouse, GPU (if needed)
- No complex IRQ routing
3. Process/Thread support
- Simple round-robin scheduler
- Context switching (bare minimum)
- Single user process support
- *No multi-user, no fancy scheduling*
3. Memory allocator
- Bump allocator or simple free list
- No fancy algorithms
- Just malloc/free for QT6
4. Basic I/O
- Serial port for debugging
- Framebuffer console
- *No disk I/O needed initially*
4. NO scheduler - one process, always running
5. NO process management - app is statically linked with kernel or simple jump
**Success Criteria**: Kernel boots, prints messages, can allocate memory
**Simplifications**:
- Skip GDT setup if not needed (UEFI might have set it up)
- Identity mapping instead of complex virtual memory
- Bump allocator instead of buddy/slab
- No TLB shootdown, no page fault handling
### Phase 4: Hardware Abstraction Layer
**Success Criteria**: Kernel boots, prints messages, mallocs work
**Goal**: Support minimal hardware needed for QT6
### Phase 4: Hardware Support
**Goal**: GPU + Input (< 70 KB code)
**Tasks**:
1. PCI Bus enumeration
- Scan PCI devices
- Find Radeon RX 6600 GPU
- Basic configuration
1. PCI scan (minimal)
- Hardcode scan for vendor 0x1002 (AMD)
- Find RX 6600 device ID
- Enable memory access
- That's it!
2. GPU Driver (Radeon RX 6600)
- Initialize GPU
- Set up display pipeline
- Configure framebuffer
- *Minimal - no 3D acceleration initially*
- *Can use reference from Linux amdgpu driver*
2. GPU Driver (hardest part, < 50 KB)
- Map MMIO registers
- Initialize display controller (DCN)
- Hardcode 1920x1080 mode
- Set up framebuffer in VRAM
- Enable display output
- *Study Linux amdgpu driver, but keep it simple*
3. Input devices
- USB HID keyboard support
- USB HID mouse support
- PS/2 fallback (if needed)
- *Just enough for QT event handling*
3. Input devices (< 20 KB)
- **Try PS/2 first** (much simpler than USB!)
- If no PS/2: minimal USB XHCI for HID
- Keyboard: scancode → QT key events
- Mouse: packets → QT mouse events
4. Timer
- APIC timer or PIT
- For scheduling and timeouts
**Simplifications**:
- No PCI tree traversal, just scan for our GPU
- No GPU 3D, just 2D framebuffer
- No hot-plug, no multiple displays
- PS/2 over USB if possible (way simpler)
- No timer sophistication, PIT is fine
**Success Criteria**: Can detect and initialize GPU, receive keyboard/mouse input
**Success Criteria**: Display working, keyboard/mouse input working
### Phase 5: System Call Interface
### Phase 5: Minimal Syscalls
**Goal**: Provide user-kernel boundary
**Goal**: User-kernel boundary (< 10 KB code)
**Tasks**:
1. System call mechanism
- syscall/sysret instructions
- System call table
- Parameter passing
1. Syscall mechanism (syscall/sysret or just direct calls)
2. Maybe 5-10 syscalls total:
- write() - debugging
- mmap() / munmap() - memory
- ioctl() - device control
- poll() - wait for input events
- exit() - halt system
2. Essential system calls
- exit() - terminate process
- write() - output to console/log
- mmap() - memory allocation
- open/read/close() - minimal file operations (if needed)
- ioctl() - device control (for GPU)
- poll/select() - event handling (for input)
**Simplifications**:
- No syscall table if app can directly call kernel functions
- No parameter validation (trust everything)
- No error handling (just panic)
3. User-kernel transitions
- Ring 3 to Ring 0 transitions
- Parameter validation
- Error handling
**Success Criteria**: App can call kernel functions
**Success Criteria**: User space can make system calls
### Phase 6: User Space & Application
### Phase 6: User Space Runtime
**Goal**: Support C++ applications
**Goal**: Load and run app
**Tasks**:
1. ELF loader
- Parse ELF headers
- Load program segments
- Set up entry point
- *Static linking initially - no dynamic loader*
1. Simple app loading
- Static-linked binary
- No ELF parsing if we can avoid it
- Just jump to known entry point
2. Minimal C/C++ runtime
- _start() function
- C++ global constructors/destructors
- Memory allocation (malloc/free)
- Basic string functions
- *Only what QT6 needs*
2. C++ minimal runtime
- Global constructors
- Basic new/delete (use kernel malloc)
- No exceptions (disable them)
3. Application launcher (no init/shell needed)
- Directly load QT6 hello world application
- No command line, no shell
- Single application until reboot
3. Direct boot to app
- No init, no shell
- Kernel calls app's main() directly
- App exits → kernel halts
**Success Criteria**: Can load and run the QT6 hello world application directly
**Simplifications**:
- Static link everything into one blob
- Skip ELF loader completely if possible
- No exceptions (compile with -fno-exceptions)
- App runs in ring 0 or simple ring 3
**Success Criteria**: Can run simple C++ program
### Phase 7: QT6 Port

View File

@@ -1,8 +1,9 @@
/*
* MetalOS Kernel - Main Entry Point
*
* Minimal kernel implementation for running QT6 applications.
* Only implements what's absolutely necessary.
* EXTREME MINIMAL kernel - only what's needed for QT6 Hello World.
* No scheduler, no process management, no filesystem, no nothing.
* Just: boot -> init GPU -> init input -> run app.
*/
#include "kernel/kernel.h"
@@ -11,6 +12,9 @@
/*
* Kernel main entry point
* Called by bootloader with boot information
*
* This is it. The entire OS. No scheduler, no processes, no filesystem.
* Just set up hardware and jump to the QT6 app.
*/
void kernel_main(BootInfo* boot_info) {
// Initialize basic console output using framebuffer
@@ -22,41 +26,55 @@ void kernel_main(BootInfo* boot_info) {
);
console_clear();
console_print("MetalOS Kernel v0.1.0\n");
console_print("=====================\n\n");
console_print("MetalOS v0.1 - MINIMAL\n");
console_print("======================\n\n");
console_print("Initializing minimal kernel...\n");
// TODO: Set up minimal page tables (identity mapped or simple offset)
console_print("[ ] Memory (identity map)\n");
// TODO: Initialize memory management
console_print("[ ] Memory management\n");
// TODO: Set up IDT with only interrupts we need:
// - Keyboard/mouse (USB or PS/2)
// - Timer (for QT event loop)
// - GPU (if needed)
// That's it! Maybe 5 interrupt handlers total.
console_print("[ ] Interrupts (minimal)\n");
// TODO: Initialize interrupt handling
console_print("[ ] Interrupt handling\n");
// TODO: Simple memory allocator (bump allocator is fine)
console_print("[ ] Heap (bump allocator)\n");
// TODO: Initialize PCI bus
console_print("[ ] PCI enumeration\n");
// TODO: Find RX 6600 GPU via PCI (hardcode vendor/device ID)
console_print("[ ] PCI (find GPU only)\n");
// TODO: Initialize GPU driver
console_print("[ ] GPU driver (Radeon RX 6600)\n");
// TODO: Initialize GPU - minimal
// - Enable BAR
// - Init display pipeline
// - Set up framebuffer at 1920x1080 (hardcoded)
console_print("[ ] GPU (RX 6600, 1920x1080)\n");
// TODO: Initialize input devices
console_print("[ ] Input devices\n");
// TODO: Initialize input
// Try PS/2 first (simpler!)
// Fall back to minimal USB XHCI if needed
console_print("[ ] Input (PS/2 or USB)\n");
// TODO: Setup system calls
console_print("[ ] System call interface\n");
// TODO: Jump directly to QT6 Hello World app
// No shell, no init, no fork/exec
// Just: jump to application entry point
console_print("[ ] Jump to QT6 app\n");
// TODO: Load and run QT6 hello world application directly (no shell/init)
console_print("[ ] Loading QT6 Hello World application...\n");
console_print("\nBooting app...\n");
console_print("\nKernel initialization complete.\n");
console_print("Booting directly into application (no shell)...\n");
// TODO: Replace this with jump to QT6 app
// For now, halt
console_print("ERROR: App not linked yet\n");
// TODO: Jump to QT6 hello world application entry point
// The application will run full-screen until exit
// No shell, no command line - just the one app
// Halt - in real implementation, we'd start the application
while(1) {
__asm__ volatile("hlt");
}
}
/*
* That's the entire kernel. No scheduler. No processes. No filesystem.
* Just boot, initialize hardware, run app.
*
* Total kernel size target: < 100 KB
*/