mirror of
https://github.com/johndoe6345789/MetalOS.git
synced 2026-04-24 13:45:02 +00:00
Create foundational structure for MetalOS - Phase 1 complete
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
59
.gitignore
vendored
59
.gitignore
vendored
@@ -1,11 +1,24 @@
|
|||||||
# Prerequisites
|
# MetalOS .gitignore
|
||||||
*.d
|
|
||||||
|
|
||||||
# Compiled Object files
|
# Build artifacts
|
||||||
|
*.o
|
||||||
|
*.d
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.bin
|
||||||
|
*.efi
|
||||||
|
*.elf
|
||||||
|
*.img
|
||||||
|
*.iso
|
||||||
*.slo
|
*.slo
|
||||||
*.lo
|
*.lo
|
||||||
*.o
|
|
||||||
*.obj
|
*.obj
|
||||||
|
*.dwo
|
||||||
|
|
||||||
|
# Build directories
|
||||||
|
build/
|
||||||
|
bootloader/build/
|
||||||
|
kernel/build/
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
@@ -18,18 +31,16 @@
|
|||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
# Compiled Dynamic libraries
|
# Compiled Dynamic libraries
|
||||||
*.so
|
|
||||||
*.dylib
|
*.dylib
|
||||||
*.dll
|
*.dll
|
||||||
|
|
||||||
# Fortran module files
|
# Fortran module files (if ever used)
|
||||||
*.mod
|
*.mod
|
||||||
*.smod
|
*.smod
|
||||||
|
|
||||||
# Compiled Static libraries
|
# Compiled Static libraries
|
||||||
*.lai
|
*.lai
|
||||||
*.la
|
*.la
|
||||||
*.a
|
|
||||||
*.lib
|
*.lib
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
@@ -37,5 +48,35 @@
|
|||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
# debug information files
|
# Editor files
|
||||||
*.dwo
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.sublime-*
|
||||||
|
|
||||||
|
# OS specific
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Debug and log files
|
||||||
|
*.log
|
||||||
|
qemu.log
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
|
||||||
|
# Qt specific
|
||||||
|
*.pro.user
|
||||||
|
*.pro.user.*
|
||||||
|
moc_*.cpp
|
||||||
|
moc_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
.qmake.stash
|
||||||
|
|
||||||
|
# Don't ignore example files
|
||||||
|
!docs/examples/*.bin
|
||||||
|
|
||||||
|
|||||||
195
CONTRIBUTING.md
Normal file
195
CONTRIBUTING.md
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
# Contributing to MetalOS
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to MetalOS!
|
||||||
|
|
||||||
|
## Philosophy
|
||||||
|
|
||||||
|
MetalOS has a unique philosophy:
|
||||||
|
|
||||||
|
1. **Minimal by Design**: Every line of code must justify its existence
|
||||||
|
2. **Purpose-Built**: The goal is to run QT6 Hello World, not to be a general-purpose OS
|
||||||
|
3. **Creative Freedom**: We're not bound by POSIX or traditional OS designs
|
||||||
|
4. **Precise Drivers**: Hardware driver code must be accurate and follow specs
|
||||||
|
|
||||||
|
## What We Accept
|
||||||
|
|
||||||
|
### Welcome Contributions ✅
|
||||||
|
|
||||||
|
- Bug fixes in existing code
|
||||||
|
- Documentation improvements
|
||||||
|
- Build system enhancements
|
||||||
|
- Code simplification (making things simpler is better than adding features)
|
||||||
|
- Hardware driver improvements (especially GPU)
|
||||||
|
- QT6 port work
|
||||||
|
- Performance optimizations
|
||||||
|
|
||||||
|
### Think Twice Before Adding ❌
|
||||||
|
|
||||||
|
- New features that don't directly support QT6
|
||||||
|
- Additional hardware support beyond target (AMD64 + RX 6600)
|
||||||
|
- Complex abstractions
|
||||||
|
- POSIX compatibility layers
|
||||||
|
- Security features (this is a demo project)
|
||||||
|
- Multi-user support
|
||||||
|
|
||||||
|
**Golden Rule**: Ask yourself "Does this help run QT6 Hello World?" before adding anything.
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
### C Code
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 4 spaces, no tabs
|
||||||
|
// snake_case for functions and variables
|
||||||
|
// PascalCase for types
|
||||||
|
// UPPER_SNAKE_CASE for constants
|
||||||
|
|
||||||
|
#ifndef METALOS_PATH_FILE_H
|
||||||
|
#define METALOS_PATH_FILE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX_BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t address;
|
||||||
|
uint64_t size;
|
||||||
|
} MemoryBlock;
|
||||||
|
|
||||||
|
// Functions: descriptive names, clear purpose
|
||||||
|
int allocate_memory(uint64_t size);
|
||||||
|
void free_memory(void* ptr);
|
||||||
|
|
||||||
|
#endif // METALOS_PATH_FILE_H
|
||||||
|
```
|
||||||
|
|
||||||
|
### C++ Code (for applications)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 4 spaces, no tabs
|
||||||
|
// camelCase for methods
|
||||||
|
// PascalCase for classes
|
||||||
|
|
||||||
|
class DisplayManager {
|
||||||
|
private:
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DisplayManager(uint32_t w, uint32_t h);
|
||||||
|
void render();
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Assembly
|
||||||
|
|
||||||
|
```nasm
|
||||||
|
; Intel syntax
|
||||||
|
; Clear comments explaining what's happening
|
||||||
|
; Descriptive labels
|
||||||
|
|
||||||
|
section .text
|
||||||
|
global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
; Set up stack
|
||||||
|
mov rsp, stack_top
|
||||||
|
|
||||||
|
; Call kernel main
|
||||||
|
call kernel_main
|
||||||
|
|
||||||
|
; Halt if we return
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Submission Process
|
||||||
|
|
||||||
|
1. **Fork the repository**
|
||||||
|
2. **Create a feature branch**: `git checkout -b feature/my-feature`
|
||||||
|
3. **Make your changes**
|
||||||
|
4. **Test thoroughly**: At minimum, test in QEMU
|
||||||
|
5. **Commit with clear messages**: `git commit -m "Add feature: description"`
|
||||||
|
6. **Push to your fork**: `git push origin feature/my-feature`
|
||||||
|
7. **Open a Pull Request**
|
||||||
|
|
||||||
|
## Pull Request Guidelines
|
||||||
|
|
||||||
|
### Good PR Description
|
||||||
|
|
||||||
|
```
|
||||||
|
## What does this do?
|
||||||
|
|
||||||
|
Implements basic PCI device enumeration in the HAL.
|
||||||
|
|
||||||
|
## Why is this needed?
|
||||||
|
|
||||||
|
Required to detect and initialize the Radeon RX 6600 GPU.
|
||||||
|
|
||||||
|
## How was it tested?
|
||||||
|
|
||||||
|
- Tested in QEMU with emulated PCI devices
|
||||||
|
- Verified PCI device list output
|
||||||
|
- Confirmed GPU is detected correctly
|
||||||
|
|
||||||
|
## Related Issues
|
||||||
|
|
||||||
|
Closes #42
|
||||||
|
```
|
||||||
|
|
||||||
|
### What We Look For
|
||||||
|
|
||||||
|
- **Clear purpose**: Why is this change needed?
|
||||||
|
- **Minimal scope**: Does it do one thing well?
|
||||||
|
- **Testing**: Has it been tested?
|
||||||
|
- **Documentation**: Are non-obvious parts explained?
|
||||||
|
- **No regressions**: Does existing functionality still work?
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Minimum Testing
|
||||||
|
|
||||||
|
Every PR should be tested in QEMU:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make clean
|
||||||
|
make all
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify:
|
||||||
|
- Code compiles without warnings
|
||||||
|
- System boots (if applicable)
|
||||||
|
- Changes work as expected
|
||||||
|
- No crashes or hangs
|
||||||
|
|
||||||
|
### Hardware Testing (if applicable)
|
||||||
|
|
||||||
|
For GPU driver changes or hardware-specific code, testing on real hardware is highly recommended.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
If you change functionality, update relevant documentation:
|
||||||
|
|
||||||
|
- Code comments for complex logic
|
||||||
|
- README.md for user-facing changes
|
||||||
|
- docs/ARCHITECTURE.md for design changes
|
||||||
|
- docs/DEVELOPMENT.md for development workflow changes
|
||||||
|
|
||||||
|
## Questions?
|
||||||
|
|
||||||
|
- Open a GitHub Discussion for general questions
|
||||||
|
- Comment on existing Issues for specific topics
|
||||||
|
- Tag maintainers in PRs if you need feedback
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
|
||||||
|
Be respectful, constructive, and helpful. This is a learning project - everyone is welcome regardless of experience level.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing, you agree that your contributions will be licensed under the same license as the project (see LICENSE file).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Happy hacking! 🚀
|
||||||
66
Makefile
Normal file
66
Makefile
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# MetalOS Main Makefile
|
||||||
|
# Builds bootloader, kernel, and creates bootable image
|
||||||
|
|
||||||
|
.PHONY: all bootloader kernel image qemu qemu-debug qemu-gdb clean distclean
|
||||||
|
|
||||||
|
all: bootloader kernel
|
||||||
|
|
||||||
|
bootloader:
|
||||||
|
@echo "Building bootloader..."
|
||||||
|
@cd bootloader && $(MAKE)
|
||||||
|
|
||||||
|
kernel:
|
||||||
|
@echo "Building kernel..."
|
||||||
|
@cd kernel && $(MAKE)
|
||||||
|
|
||||||
|
# Create bootable disk image
|
||||||
|
image: bootloader kernel
|
||||||
|
@echo "Creating bootable image..."
|
||||||
|
@mkdir -p build/iso/EFI/BOOT
|
||||||
|
@cp bootloader/bootx64.efi build/iso/EFI/BOOT/
|
||||||
|
@cp kernel/metalos.bin build/iso/
|
||||||
|
@# TODO: Use xorriso or similar to create proper disk image
|
||||||
|
@echo "Image creation requires additional tools (xorriso, mtools)"
|
||||||
|
@echo "Manual steps:"
|
||||||
|
@echo " 1. Format USB/disk with GPT and FAT32 EFI System Partition"
|
||||||
|
@echo " 2. Copy bootloader/bootx64.efi to /EFI/BOOT/ on ESP"
|
||||||
|
@echo " 3. Copy kernel/metalos.bin to root of ESP"
|
||||||
|
|
||||||
|
# Run in QEMU
|
||||||
|
qemu: image
|
||||||
|
@echo "Starting QEMU..."
|
||||||
|
@# Requires OVMF UEFI firmware
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-bios /usr/share/ovmf/OVMF.fd \
|
||||||
|
-drive format=raw,file=build/metalos.img \
|
||||||
|
-m 512M \
|
||||||
|
-serial stdio
|
||||||
|
|
||||||
|
qemu-debug: image
|
||||||
|
@echo "Starting QEMU with debug output..."
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-bios /usr/share/ovmf/OVMF.fd \
|
||||||
|
-drive format=raw,file=build/metalos.img \
|
||||||
|
-m 512M \
|
||||||
|
-serial stdio \
|
||||||
|
-d int,cpu_reset
|
||||||
|
|
||||||
|
qemu-gdb: image
|
||||||
|
@echo "Starting QEMU with GDB server on port 1234..."
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-bios /usr/share/ovmf/OVMF.fd \
|
||||||
|
-drive format=raw,file=build/metalos.img \
|
||||||
|
-m 512M \
|
||||||
|
-serial stdio \
|
||||||
|
-s -S
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "Cleaning build artifacts..."
|
||||||
|
@cd bootloader && $(MAKE) clean
|
||||||
|
@cd kernel && $(MAKE) clean
|
||||||
|
@rm -rf build
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
@echo "Deep clean..."
|
||||||
|
@find . -name "*.o" -delete
|
||||||
|
@find . -name "*.d" -delete
|
||||||
173
README.md
173
README.md
@@ -1,5 +1,172 @@
|
|||||||
# MetalOS
|
# MetalOS
|
||||||
A OS that is not linux, not bsd and not windows. Ground up OS with just enough bespoke kernel to run a QT6 hello world full screen app on AMD64 with Radeon RX 6600 GPU., UEFI native
|
|
||||||
|
|
||||||
- Might use Linux kernel only as inspiration for driver code
|
A minimal operating system built from the ground up to run QT6 applications on AMD64 hardware with Radeon RX 6600 GPU and UEFI boot.
|
||||||
- Some changes might be required to QT6 - We can git clone this.
|
|
||||||
|
**Not Linux. Not BSD. Not Windows.** Just enough OS to run a QT6 Hello World full-screen application.
|
||||||
|
|
||||||
|
## Project Status
|
||||||
|
|
||||||
|
🚧 **In Development** - Phase 1 Complete (Foundation)
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
|
||||||
|
- ✅ **UEFI Native**: Modern boot via UEFI (no legacy BIOS)
|
||||||
|
- ✅ **AMD64 Architecture**: 64-bit x86 processor support
|
||||||
|
- ✅ **Radeon RX 6600 GPU**: Hardware-specific graphics support
|
||||||
|
- ✅ **QT6 Framework**: Full QT6 widget support
|
||||||
|
- ✅ **Minimal Design**: Only what's necessary, nothing more
|
||||||
|
|
||||||
|
### What's Included
|
||||||
|
|
||||||
|
- **UEFI Bootloader**: Initializes hardware and loads kernel
|
||||||
|
- **Minimal Kernel**: Memory management, scheduling, interrupts
|
||||||
|
- **GPU Driver**: Radeon RX 6600 specific (inspired by Linux amdgpu)
|
||||||
|
- **HAL**: Hardware abstraction for PCI, input devices
|
||||||
|
- **User Space**: Minimal C++ runtime for applications
|
||||||
|
- **QT6 Port**: QT6 framework ported to MetalOS
|
||||||
|
- **Hello World App**: Full-screen QT6 demonstration application
|
||||||
|
|
||||||
|
### What's NOT Included
|
||||||
|
|
||||||
|
- ❌ Multi-user support
|
||||||
|
- ❌ Command line / shell
|
||||||
|
- ❌ Networking stack
|
||||||
|
- ❌ File systems (app embedded in boot image)
|
||||||
|
- ❌ POSIX compatibility
|
||||||
|
- ❌ Security features (this is a demo/learning project)
|
||||||
|
- ❌ Support for other hardware
|
||||||
|
- ❌ Multiple applications (single app only)
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install build-essential nasm qemu-system-x86 ovmf
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
brew install nasm qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll also need a cross-compiler. See [docs/BUILD.md](docs/BUILD.md) for details.
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone https://github.com/johndoe6345789/MetalOS.git
|
||||||
|
cd MetalOS
|
||||||
|
|
||||||
|
# Build everything
|
||||||
|
make all
|
||||||
|
|
||||||
|
# Create bootable image
|
||||||
|
make image
|
||||||
|
|
||||||
|
# Test in QEMU
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing on Hardware
|
||||||
|
|
||||||
|
⚠️ **WARNING**: This is experimental software. Test on non-production hardware only.
|
||||||
|
|
||||||
|
See [docs/BUILD.md](docs/BUILD.md) for instructions on creating a bootable USB drive.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
MetalOS/
|
||||||
|
├── bootloader/ # UEFI bootloader
|
||||||
|
├── kernel/ # MetalOS kernel
|
||||||
|
├── userspace/ # User space runtime and applications
|
||||||
|
│ ├── runtime/ # C++ runtime
|
||||||
|
│ ├── init/ # Init process
|
||||||
|
│ └── apps/ # QT6 hello world application
|
||||||
|
├── docs/ # Documentation
|
||||||
|
└── scripts/ # Build scripts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Phases
|
||||||
|
|
||||||
|
- [x] **Phase 1**: Foundation (Complete)
|
||||||
|
- [ ] **Phase 2**: UEFI Bootloader
|
||||||
|
- [ ] **Phase 3**: Minimal Kernel
|
||||||
|
- [ ] **Phase 4**: Hardware Abstraction Layer
|
||||||
|
- [ ] **Phase 5**: System Call Interface
|
||||||
|
- [ ] **Phase 6**: User Space Runtime
|
||||||
|
- [ ] **Phase 7**: QT6 Port
|
||||||
|
- [ ] **Phase 8**: Integration & Polish
|
||||||
|
|
||||||
|
See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed breakdown.
|
||||||
|
|
||||||
|
## Why?
|
||||||
|
|
||||||
|
**Learning**: Building an OS from scratch is the ultimate systems programming education.
|
||||||
|
|
||||||
|
**Minimal Design**: Modern OSes are complex. This project asks: "What's the absolute minimum needed for a GUI application?"
|
||||||
|
|
||||||
|
**Custom Hardware**: Show that you can optimize an OS for specific hardware instead of supporting everything.
|
||||||
|
|
||||||
|
**QT6 Demo**: Prove that modern application frameworks can run on custom OS implementations.
|
||||||
|
|
||||||
|
## Technology Stack
|
||||||
|
|
||||||
|
- **Language**: C for kernel, C++ for applications
|
||||||
|
- **Boot**: UEFI
|
||||||
|
- **Architecture**: AMD64 (x86-64)
|
||||||
|
- **Graphics**: Direct framebuffer + Radeon RX 6600
|
||||||
|
- **GUI**: QT6 (Core, Gui, Widgets)
|
||||||
|
- **Build**: GNU Make, GCC cross-compiler
|
||||||
|
|
||||||
|
## Inspiration
|
||||||
|
|
||||||
|
- **Linux Kernel**: For driver implementations (especially GPU)
|
||||||
|
- **SerenityOS**: For clean, minimal OS design
|
||||||
|
- **TempleOS**: For single-purpose OS philosophy
|
||||||
|
- **Redox OS**: For Rust-based OS architecture (though we use C/C++)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
This is primarily a learning/demonstration project, but contributions are welcome!
|
||||||
|
|
||||||
|
**Guidelines**:
|
||||||
|
- Keep it minimal - every feature must justify its existence
|
||||||
|
- Document your changes
|
||||||
|
- Follow existing code style
|
||||||
|
- Test on QEMU before submitting
|
||||||
|
|
||||||
|
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for details.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
⚠️ **This is not production software!** MetalOS is a learning/demonstration project. It lacks security features, error handling, and hardware support expected in production OSes.
|
||||||
|
|
||||||
|
Do not use for anything important!
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
- **Issues**: [GitHub Issues](https://github.com/johndoe6345789/MetalOS/issues)
|
||||||
|
- **Discussions**: [GitHub Discussions](https://github.com/johndoe6345789/MetalOS/discussions)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**MetalOS** - A minimal OS for maximal learning.
|
||||||
|
|||||||
55
bootloader/Makefile
Normal file
55
bootloader/Makefile
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# MetalOS Bootloader Makefile
|
||||||
|
# Builds UEFI bootloader (bootx64.efi)
|
||||||
|
|
||||||
|
# Cross-compiler setup
|
||||||
|
CC = gcc
|
||||||
|
LD = ld
|
||||||
|
OBJCOPY = objcopy
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
SRC_DIR = src
|
||||||
|
INC_DIR = include
|
||||||
|
BUILD_DIR = build
|
||||||
|
|
||||||
|
# Compiler flags for UEFI
|
||||||
|
CFLAGS = -Wall -Wextra -Werror \
|
||||||
|
-ffreestanding -fno-stack-protector -fno-stack-check \
|
||||||
|
-fshort-wchar -mno-red-zone \
|
||||||
|
-I$(INC_DIR) \
|
||||||
|
-DEFI_FUNCTION_WRAPPER
|
||||||
|
|
||||||
|
# Linker flags for UEFI
|
||||||
|
LDFLAGS = -shared -Bsymbolic -nostdlib \
|
||||||
|
-znocombreloc -T uefi.lds
|
||||||
|
|
||||||
|
# Source files
|
||||||
|
SOURCES = $(wildcard $(SRC_DIR)/*.c)
|
||||||
|
OBJECTS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SOURCES))
|
||||||
|
|
||||||
|
# Output
|
||||||
|
TARGET = bootx64.efi
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(BUILD_DIR) $(TARGET)
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
# Compile C files
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Link and create EFI binary
|
||||||
|
$(TARGET): $(OBJECTS)
|
||||||
|
$(LD) $(LDFLAGS) $(OBJECTS) -o $(BUILD_DIR)/bootx64.so
|
||||||
|
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic \
|
||||||
|
-j .dynsym -j .rel -j .rela -j .reloc \
|
||||||
|
--target=efi-app-x86_64 \
|
||||||
|
$(BUILD_DIR)/bootx64.so $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR) $(TARGET)
|
||||||
|
|
||||||
|
# Note: This is a simplified Makefile
|
||||||
|
# A real implementation would use gnu-efi or proper UEFI SDK
|
||||||
22
bootloader/include/bootloader.h
Normal file
22
bootloader/include/bootloader.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef METALOS_BOOTLOADER_BOOTLOADER_H
|
||||||
|
#define METALOS_BOOTLOADER_BOOTLOADER_H
|
||||||
|
|
||||||
|
#include "efi.h"
|
||||||
|
|
||||||
|
// Bootloader version
|
||||||
|
#define BOOTLOADER_VERSION_MAJOR 0
|
||||||
|
#define BOOTLOADER_VERSION_MINOR 1
|
||||||
|
#define BOOTLOADER_VERSION_PATCH 0
|
||||||
|
|
||||||
|
// Memory limits
|
||||||
|
#define KERNEL_LOAD_ADDRESS 0x100000 // 1MB mark
|
||||||
|
#define MAX_KERNEL_SIZE 0x1000000 // 16MB max
|
||||||
|
|
||||||
|
// Function declarations
|
||||||
|
EFI_STATUS initialize_graphics(EFI_HANDLE ImageHandle);
|
||||||
|
EFI_STATUS load_kernel(EFI_HANDLE ImageHandle);
|
||||||
|
void* get_rsdp(void);
|
||||||
|
void print_string(const CHAR16* str);
|
||||||
|
void print_status(const CHAR16* operation, EFI_STATUS status);
|
||||||
|
|
||||||
|
#endif // METALOS_BOOTLOADER_BOOTLOADER_H
|
||||||
98
bootloader/include/efi.h
Normal file
98
bootloader/include/efi.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#ifndef METALOS_BOOTLOADER_EFI_H
|
||||||
|
#define METALOS_BOOTLOADER_EFI_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Basic UEFI types
|
||||||
|
typedef uint64_t EFI_STATUS;
|
||||||
|
typedef void* EFI_HANDLE;
|
||||||
|
typedef uint64_t UINTN;
|
||||||
|
typedef uint16_t CHAR16;
|
||||||
|
|
||||||
|
// EFI Status codes
|
||||||
|
#define EFI_SUCCESS 0
|
||||||
|
#define EFI_LOAD_ERROR 1
|
||||||
|
#define EFI_INVALID_PARAMETER 2
|
||||||
|
#define EFI_UNSUPPORTED 3
|
||||||
|
#define EFI_BUFFER_TOO_SMALL 5
|
||||||
|
#define EFI_NOT_READY 6
|
||||||
|
#define EFI_NOT_FOUND 14
|
||||||
|
|
||||||
|
// EFI Memory types
|
||||||
|
#define EfiReservedMemoryType 0
|
||||||
|
#define EfiLoaderCode 1
|
||||||
|
#define EfiLoaderData 2
|
||||||
|
#define EfiBootServicesCode 3
|
||||||
|
#define EfiBootServicesData 4
|
||||||
|
#define EfiRuntimeServicesCode 5
|
||||||
|
#define EfiRuntimeServicesData 6
|
||||||
|
#define EfiConventionalMemory 7
|
||||||
|
#define EfiUnusableMemory 8
|
||||||
|
#define EfiACPIReclaimMemory 9
|
||||||
|
#define EfiACPIMemoryNVS 10
|
||||||
|
#define EfiMemoryMappedIO 11
|
||||||
|
#define EfiMemoryMappedIOPortSpace 12
|
||||||
|
#define EfiPalCode 13
|
||||||
|
#define EfiPersistentMemory 14
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t Type;
|
||||||
|
uint64_t PhysicalStart;
|
||||||
|
uint64_t VirtualStart;
|
||||||
|
uint64_t NumberOfPages;
|
||||||
|
uint64_t Attribute;
|
||||||
|
} EFI_MEMORY_DESCRIPTOR;
|
||||||
|
|
||||||
|
// Graphics Output Protocol structures
|
||||||
|
typedef struct {
|
||||||
|
uint32_t RedMask;
|
||||||
|
uint32_t GreenMask;
|
||||||
|
uint32_t BlueMask;
|
||||||
|
uint32_t ReservedMask;
|
||||||
|
} EFI_PIXEL_BITMASK;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PixelRedGreenBlueReserved8BitPerColor,
|
||||||
|
PixelBlueGreenRedReserved8BitPerColor,
|
||||||
|
PixelBitMask,
|
||||||
|
PixelBltOnly,
|
||||||
|
PixelFormatMax
|
||||||
|
} EFI_GRAPHICS_PIXEL_FORMAT;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t Version;
|
||||||
|
uint32_t HorizontalResolution;
|
||||||
|
uint32_t VerticalResolution;
|
||||||
|
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
|
||||||
|
EFI_PIXEL_BITMASK PixelInformation;
|
||||||
|
uint32_t PixelsPerScanLine;
|
||||||
|
} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t MaxMode;
|
||||||
|
uint32_t Mode;
|
||||||
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* Info;
|
||||||
|
UINTN SizeOfInfo;
|
||||||
|
uint64_t FrameBufferBase;
|
||||||
|
UINTN FrameBufferSize;
|
||||||
|
} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
|
||||||
|
|
||||||
|
// Boot information passed to kernel
|
||||||
|
typedef struct {
|
||||||
|
uint64_t memory_map_size;
|
||||||
|
uint64_t memory_map_descriptor_size;
|
||||||
|
EFI_MEMORY_DESCRIPTOR* memory_map;
|
||||||
|
|
||||||
|
uint64_t framebuffer_base;
|
||||||
|
uint32_t framebuffer_width;
|
||||||
|
uint32_t framebuffer_height;
|
||||||
|
uint32_t framebuffer_pitch;
|
||||||
|
uint32_t framebuffer_bpp;
|
||||||
|
|
||||||
|
uint64_t kernel_base;
|
||||||
|
uint64_t kernel_size;
|
||||||
|
|
||||||
|
void* rsdp; // ACPI RSDP pointer
|
||||||
|
} BootInfo;
|
||||||
|
|
||||||
|
#endif // METALOS_BOOTLOADER_EFI_H
|
||||||
161
bootloader/src/main.c
Normal file
161
bootloader/src/main.c
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bootloader.h"
|
||||||
|
#include "efi.h"
|
||||||
|
|
||||||
|
// Simplified UEFI System Table structures (bare minimum)
|
||||||
|
// In a real implementation, we'd use gnu-efi or full UEFI headers
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t Signature;
|
||||||
|
uint32_t Revision;
|
||||||
|
uint32_t HeaderSize;
|
||||||
|
uint32_t CRC32;
|
||||||
|
uint32_t Reserved;
|
||||||
|
} EFI_TABLE_HEADER;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_TABLE_HEADER Hdr;
|
||||||
|
// Simplified - real implementation would have all console I/O functions
|
||||||
|
void* pad[10];
|
||||||
|
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_TABLE_HEADER Hdr;
|
||||||
|
CHAR16* FirmwareVendor;
|
||||||
|
uint32_t FirmwareRevision;
|
||||||
|
EFI_HANDLE ConsoleInHandle;
|
||||||
|
void* ConIn;
|
||||||
|
EFI_HANDLE ConsoleOutHandle;
|
||||||
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* ConOut;
|
||||||
|
EFI_HANDLE StandardErrorHandle;
|
||||||
|
void* StdErr;
|
||||||
|
void* RuntimeServices;
|
||||||
|
void* BootServices;
|
||||||
|
UINTN NumberOfTableEntries;
|
||||||
|
void* ConfigurationTable;
|
||||||
|
} EFI_SYSTEM_TABLE;
|
||||||
|
|
||||||
|
// Global system table
|
||||||
|
static EFI_SYSTEM_TABLE* gST = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a string to the UEFI console
|
||||||
|
*/
|
||||||
|
void print_string(const CHAR16* str) {
|
||||||
|
if (gST && gST->ConOut) {
|
||||||
|
// In real implementation: gST->ConOut->OutputString(gST->ConOut, (CHAR16*)str);
|
||||||
|
// For now, this is a stub
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print operation status
|
||||||
|
*/
|
||||||
|
void print_status(const CHAR16* operation, EFI_STATUS status) {
|
||||||
|
// Stub for status reporting
|
||||||
|
(void)operation;
|
||||||
|
(void)status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize graphics output protocol
|
||||||
|
*/
|
||||||
|
EFI_STATUS initialize_graphics(EFI_HANDLE ImageHandle) {
|
||||||
|
(void)ImageHandle;
|
||||||
|
|
||||||
|
// TODO: Implement graphics initialization
|
||||||
|
// 1. Locate Graphics Output Protocol
|
||||||
|
// 2. Query available modes
|
||||||
|
// 3. Select appropriate resolution (prefer 1920x1080 or 1280x720)
|
||||||
|
// 4. Set mode
|
||||||
|
// 5. Clear screen
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load kernel from disk
|
||||||
|
*/
|
||||||
|
EFI_STATUS load_kernel(EFI_HANDLE ImageHandle) {
|
||||||
|
(void)ImageHandle;
|
||||||
|
|
||||||
|
// TODO: Implement kernel loading
|
||||||
|
// 1. Open volume protocol
|
||||||
|
// 2. Open kernel file (metalos.bin)
|
||||||
|
// 3. Read kernel into memory at KERNEL_LOAD_ADDRESS
|
||||||
|
// 4. Verify kernel signature/checksum
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get ACPI RSDP (Root System Description Pointer)
|
||||||
|
*/
|
||||||
|
void* get_rsdp(void) {
|
||||||
|
// TODO: Search configuration tables for ACPI RSDP
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main entry point for bootloader
|
||||||
|
*/
|
||||||
|
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) {
|
||||||
|
EFI_STATUS status;
|
||||||
|
BootInfo boot_info = {0};
|
||||||
|
|
||||||
|
gST = SystemTable;
|
||||||
|
|
||||||
|
// Print banner
|
||||||
|
print_string(u"MetalOS Bootloader v0.1.0\r\n");
|
||||||
|
print_string(u"=========================\r\n\r\n");
|
||||||
|
|
||||||
|
// Initialize graphics
|
||||||
|
print_string(u"Initializing graphics...\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");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load kernel
|
||||||
|
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");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get ACPI information
|
||||||
|
print_string(u"Retrieving ACPI tables...\r\n");
|
||||||
|
boot_info.rsdp = get_rsdp();
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Jump to kernel
|
||||||
|
print_string(u"Starting kernel...\r\n");
|
||||||
|
|
||||||
|
// 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
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
38
bootloader/uefi.lds
Normal file
38
bootloader/uefi.lds
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* UEFI Linker Script */
|
||||||
|
OUTPUT_FORMAT("elf64-x86-64")
|
||||||
|
OUTPUT_ARCH(i386:x86-64)
|
||||||
|
ENTRY(efi_main)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0;
|
||||||
|
ImageBase = .;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic : {
|
||||||
|
*(.dynamic)
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynsym : {
|
||||||
|
*(.dynsym)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rel : {
|
||||||
|
*(.rel.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.reloc : {
|
||||||
|
*(.reloc)
|
||||||
|
}
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.comment)
|
||||||
|
}
|
||||||
|
}
|
||||||
167
docs/ARCHITECTURE.md
Normal file
167
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
# MetalOS Architecture
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
MetalOS is a ground-up operating system designed specifically to run QT6 applications on AMD64 hardware with UEFI boot and Radeon RX 6600 GPU support.
|
||||||
|
|
||||||
|
## Design Principles
|
||||||
|
|
||||||
|
1. **Minimal by Design**: Only implement what's necessary to run QT6 applications
|
||||||
|
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
|
||||||
|
|
||||||
|
## System Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ QT6 Hello World Application │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ QT6 Framework │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ User Space Runtime │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ System Call Interface │
|
||||||
|
├═════════════════════════════════════┤ ← Kernel Space
|
||||||
|
│ MetalOS Kernel │
|
||||||
|
│ ┌───────────┬──────────┬────────┐ │
|
||||||
|
│ │ Memory │ Scheduler│ I/O │ │
|
||||||
|
│ │ Mgr │ │ Mgr │ │
|
||||||
|
│ └───────────┴──────────┴────────┘ │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ Hardware Abstraction Layer │
|
||||||
|
│ ┌───────────┬──────────┬────────┐ │
|
||||||
|
│ │ GPU │ PCI │ Input │ │
|
||||||
|
│ │ Driver │ Bus │ Devices│ │
|
||||||
|
│ └───────────┴──────────┴────────┘ │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ UEFI Boot Services │
|
||||||
|
├─────────────────────────────────────┤
|
||||||
|
│ AMD64 Hardware │
|
||||||
|
│ (CPU + Radeon RX 6600 GPU) │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Components
|
||||||
|
|
||||||
|
### 1. UEFI Bootloader
|
||||||
|
- **Purpose**: Initialize hardware and load kernel
|
||||||
|
- **Language**: C with inline assembly
|
||||||
|
- **Responsibilities**:
|
||||||
|
- Set up memory map
|
||||||
|
- Initialize graphics framebuffer
|
||||||
|
- Load kernel into memory
|
||||||
|
- Transfer control to kernel
|
||||||
|
|
||||||
|
### 2. Kernel Core
|
||||||
|
- **Purpose**: Provide essential OS services
|
||||||
|
- **Language**: C/C++ with assembly for low-level operations
|
||||||
|
- **Subsystems**:
|
||||||
|
- Memory Management (physical/virtual)
|
||||||
|
- Process/Thread Scheduler
|
||||||
|
- Interrupt Handling
|
||||||
|
- System Call Interface
|
||||||
|
|
||||||
|
### 3. Hardware Abstraction Layer (HAL)
|
||||||
|
- **Purpose**: Abstract hardware specifics
|
||||||
|
- **Components**:
|
||||||
|
- PCI enumeration and configuration
|
||||||
|
- GPU driver (Radeon RX 6600 specific)
|
||||||
|
- Framebuffer management
|
||||||
|
- Input device drivers
|
||||||
|
|
||||||
|
### 4. User Space Runtime
|
||||||
|
- **Purpose**: Support the single QT6 application
|
||||||
|
- **Features**:
|
||||||
|
- Application loader (ELF format, static-linked)
|
||||||
|
- C/C++ standard library subset
|
||||||
|
- QT6 framework (statically linked into application)
|
||||||
|
- No shell, no command line - direct boot to app
|
||||||
|
|
||||||
|
## Memory Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
0x0000000000000000 - 0x0000000000000FFF : NULL guard page
|
||||||
|
0x0000000000001000 - 0x00000000000FFFFF : Bootloader code/data
|
||||||
|
0x0000000000100000 - 0x00000000FFFFFFFF : Kernel space
|
||||||
|
0x0000000100000000 - 0x00007FFFFFFFFFFF : User space
|
||||||
|
0xFFFF800000000000 - 0xFFFFFFFFFFFFFFFF : Kernel heap/stacks
|
||||||
|
```
|
||||||
|
|
||||||
|
## Boot Process
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
**Note**: No command line, no shell - the system boots directly into the single application.
|
||||||
|
|
||||||
|
## Development Phases
|
||||||
|
|
||||||
|
### Phase 1: Foundation (Current)
|
||||||
|
- Project structure
|
||||||
|
- Build system
|
||||||
|
- Basic documentation
|
||||||
|
- Minimal bootloader stub
|
||||||
|
|
||||||
|
### Phase 2: Kernel Basics
|
||||||
|
- Boot to kernel C code
|
||||||
|
- Basic console output
|
||||||
|
- Memory management
|
||||||
|
- Interrupt handling
|
||||||
|
|
||||||
|
### Phase 3: Hardware Support
|
||||||
|
- PCI enumeration
|
||||||
|
- Basic GPU initialization
|
||||||
|
- Framebuffer graphics
|
||||||
|
- Keyboard/mouse input
|
||||||
|
|
||||||
|
### Phase 4: User Space
|
||||||
|
- System call interface
|
||||||
|
- Process loading
|
||||||
|
- QT6 dependencies
|
||||||
|
- User space runtime
|
||||||
|
|
||||||
|
### Phase 5: QT6 Integration
|
||||||
|
- Port QT6 to MetalOS
|
||||||
|
- Build Hello World app
|
||||||
|
- Full screen rendering
|
||||||
|
- Final testing
|
||||||
|
|
||||||
|
## Technical Decisions
|
||||||
|
|
||||||
|
### Why UEFI?
|
||||||
|
- Modern standard for booting
|
||||||
|
- Better hardware discovery
|
||||||
|
- Graphics mode setup easier
|
||||||
|
- No legacy baggage
|
||||||
|
|
||||||
|
### Why C/C++?
|
||||||
|
- Direct hardware access
|
||||||
|
- Good toolchain support
|
||||||
|
- QT6 is C++ based
|
||||||
|
- Industry standard for OS development
|
||||||
|
|
||||||
|
### Why Radeon RX 6600 Specific?
|
||||||
|
- Define clear target for initial implementation
|
||||||
|
- Avoid generic driver complexity
|
||||||
|
- Can expand later if needed
|
||||||
|
|
||||||
|
### Why QT6?
|
||||||
|
- Modern cross-platform framework
|
||||||
|
- Good graphics support
|
||||||
|
- Active development
|
||||||
|
- Clear end goal
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- UEFI Specification 2.10
|
||||||
|
- AMD64 Architecture Programmer's Manual
|
||||||
|
- AMD Radeon GPU Documentation
|
||||||
|
- QT6 Documentation
|
||||||
|
- Linux Kernel (for driver inspiration)
|
||||||
189
docs/BUILD.md
Normal file
189
docs/BUILD.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# Building MetalOS
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Required Tools
|
||||||
|
|
||||||
|
1. **GNU Compiler Collection (GCC)**
|
||||||
|
- Cross-compiler for x86_64-elf target
|
||||||
|
- Version 11.0 or later recommended
|
||||||
|
|
||||||
|
2. **GNU Binutils**
|
||||||
|
- Cross-binutils for x86_64-elf target
|
||||||
|
- Includes ld, as, objcopy, etc.
|
||||||
|
|
||||||
|
3. **NASM**
|
||||||
|
- Netwide Assembler for x86_64
|
||||||
|
- Version 2.15 or later
|
||||||
|
|
||||||
|
4. **GNU Make**
|
||||||
|
- Build automation
|
||||||
|
- Version 4.0 or later
|
||||||
|
|
||||||
|
5. **QEMU** (for testing)
|
||||||
|
- QEMU system x86_64
|
||||||
|
- Version 6.0 or later with UEFI support
|
||||||
|
|
||||||
|
6. **EDK II OVMF**
|
||||||
|
- UEFI firmware for QEMU
|
||||||
|
- Required for UEFI boot testing
|
||||||
|
|
||||||
|
### Installing Prerequisites on Ubuntu/Debian
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install basic build tools
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y build-essential nasm qemu-system-x86 ovmf mtools xorriso
|
||||||
|
|
||||||
|
# Install cross-compiler prerequisites
|
||||||
|
sudo apt-get install -y libgmp-dev libmpfr-dev libmpc-dev texinfo
|
||||||
|
|
||||||
|
# Note: You may need to build the cross-compiler manually
|
||||||
|
# See docs/CROSS_COMPILER.md for instructions
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installing Prerequisites on Arch Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pacman -S base-devel nasm qemu-full edk2-ovmf mtools xorriso
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installing Prerequisites on macOS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew install nasm qemu x86_64-elf-gcc x86_64-elf-binutils
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building the Bootloader
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
cd bootloader
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
This produces `bootloader/bootx64.efi` - the UEFI bootloader.
|
||||||
|
|
||||||
|
## Building the Kernel
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
cd kernel
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
This produces `kernel/metalos.bin` - the kernel binary.
|
||||||
|
|
||||||
|
## Creating Bootable Image
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
make image
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates `build/metalos.img` - a bootable disk image containing:
|
||||||
|
- EFI System Partition with bootloader
|
||||||
|
- Kernel binary
|
||||||
|
- Any required data files
|
||||||
|
|
||||||
|
## Testing in QEMU
|
||||||
|
|
||||||
|
### Boot MetalOS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
### Boot with Debug Output
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make qemu-debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Boot with GDB Support
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 1
|
||||||
|
make qemu-gdb
|
||||||
|
|
||||||
|
# Terminal 2
|
||||||
|
gdb kernel/metalos.bin
|
||||||
|
(gdb) target remote localhost:1234
|
||||||
|
(gdb) continue
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing on Real Hardware
|
||||||
|
|
||||||
|
⚠️ **WARNING**: Testing on real hardware can be risky. Always backup your data.
|
||||||
|
|
||||||
|
### USB Boot Drive Creation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create bootable USB (replace /dev/sdX with your USB device)
|
||||||
|
sudo dd if=build/metalos.img of=/dev/sdX bs=4M status=progress
|
||||||
|
sync
|
||||||
|
```
|
||||||
|
|
||||||
|
### Requirements for Hardware Testing
|
||||||
|
- AMD64 system with UEFI firmware
|
||||||
|
- Radeon RX 6600 GPU (for full functionality)
|
||||||
|
- USB drive (1GB or larger)
|
||||||
|
- Ability to boot from USB in UEFI mode
|
||||||
|
|
||||||
|
## Build Configuration
|
||||||
|
|
||||||
|
Build options can be configured in `config.mk`:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
# Debug build (includes symbols, verbose output)
|
||||||
|
DEBUG ?= 1
|
||||||
|
|
||||||
|
# Optimization level (0, 1, 2, 3, s)
|
||||||
|
OPT_LEVEL ?= 2
|
||||||
|
|
||||||
|
# Target architecture
|
||||||
|
ARCH ?= x86_64
|
||||||
|
|
||||||
|
# Enable specific features
|
||||||
|
ENABLE_LOGGING ?= 1
|
||||||
|
ENABLE_SERIAL ?= 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Clean Builds
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clean all build artifacts
|
||||||
|
make clean
|
||||||
|
|
||||||
|
# Clean everything including dependencies
|
||||||
|
make distclean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Cross-Compiler Not Found
|
||||||
|
If you get errors about missing cross-compiler:
|
||||||
|
1. Check that x86_64-elf-gcc is in your PATH
|
||||||
|
2. See `docs/CROSS_COMPILER.md` for building instructions
|
||||||
|
|
||||||
|
### QEMU UEFI Firmware Missing
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install ovmf
|
||||||
|
|
||||||
|
# Arch
|
||||||
|
sudo pacman -S edk2-ovmf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Fails with "Permission Denied"
|
||||||
|
```bash
|
||||||
|
# Make sure scripts are executable
|
||||||
|
chmod +x scripts/*.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
After successful build:
|
||||||
|
1. Review `docs/ARCHITECTURE.md` for system design
|
||||||
|
2. See `docs/DEVELOPMENT.md` for development workflow
|
||||||
|
3. Check `docs/DEBUGGING.md` for debugging techniques
|
||||||
272
docs/COMPONENTS.md
Normal file
272
docs/COMPONENTS.md
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
# MetalOS - Planned Components
|
||||||
|
|
||||||
|
This document outlines the key components that need to be implemented.
|
||||||
|
|
||||||
|
## Bootloader Components
|
||||||
|
|
||||||
|
### Implemented
|
||||||
|
- [x] Basic structure
|
||||||
|
- [x] EFI types and definitions
|
||||||
|
- [x] Entry point stub
|
||||||
|
|
||||||
|
### TODO
|
||||||
|
- [ ] UEFI protocol implementations
|
||||||
|
- [ ] Console I/O (OutputString, etc.)
|
||||||
|
- [ ] Graphics Output Protocol
|
||||||
|
- [ ] Simple File System Protocol
|
||||||
|
- [ ] Memory allocation
|
||||||
|
- [ ] Graphics initialization
|
||||||
|
- [ ] Mode enumeration
|
||||||
|
- [ ] Mode selection
|
||||||
|
- [ ] Framebuffer setup
|
||||||
|
- [ ] Kernel loading from disk
|
||||||
|
- [ ] Memory map retrieval
|
||||||
|
- [ ] Exit boot services
|
||||||
|
- [ ] Jump to kernel with boot info
|
||||||
|
|
||||||
|
## Kernel Components
|
||||||
|
|
||||||
|
### Core Kernel
|
||||||
|
|
||||||
|
#### Implemented
|
||||||
|
- [x] Entry point
|
||||||
|
- [x] Basic console output to framebuffer
|
||||||
|
- [x] Boot info structure
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] GDT (Global Descriptor Table) setup
|
||||||
|
- [ ] IDT (Interrupt Descriptor Table) setup
|
||||||
|
- [ ] Interrupt handlers (ISRs)
|
||||||
|
- [ ] Exception handlers
|
||||||
|
- [ ] Timer interrupt (for scheduling)
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Physical memory allocator
|
||||||
|
- [ ] Parse UEFI memory map
|
||||||
|
- [ ] Bitmap or buddy allocator
|
||||||
|
- [ ] Page allocation (4KB pages)
|
||||||
|
- [ ] Virtual memory
|
||||||
|
- [ ] Page table setup (4-level paging)
|
||||||
|
- [ ] Kernel space mapping
|
||||||
|
- [ ] User space mapping
|
||||||
|
- [ ] Heap allocator
|
||||||
|
- [ ] Simple malloc/free
|
||||||
|
- [ ] For kernel use
|
||||||
|
|
||||||
|
### Process Management
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Process structure
|
||||||
|
- [ ] Thread structure
|
||||||
|
- [ ] Context switching
|
||||||
|
- [ ] Save/restore CPU state
|
||||||
|
- [ ] Stack switching
|
||||||
|
- [ ] Simple scheduler
|
||||||
|
- [ ] Round-robin
|
||||||
|
- [ ] Single user process initially
|
||||||
|
- [ ] User/kernel mode transitions
|
||||||
|
|
||||||
|
### System Calls
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] System call mechanism (syscall/sysret)
|
||||||
|
- [ ] System call table
|
||||||
|
- [ ] Essential syscalls:
|
||||||
|
- [ ] exit()
|
||||||
|
- [ ] write() - for debugging
|
||||||
|
- [ ] mmap() - memory allocation
|
||||||
|
- [ ] ioctl() - device control
|
||||||
|
- [ ] poll() - wait for events
|
||||||
|
|
||||||
|
## Hardware Abstraction Layer (HAL)
|
||||||
|
|
||||||
|
### PCI Bus
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] PCI configuration space access
|
||||||
|
- [ ] Device enumeration
|
||||||
|
- [ ] Find GPU (vendor 0x1002, device ID for RX 6600)
|
||||||
|
- [ ] BAR (Base Address Register) reading
|
||||||
|
- [ ] Enable memory and I/O access
|
||||||
|
|
||||||
|
### GPU Driver (Radeon RX 6600)
|
||||||
|
|
||||||
|
This needs to be precise - based on actual AMD GPU specs.
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] GPU identification
|
||||||
|
- [ ] Check PCI vendor/device ID
|
||||||
|
- [ ] Verify it's RX 6600 (Navi 23)
|
||||||
|
- [ ] Basic initialization
|
||||||
|
- [ ] Map MMIO registers
|
||||||
|
- [ ] Reset GPU if needed
|
||||||
|
- [ ] Initialize display engine
|
||||||
|
- [ ] Display pipeline setup
|
||||||
|
- [ ] Configure CRTC (display controller)
|
||||||
|
- [ ] Set up display timing
|
||||||
|
- [ ] Configure framebuffer
|
||||||
|
- [ ] Enable output
|
||||||
|
- [ ] Framebuffer management
|
||||||
|
- [ ] Allocate VRAM for framebuffer
|
||||||
|
- [ ] Map to CPU address space
|
||||||
|
- [ ] Set up for blitting
|
||||||
|
|
||||||
|
**Note**: This is the most complex part. Will need to reference:
|
||||||
|
- Linux amdgpu driver
|
||||||
|
- AMD register specifications
|
||||||
|
- Display Controller (DCN) documentation
|
||||||
|
|
||||||
|
### Input Devices
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] USB Stack (minimal)
|
||||||
|
- [ ] XHCI controller initialization
|
||||||
|
- [ ] USB device enumeration
|
||||||
|
- [ ] HID class driver
|
||||||
|
- [ ] Keyboard driver
|
||||||
|
- [ ] USB HID keyboard
|
||||||
|
- [ ] Key code translation
|
||||||
|
- [ ] Event generation for QT
|
||||||
|
- [ ] Mouse driver
|
||||||
|
- [ ] USB HID mouse
|
||||||
|
- [ ] Movement/button tracking
|
||||||
|
- [ ] Event generation for QT
|
||||||
|
|
||||||
|
### Timer
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] APIC timer or PIT
|
||||||
|
- [ ] Timer interrupt setup
|
||||||
|
- [ ] Time tracking for scheduler
|
||||||
|
|
||||||
|
## User Space
|
||||||
|
|
||||||
|
### Runtime
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] ELF loader
|
||||||
|
- [ ] Parse ELF64 headers
|
||||||
|
- [ ] Load program segments
|
||||||
|
- [ ] Set up entry point
|
||||||
|
- [ ] C runtime
|
||||||
|
- [ ] _start function
|
||||||
|
- [ ] Call constructors
|
||||||
|
- [ ] Call main()
|
||||||
|
- [ ] Call destructors
|
||||||
|
- [ ] C++ runtime
|
||||||
|
- [ ] Global constructors
|
||||||
|
- [ ] Global destructors
|
||||||
|
- [ ] Exception handling (minimal or disabled)
|
||||||
|
- [ ] Standard library subset
|
||||||
|
- [ ] malloc/free
|
||||||
|
- [ ] memcpy/memset/memcmp
|
||||||
|
- [ ] String functions
|
||||||
|
- [ ] Basic I/O
|
||||||
|
|
||||||
|
### Application Launcher (No Init Needed)
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Direct kernel boot into application
|
||||||
|
- [ ] Load QT6 hello world as only user process
|
||||||
|
- [ ] No shell, no command line
|
||||||
|
- [ ] Handle application exit (just halt or reboot)
|
||||||
|
|
||||||
|
## QT6 Port
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Identify minimal QT6 dependencies
|
||||||
|
- [ ] Port/stub required libraries:
|
||||||
|
- [ ] zlib
|
||||||
|
- [ ] libpng
|
||||||
|
- [ ] freetype (fonts)
|
||||||
|
- [ ] Others as discovered
|
||||||
|
|
||||||
|
### QT Platform Abstraction (QPA)
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Create MetalOS QPA plugin
|
||||||
|
- [ ] Implement platform integration
|
||||||
|
- [ ] Window system integration (full screen)
|
||||||
|
- [ ] Event dispatcher
|
||||||
|
- [ ] Backingstore (framebuffer backing)
|
||||||
|
- [ ] Graphics backend
|
||||||
|
- [ ] Raster rendering to framebuffer
|
||||||
|
- [ ] Optionally: GPU acceleration
|
||||||
|
- [ ] Input integration
|
||||||
|
- [ ] Keyboard events
|
||||||
|
- [ ] Mouse events
|
||||||
|
- [ ] Event queue
|
||||||
|
- [ ] Font backend
|
||||||
|
- [ ] Basic font rendering
|
||||||
|
- [ ] Use embedded font or simple bitmap
|
||||||
|
|
||||||
|
### QT Build
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Configure QT6 for MetalOS target
|
||||||
|
- [ ] Disable unnecessary modules
|
||||||
|
- [ ] Enable: QtCore, QtGui, QtWidgets only
|
||||||
|
- [ ] Cross-compile for MetalOS
|
||||||
|
- [ ] Static linking
|
||||||
|
|
||||||
|
## Applications
|
||||||
|
|
||||||
|
### Hello World
|
||||||
|
|
||||||
|
#### Implemented
|
||||||
|
- [x] Basic QT6 hello world source code
|
||||||
|
- [x] .pro file
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Build for MetalOS
|
||||||
|
- [ ] Static link with QT6
|
||||||
|
- [ ] Test rendering
|
||||||
|
- [ ] Test input handling
|
||||||
|
- [ ] Package into bootable image
|
||||||
|
|
||||||
|
## Build System
|
||||||
|
|
||||||
|
#### Implemented
|
||||||
|
- [x] Basic Makefiles
|
||||||
|
- [x] Directory structure
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Cross-compiler setup scripts
|
||||||
|
- [ ] Image creation script
|
||||||
|
- [ ] Create GPT disk image
|
||||||
|
- [ ] Format EFI System Partition
|
||||||
|
- [ ] Copy bootloader and kernel
|
||||||
|
- [ ] Automated testing in QEMU
|
||||||
|
- [ ] CI/CD pipeline (optional)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
#### Implemented
|
||||||
|
- [x] README.md
|
||||||
|
- [x] ARCHITECTURE.md
|
||||||
|
- [x] BUILD.md
|
||||||
|
- [x] DEVELOPMENT.md
|
||||||
|
- [x] ROADMAP.md
|
||||||
|
- [x] CONTRIBUTING.md
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] API documentation
|
||||||
|
- [ ] Driver development guide
|
||||||
|
- [ ] Troubleshooting guide
|
||||||
|
- [ ] Performance tuning guide
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
#### TODO
|
||||||
|
- [ ] Unit tests for key components
|
||||||
|
- [ ] Integration tests
|
||||||
|
- [ ] QEMU boot tests
|
||||||
|
- [ ] Hardware test checklist
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This is a living document - components will be checked off as implemented.
|
||||||
272
docs/DEVELOPMENT.md
Normal file
272
docs/DEVELOPMENT.md
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
# MetalOS Development Guide
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
MetalOS/
|
||||||
|
├── bootloader/ # UEFI bootloader code
|
||||||
|
│ ├── src/ # Bootloader source
|
||||||
|
│ ├── include/ # Bootloader headers
|
||||||
|
│ └── Makefile # Bootloader build
|
||||||
|
├── kernel/ # MetalOS kernel
|
||||||
|
│ ├── src/ # Kernel source
|
||||||
|
│ │ ├── core/ # Core kernel (memory, scheduler)
|
||||||
|
│ │ ├── hal/ # Hardware abstraction layer
|
||||||
|
│ │ ├── drivers/ # Device drivers
|
||||||
|
│ │ └── syscall/ # System call interface
|
||||||
|
│ ├── include/ # Kernel headers
|
||||||
|
│ └── Makefile # Kernel build
|
||||||
|
├── userspace/ # User space components
|
||||||
|
│ ├── runtime/ # C/C++ runtime
|
||||||
|
│ ├── init/ # Init process
|
||||||
|
│ └── apps/ # Applications (QT6 hello world)
|
||||||
|
├── drivers/ # Additional drivers
|
||||||
|
│ ├── gpu/ # GPU drivers (Radeon RX 6600)
|
||||||
|
│ ├── input/ # Input device drivers
|
||||||
|
│ └── pci/ # PCI bus drivers
|
||||||
|
├── docs/ # Documentation
|
||||||
|
├── scripts/ # Build and utility scripts
|
||||||
|
├── tests/ # Test suite
|
||||||
|
└── tools/ # Development tools
|
||||||
|
```
|
||||||
|
|
||||||
|
## Coding Standards
|
||||||
|
|
||||||
|
### C/C++ Style
|
||||||
|
|
||||||
|
- **Indentation**: 4 spaces, no tabs
|
||||||
|
- **Naming**:
|
||||||
|
- Functions: `snake_case`
|
||||||
|
- Types: `PascalCase`
|
||||||
|
- Constants: `UPPER_SNAKE_CASE`
|
||||||
|
- Variables: `snake_case`
|
||||||
|
- **Comments**: Use `//` for single-line, `/* */` for multi-line
|
||||||
|
- **Headers**: Include guards with `METALOS_<PATH>_<FILE>_H`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```c
|
||||||
|
#ifndef METALOS_KERNEL_MEMORY_H
|
||||||
|
#define METALOS_KERNEL_MEMORY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define KERNEL_BASE 0xFFFF800000000000
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t physical_addr;
|
||||||
|
uint64_t virtual_addr;
|
||||||
|
uint64_t size;
|
||||||
|
} MemoryRegion;
|
||||||
|
|
||||||
|
// Initialize memory management subsystem
|
||||||
|
int memory_init(void);
|
||||||
|
|
||||||
|
// Allocate physical page
|
||||||
|
void* allocate_page(void);
|
||||||
|
|
||||||
|
#endif // METALOS_KERNEL_MEMORY_H
|
||||||
|
```
|
||||||
|
|
||||||
|
### Assembly Style
|
||||||
|
|
||||||
|
- **Syntax**: Intel syntax preferred
|
||||||
|
- **Comments**: Explain non-obvious operations
|
||||||
|
- **Labels**: Descriptive names
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```nasm
|
||||||
|
; Set up initial GDT
|
||||||
|
setup_gdt:
|
||||||
|
mov rax, gdt_pointer
|
||||||
|
lgdt [rax]
|
||||||
|
ret
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### 1. Create Feature Branch
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/my-feature
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Make Changes
|
||||||
|
- Follow coding standards
|
||||||
|
- Add comments for complex logic
|
||||||
|
- Update documentation
|
||||||
|
|
||||||
|
### 3. Build and Test
|
||||||
|
```bash
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Commit Changes
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "Add feature: description"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Submit Pull Request
|
||||||
|
- Describe changes clearly
|
||||||
|
- Reference any related issues
|
||||||
|
- Ensure CI passes
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
### Serial Console Output
|
||||||
|
|
||||||
|
Add serial debugging output:
|
||||||
|
```c
|
||||||
|
#include <kernel/serial.h>
|
||||||
|
|
||||||
|
void my_function(void) {
|
||||||
|
serial_printf("Debug: value=%d\n", some_value);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### QEMU Monitor
|
||||||
|
|
||||||
|
Access QEMU monitor during execution:
|
||||||
|
- Press `Ctrl+Alt+2` to switch to monitor
|
||||||
|
- Press `Ctrl+Alt+1` to return to guest
|
||||||
|
- Use `info registers` to inspect CPU state
|
||||||
|
|
||||||
|
### GDB Debugging
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 1: Start QEMU with GDB
|
||||||
|
make qemu-gdb
|
||||||
|
|
||||||
|
# Terminal 2: Connect GDB
|
||||||
|
gdb kernel/metalos.bin
|
||||||
|
(gdb) target remote localhost:1234
|
||||||
|
(gdb) break kernel_main
|
||||||
|
(gdb) continue
|
||||||
|
```
|
||||||
|
|
||||||
|
Useful GDB commands:
|
||||||
|
- `break <function>` - Set breakpoint
|
||||||
|
- `continue` - Resume execution
|
||||||
|
- `step` - Step one instruction
|
||||||
|
- `next` - Step over function
|
||||||
|
- `info registers` - Show CPU registers
|
||||||
|
- `x/10x <addr>` - Examine memory
|
||||||
|
- `backtrace` - Show call stack
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
|
||||||
|
Run kernel unit tests:
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
|
||||||
|
Test full system boot:
|
||||||
|
```bash
|
||||||
|
make test-integration
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hardware Tests
|
||||||
|
|
||||||
|
Test on real hardware (advanced):
|
||||||
|
```bash
|
||||||
|
make usb-image
|
||||||
|
# Then boot from USB on test machine
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Tasks
|
||||||
|
|
||||||
|
### Adding a New Driver
|
||||||
|
|
||||||
|
1. Create driver file: `kernel/src/drivers/mydriver.c`
|
||||||
|
2. Create header: `kernel/include/drivers/mydriver.h`
|
||||||
|
3. Add to build: Edit `kernel/Makefile`
|
||||||
|
4. Initialize in kernel: Call from `kernel_main()`
|
||||||
|
|
||||||
|
### Adding System Call
|
||||||
|
|
||||||
|
1. Define syscall: `kernel/include/syscall/syscall.h`
|
||||||
|
2. Implement handler: `kernel/src/syscall/handlers.c`
|
||||||
|
3. Add to syscall table: `kernel/src/syscall/table.c`
|
||||||
|
4. Update userspace wrapper: `userspace/runtime/syscall.c`
|
||||||
|
|
||||||
|
### Modifying Memory Layout
|
||||||
|
|
||||||
|
1. Update linker script: `kernel/linker.ld`
|
||||||
|
2. Update memory map: `kernel/src/core/memory.c`
|
||||||
|
3. Update documentation: `docs/ARCHITECTURE.md`
|
||||||
|
|
||||||
|
## Performance Profiling
|
||||||
|
|
||||||
|
### Boot Time Analysis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable boot time logging
|
||||||
|
make DEBUG=1 ENABLE_BOOTTIME=1
|
||||||
|
make qemu
|
||||||
|
# Check serial output for timing information
|
||||||
|
```
|
||||||
|
|
||||||
|
### CPU Profiling
|
||||||
|
|
||||||
|
Use QEMU's built-in profiling:
|
||||||
|
```bash
|
||||||
|
qemu-system-x86_64 -enable-kvm -cpu host \
|
||||||
|
-d cpu_reset -D qemu.log \
|
||||||
|
-drive file=build/metalos.img,format=raw
|
||||||
|
```
|
||||||
|
|
||||||
|
## Continuous Integration
|
||||||
|
|
||||||
|
Our CI pipeline:
|
||||||
|
1. **Build Check**: Ensure code compiles
|
||||||
|
2. **Unit Tests**: Run test suite
|
||||||
|
3. **Boot Test**: Verify kernel boots in QEMU
|
||||||
|
4. **Code Style**: Check formatting
|
||||||
|
5. **Documentation**: Verify docs build
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
### Specifications
|
||||||
|
- [UEFI 2.10 Specification](https://uefi.org/specifications)
|
||||||
|
- [AMD64 Programmer's Manual](https://www.amd.com/en/support/tech-docs)
|
||||||
|
- [Intel SDM](https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html)
|
||||||
|
|
||||||
|
### OS Development
|
||||||
|
- [OSDev Wiki](https://wiki.osdev.org/)
|
||||||
|
- [Linux Kernel Source](https://kernel.org/) (for reference)
|
||||||
|
- [SerenityOS](https://github.com/SerenityOS/serenity) (good example)
|
||||||
|
|
||||||
|
### Graphics/GPU
|
||||||
|
- [AMD GPU Documentation](https://www.amd.com/en/support/kb/release-notes/rn-rad-win-crimson-16-12-1)
|
||||||
|
- [Linux DRM/KMS](https://dri.freedesktop.org/wiki/)
|
||||||
|
|
||||||
|
### QT6
|
||||||
|
- [QT6 Documentation](https://doc.qt.io/qt-6/)
|
||||||
|
- [QT Platform Abstraction](https://doc.qt.io/qt-6/qpa.html)
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
- **Documentation**: Check `docs/` directory
|
||||||
|
- **Issues**: Search existing GitHub issues
|
||||||
|
- **Discussions**: Use GitHub Discussions for questions
|
||||||
|
- **IRC**: #metalos on libera.chat (planned)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
We welcome contributions! Please:
|
||||||
|
1. Follow the coding standards
|
||||||
|
2. Write clear commit messages
|
||||||
|
3. Add tests for new features
|
||||||
|
4. Update documentation
|
||||||
|
5. Be respectful and constructive
|
||||||
|
|
||||||
|
See `CONTRIBUTING.md` for detailed guidelines.
|
||||||
346
docs/ROADMAP.md
Normal file
346
docs/ROADMAP.md
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
# MetalOS Roadmap
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
This is not a general-purpose OS. Every component is purpose-built to achieve this specific goal with minimal complexity.
|
||||||
|
|
||||||
|
## Development Phases
|
||||||
|
|
||||||
|
### Phase 1: Foundation ✓ (Current)
|
||||||
|
|
||||||
|
**Goal**: Establish project structure and documentation
|
||||||
|
|
||||||
|
- [x] Create project directory structure
|
||||||
|
- [x] Write architecture documentation
|
||||||
|
- [x] Define build system
|
||||||
|
- [x] Create bootloader skeleton
|
||||||
|
- [x] Create kernel skeleton
|
||||||
|
- [x] Create QT6 hello world application template
|
||||||
|
- [x] Document development workflow
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Project structure in place
|
||||||
|
- Documentation framework
|
||||||
|
- Skeleton code for bootloader and kernel
|
||||||
|
- Build system (Makefiles)
|
||||||
|
|
||||||
|
### Phase 2: UEFI Bootloader (Next)
|
||||||
|
|
||||||
|
**Goal**: Boot from UEFI and load kernel
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. Implement UEFI protocol interfaces
|
||||||
|
- Console I/O for early debugging
|
||||||
|
- Graphics Output Protocol
|
||||||
|
- Simple File System Protocol
|
||||||
|
- Memory allocation
|
||||||
|
|
||||||
|
2. Graphics initialization
|
||||||
|
- Query available video modes
|
||||||
|
- Set optimal resolution (1920x1080 or best available)
|
||||||
|
- Set up framebuffer
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
### Phase 3: Minimal Kernel
|
||||||
|
|
||||||
|
**Goal**: Initialize hardware and provide basic services
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. Early kernel initialization
|
||||||
|
- Set up GDT (Global Descriptor Table)
|
||||||
|
- Set up IDT (Interrupt Descriptor Table)
|
||||||
|
- Enable interrupts
|
||||||
|
- Initialize framebuffer console
|
||||||
|
|
||||||
|
2. Memory management
|
||||||
|
- Physical memory allocator (buddy system or bitmap)
|
||||||
|
- Virtual memory setup (page tables)
|
||||||
|
- Kernel heap allocator
|
||||||
|
- *Minimal implementation - just enough for QT6*
|
||||||
|
|
||||||
|
3. Process/Thread support
|
||||||
|
- Simple round-robin scheduler
|
||||||
|
- Context switching (bare minimum)
|
||||||
|
- Single user process support
|
||||||
|
- *No multi-user, no fancy scheduling*
|
||||||
|
|
||||||
|
4. Basic I/O
|
||||||
|
- Serial port for debugging
|
||||||
|
- Framebuffer console
|
||||||
|
- *No disk I/O needed initially*
|
||||||
|
|
||||||
|
**Success Criteria**: Kernel boots, prints messages, can allocate memory
|
||||||
|
|
||||||
|
### Phase 4: Hardware Abstraction Layer
|
||||||
|
|
||||||
|
**Goal**: Support minimal hardware needed for QT6
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. PCI Bus enumeration
|
||||||
|
- Scan PCI devices
|
||||||
|
- Find Radeon RX 6600 GPU
|
||||||
|
- Basic configuration
|
||||||
|
|
||||||
|
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*
|
||||||
|
|
||||||
|
3. Input devices
|
||||||
|
- USB HID keyboard support
|
||||||
|
- USB HID mouse support
|
||||||
|
- PS/2 fallback (if needed)
|
||||||
|
- *Just enough for QT event handling*
|
||||||
|
|
||||||
|
4. Timer
|
||||||
|
- APIC timer or PIT
|
||||||
|
- For scheduling and timeouts
|
||||||
|
|
||||||
|
**Success Criteria**: Can detect and initialize GPU, receive keyboard/mouse input
|
||||||
|
|
||||||
|
### Phase 5: System Call Interface
|
||||||
|
|
||||||
|
**Goal**: Provide user-kernel boundary
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. System call mechanism
|
||||||
|
- syscall/sysret instructions
|
||||||
|
- System call table
|
||||||
|
- Parameter passing
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
3. User-kernel transitions
|
||||||
|
- Ring 3 to Ring 0 transitions
|
||||||
|
- Parameter validation
|
||||||
|
- Error handling
|
||||||
|
|
||||||
|
**Success Criteria**: User space can make system calls
|
||||||
|
|
||||||
|
### Phase 6: User Space Runtime
|
||||||
|
|
||||||
|
**Goal**: Support C++ applications
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. ELF loader
|
||||||
|
- Parse ELF headers
|
||||||
|
- Load program segments
|
||||||
|
- Set up entry point
|
||||||
|
- *Static linking initially - no dynamic loader*
|
||||||
|
|
||||||
|
2. Minimal C/C++ runtime
|
||||||
|
- _start() function
|
||||||
|
- C++ global constructors/destructors
|
||||||
|
- Memory allocation (malloc/free)
|
||||||
|
- Basic string functions
|
||||||
|
- *Only what QT6 needs*
|
||||||
|
|
||||||
|
3. Application launcher (no init/shell needed)
|
||||||
|
- Directly load QT6 hello world application
|
||||||
|
- No command line, no shell
|
||||||
|
- Single application until reboot
|
||||||
|
|
||||||
|
**Success Criteria**: Can load and run the QT6 hello world application directly
|
||||||
|
|
||||||
|
### Phase 7: QT6 Port
|
||||||
|
|
||||||
|
**Goal**: Port QT6 to MetalOS
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. QT6 dependencies
|
||||||
|
- Port minimal C++ standard library
|
||||||
|
- Port required libraries (zlib, png, freetype, etc.)
|
||||||
|
- *Only what QT6 absolutely needs*
|
||||||
|
|
||||||
|
2. QT Platform Abstraction (QPA) Plugin
|
||||||
|
- MetalOS platform plugin
|
||||||
|
- Framebuffer graphics backend
|
||||||
|
- Input event integration
|
||||||
|
- Event loop integration with kernel
|
||||||
|
|
||||||
|
3. Build QT6 for MetalOS
|
||||||
|
- Configure QT6 build system
|
||||||
|
- Cross-compile QT6
|
||||||
|
- Strip unnecessary modules
|
||||||
|
- *QtCore, QtGui, QtWidgets only*
|
||||||
|
|
||||||
|
4. Test infrastructure
|
||||||
|
- Simple QT apps for testing
|
||||||
|
- Verify widgets render
|
||||||
|
- Verify input works
|
||||||
|
|
||||||
|
**Success Criteria**: Simple QT6 applications can run
|
||||||
|
|
||||||
|
### Phase 8: Integration & Polish
|
||||||
|
|
||||||
|
**Goal**: Get Hello World running perfectly
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
1. Build hello world application
|
||||||
|
- Compile against MetalOS QT6
|
||||||
|
- Static link everything
|
||||||
|
- Create bootable image
|
||||||
|
|
||||||
|
2. Full-screen rendering
|
||||||
|
- Ensure application fills screen
|
||||||
|
- Proper resolution handling
|
||||||
|
- Clean graphics output
|
||||||
|
|
||||||
|
3. Input handling
|
||||||
|
- Keyboard input works
|
||||||
|
- Mouse input works (if used by app)
|
||||||
|
- Clean event handling
|
||||||
|
|
||||||
|
4. Performance tuning
|
||||||
|
- Optimize critical paths
|
||||||
|
- Reduce boot time
|
||||||
|
- Smooth rendering
|
||||||
|
|
||||||
|
5. Testing
|
||||||
|
- Test on QEMU
|
||||||
|
- Test on real hardware (AMD64 + RX 6600)
|
||||||
|
- Fix any hardware-specific issues
|
||||||
|
|
||||||
|
**Success Criteria**: QT6 Hello World runs full-screen on target hardware
|
||||||
|
|
||||||
|
## Timeline Estimates
|
||||||
|
|
||||||
|
*These are rough estimates for a single developer*
|
||||||
|
|
||||||
|
- Phase 1: 1 week ✓ (Complete)
|
||||||
|
- Phase 2: 2-3 weeks
|
||||||
|
- Phase 3: 3-4 weeks
|
||||||
|
- Phase 4: 4-6 weeks
|
||||||
|
- Phase 5: 1-2 weeks
|
||||||
|
- Phase 6: 2-3 weeks
|
||||||
|
- Phase 7: 6-8 weeks
|
||||||
|
- Phase 8: 2-3 weeks
|
||||||
|
|
||||||
|
**Total**: ~4-6 months of focused development
|
||||||
|
|
||||||
|
## Technical Challenges
|
||||||
|
|
||||||
|
### Major Challenges
|
||||||
|
|
||||||
|
1. **GPU Initialization**: Radeon RX 6600 is a modern GPU with complex initialization. May need to study Linux amdgpu driver extensively.
|
||||||
|
|
||||||
|
2. **QT6 Dependencies**: QT6 has many dependencies. Need to port or stub out non-essential ones.
|
||||||
|
|
||||||
|
3. **QPA Plugin**: Creating a QT Platform Abstraction plugin from scratch is non-trivial.
|
||||||
|
|
||||||
|
4. **Memory Management**: Need working virtual memory before user space.
|
||||||
|
|
||||||
|
5. **USB Stack**: If using USB input, need minimal USB stack (XHCI for modern systems).
|
||||||
|
|
||||||
|
### Risk Mitigation
|
||||||
|
|
||||||
|
- Start with serial/VGA console before GPU
|
||||||
|
- Use PS/2 input before USB if easier
|
||||||
|
- Test incrementally in QEMU before hardware
|
||||||
|
- Study existing minimal OS implementations
|
||||||
|
- Reference Linux kernel code (but don't copy)
|
||||||
|
|
||||||
|
## Success Metrics
|
||||||
|
|
||||||
|
### Minimal Success
|
||||||
|
- Boots on target hardware
|
||||||
|
- Displays something via GPU
|
||||||
|
- Can be interacted with via keyboard
|
||||||
|
- QT6 hello world shows text
|
||||||
|
|
||||||
|
### Full Success
|
||||||
|
- Boots reliably on AMD64 + RX 6600
|
||||||
|
- Full screen 1920x1080 rendering
|
||||||
|
- Clean QT6 widget rendering
|
||||||
|
- Responsive input handling
|
||||||
|
- Boot time < 10 seconds
|
||||||
|
|
||||||
|
## Resources Needed
|
||||||
|
|
||||||
|
### Hardware
|
||||||
|
- AMD64 system with Radeon RX 6600 GPU
|
||||||
|
- USB keyboard and mouse
|
||||||
|
- Serial port (optional, for debugging)
|
||||||
|
|
||||||
|
### Software
|
||||||
|
- Cross-compiler toolchain (x86_64-elf-gcc)
|
||||||
|
- QEMU with UEFI support
|
||||||
|
- GDB for debugging
|
||||||
|
- QT6 source code
|
||||||
|
|
||||||
|
### Knowledge
|
||||||
|
- UEFI specification
|
||||||
|
- x86_64 architecture
|
||||||
|
- PCI/PCIe protocol
|
||||||
|
- AMD GPU documentation
|
||||||
|
- QT6 architecture
|
||||||
|
- OS development fundamentals
|
||||||
|
|
||||||
|
## Design Decisions
|
||||||
|
|
||||||
|
1. **File System**: ❌ Not needed
|
||||||
|
- Application embedded in boot image or loaded by bootloader
|
||||||
|
- Everything in RAM
|
||||||
|
|
||||||
|
2. **Command Line / Shell**: ❌ Not needed
|
||||||
|
- Boot directly into QT6 application
|
||||||
|
- No init process, no shell
|
||||||
|
|
||||||
|
3. **Networking**: ❌ Not needed
|
||||||
|
- Hello world doesn't need network
|
||||||
|
|
||||||
|
4. **Dynamic Linking**: ❌ Not needed
|
||||||
|
- Static link everything for simplicity
|
||||||
|
|
||||||
|
5. **SMP**: ❌ Not needed
|
||||||
|
- Single core is fine for hello world
|
||||||
|
|
||||||
|
6. **ACPI**: ⚠️ Minimal
|
||||||
|
- Just enough to work with GPU
|
||||||
|
|
||||||
|
7. **Multiple Applications**: ❌ Not needed
|
||||||
|
- One application only - the QT6 hello world
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
This is a learning/demonstration project. Contributions welcome, but:
|
||||||
|
- Keep it minimal
|
||||||
|
- Every feature must justify its existence
|
||||||
|
- Ask "Does this help run QT6 hello world?" before adding anything
|
||||||
|
- Prefer simple over clever
|
||||||
|
- Document everything
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [UEFI Specification](https://uefi.org/specifications)
|
||||||
|
- [OSDev Wiki](https://wiki.osdev.org/)
|
||||||
|
- [AMD64 Manual](https://www.amd.com/en/support/tech-docs)
|
||||||
|
- [Linux amdgpu driver](https://github.com/torvalds/linux/tree/master/drivers/gpu/drm/amd)
|
||||||
|
- [QT6 Source](https://code.qt.io/cgit/qt/qt5.git/)
|
||||||
|
- [QT QPA Documentation](https://doc.qt.io/qt-6/qpa.html)
|
||||||
79
kernel/Makefile
Normal file
79
kernel/Makefile
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# MetalOS Kernel Makefile
|
||||||
|
|
||||||
|
# Cross-compiler (x86_64 bare metal)
|
||||||
|
CC = x86_64-elf-gcc
|
||||||
|
AS = nasm
|
||||||
|
LD = x86_64-elf-ld
|
||||||
|
OBJCOPY = x86_64-elf-objcopy
|
||||||
|
|
||||||
|
# Check if cross-compiler exists, fallback to regular gcc
|
||||||
|
ifeq ($(shell which $(CC) 2>/dev/null),)
|
||||||
|
CC = gcc
|
||||||
|
LD = ld
|
||||||
|
OBJCOPY = objcopy
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
SRC_DIR = src
|
||||||
|
INC_DIR = include
|
||||||
|
BUILD_DIR = build
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
CFLAGS = -Wall -Wextra -Werror \
|
||||||
|
-ffreestanding -fno-stack-protector \
|
||||||
|
-mno-red-zone -mcmodel=large \
|
||||||
|
-I$(INC_DIR) \
|
||||||
|
-O2
|
||||||
|
|
||||||
|
# Assembler flags
|
||||||
|
ASFLAGS = -f elf64
|
||||||
|
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS = -nostdlib -T linker.ld
|
||||||
|
|
||||||
|
# Source files
|
||||||
|
C_SOURCES = $(shell find $(SRC_DIR) -name '*.c')
|
||||||
|
ASM_SOURCES = $(shell find $(SRC_DIR) -name '*.asm')
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
C_OBJECTS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(C_SOURCES))
|
||||||
|
ASM_OBJECTS = $(patsubst $(SRC_DIR)/%.asm,$(BUILD_DIR)/%.o,$(ASM_SOURCES))
|
||||||
|
OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)
|
||||||
|
|
||||||
|
# Output
|
||||||
|
TARGET = metalos.bin
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(BUILD_DIR) $(TARGET)
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
mkdir -p $(BUILD_DIR)/core
|
||||||
|
mkdir -p $(BUILD_DIR)/hal
|
||||||
|
mkdir -p $(BUILD_DIR)/drivers
|
||||||
|
mkdir -p $(BUILD_DIR)/syscall
|
||||||
|
|
||||||
|
# Compile C files
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Assemble ASM files
|
||||||
|
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(AS) $(ASFLAGS) $< -o $@
|
||||||
|
|
||||||
|
# Link kernel
|
||||||
|
$(TARGET): $(OBJECTS)
|
||||||
|
$(LD) $(LDFLAGS) $(OBJECTS) -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR) $(TARGET)
|
||||||
|
|
||||||
|
# Print variables for debugging
|
||||||
|
info:
|
||||||
|
@echo "C Sources: $(C_SOURCES)"
|
||||||
|
@echo "ASM Sources: $(ASM_SOURCES)"
|
||||||
|
@echo "Objects: $(OBJECTS)"
|
||||||
|
@echo "Compiler: $(CC)"
|
||||||
31
kernel/include/kernel/console.h
Normal file
31
kernel/include/kernel/console.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef METALOS_KERNEL_CONSOLE_H
|
||||||
|
#define METALOS_KERNEL_CONSOLE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Simple framebuffer console for early boot messages
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t* framebuffer;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t x;
|
||||||
|
uint32_t y;
|
||||||
|
uint32_t fg_color;
|
||||||
|
uint32_t bg_color;
|
||||||
|
} Console;
|
||||||
|
|
||||||
|
// Initialize console with framebuffer
|
||||||
|
void console_init(uint32_t* fb, uint32_t width, uint32_t height, uint32_t pitch);
|
||||||
|
|
||||||
|
// Print functions
|
||||||
|
void console_putchar(char c);
|
||||||
|
void console_print(const char* str);
|
||||||
|
void console_println(const char* str);
|
||||||
|
void console_clear(void);
|
||||||
|
|
||||||
|
// Set colors (RGB)
|
||||||
|
void console_set_color(uint32_t fg, uint32_t bg);
|
||||||
|
|
||||||
|
#endif // METALOS_KERNEL_CONSOLE_H
|
||||||
33
kernel/include/kernel/kernel.h
Normal file
33
kernel/include/kernel/kernel.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef METALOS_KERNEL_KERNEL_H
|
||||||
|
#define METALOS_KERNEL_KERNEL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Kernel version
|
||||||
|
#define KERNEL_VERSION_MAJOR 0
|
||||||
|
#define KERNEL_VERSION_MINOR 1
|
||||||
|
#define KERNEL_VERSION_PATCH 0
|
||||||
|
#define KERNEL_NAME "MetalOS"
|
||||||
|
|
||||||
|
// Boot information structure (matches bootloader)
|
||||||
|
typedef struct {
|
||||||
|
uint64_t memory_map_size;
|
||||||
|
uint64_t memory_map_descriptor_size;
|
||||||
|
void* memory_map;
|
||||||
|
|
||||||
|
uint64_t framebuffer_base;
|
||||||
|
uint32_t framebuffer_width;
|
||||||
|
uint32_t framebuffer_height;
|
||||||
|
uint32_t framebuffer_pitch;
|
||||||
|
uint32_t framebuffer_bpp;
|
||||||
|
|
||||||
|
uint64_t kernel_base;
|
||||||
|
uint64_t kernel_size;
|
||||||
|
|
||||||
|
void* rsdp;
|
||||||
|
} BootInfo;
|
||||||
|
|
||||||
|
// Kernel entry point
|
||||||
|
void kernel_main(BootInfo* boot_info);
|
||||||
|
|
||||||
|
#endif // METALOS_KERNEL_KERNEL_H
|
||||||
31
kernel/linker.ld
Normal file
31
kernel/linker.ld
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* MetalOS Kernel Linker Script */
|
||||||
|
|
||||||
|
ENTRY(kernel_main)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* Kernel loaded at 1MB mark */
|
||||||
|
. = 0x100000;
|
||||||
|
|
||||||
|
.text ALIGN(4K) : {
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata ALIGN(4K) : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data ALIGN(4K) : {
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss ALIGN(4K) : {
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Discard debug info */
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.comment)
|
||||||
|
*(.eh_frame)
|
||||||
|
}
|
||||||
|
}
|
||||||
113
kernel/src/core/console.c
Normal file
113
kernel/src/core/console.c
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Simple framebuffer console for kernel messages
|
||||||
|
* Minimal implementation - just enough for debugging
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/console.h"
|
||||||
|
|
||||||
|
// Simple 8x8 bitmap font (ASCII characters 32-126)
|
||||||
|
// This is a minimal font representation
|
||||||
|
static const uint8_t font_8x8[96][8] = {
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Space
|
||||||
|
{0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // !
|
||||||
|
{0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // "
|
||||||
|
{0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // #
|
||||||
|
// ... (simplified - would need full 96 characters)
|
||||||
|
// For now, we'll render simple blocks for all chars
|
||||||
|
};
|
||||||
|
|
||||||
|
static Console console;
|
||||||
|
|
||||||
|
void console_init(uint32_t* fb, uint32_t width, uint32_t height, uint32_t pitch) {
|
||||||
|
console.framebuffer = fb;
|
||||||
|
console.width = width;
|
||||||
|
console.height = height;
|
||||||
|
console.pitch = pitch;
|
||||||
|
console.x = 0;
|
||||||
|
console.y = 0;
|
||||||
|
console.fg_color = 0xFFFFFFFF; // White
|
||||||
|
console.bg_color = 0x00000000; // Black
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_clear(void) {
|
||||||
|
if (!console.framebuffer) return;
|
||||||
|
|
||||||
|
for (uint32_t y = 0; y < console.height; y++) {
|
||||||
|
for (uint32_t x = 0; x < console.width; x++) {
|
||||||
|
console.framebuffer[y * (console.pitch / 4) + x] = console.bg_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.x = 0;
|
||||||
|
console.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_set_color(uint32_t fg, uint32_t bg) {
|
||||||
|
console.fg_color = fg;
|
||||||
|
console.bg_color = bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a simple 8x8 character (simplified version)
|
||||||
|
static void draw_char(char c, uint32_t x, uint32_t y) {
|
||||||
|
if (!console.framebuffer) return;
|
||||||
|
if (x + 8 > console.width || y + 8 > console.height) return;
|
||||||
|
|
||||||
|
// For simplicity, just draw a simple pattern based on character
|
||||||
|
// In a real implementation, we'd use the font bitmap
|
||||||
|
for (int cy = 0; cy < 8; cy++) {
|
||||||
|
for (int cx = 0; cx < 8; cx++) {
|
||||||
|
uint32_t pixel_x = x + cx;
|
||||||
|
uint32_t pixel_y = y + cy;
|
||||||
|
|
||||||
|
// Simple algorithm: draw pixels based on char value
|
||||||
|
// This creates a unique pattern for each character
|
||||||
|
uint8_t pattern = (c + cy) & (1 << cx) ? 0xFF : 0x00;
|
||||||
|
|
||||||
|
uint32_t color = pattern ? console.fg_color : console.bg_color;
|
||||||
|
console.framebuffer[pixel_y * (console.pitch / 4) + pixel_x] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_putchar(char c) {
|
||||||
|
if (!console.framebuffer) return;
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
console.x = 0;
|
||||||
|
console.y += 8;
|
||||||
|
if (console.y >= console.height) {
|
||||||
|
console.y = 0; // Wrap around (simplified scrolling)
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\r') {
|
||||||
|
console.x = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_char(c, console.x, console.y);
|
||||||
|
console.x += 8;
|
||||||
|
|
||||||
|
if (console.x >= console.width) {
|
||||||
|
console.x = 0;
|
||||||
|
console.y += 8;
|
||||||
|
if (console.y >= console.height) {
|
||||||
|
console.y = 0; // Wrap around
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_print(const char* str) {
|
||||||
|
if (!str) return;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
console_putchar(*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_println(const char* str) {
|
||||||
|
console_print(str);
|
||||||
|
console_putchar('\n');
|
||||||
|
}
|
||||||
62
kernel/src/main.c
Normal file
62
kernel/src/main.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* MetalOS Kernel - Main Entry Point
|
||||||
|
*
|
||||||
|
* Minimal kernel implementation for running QT6 applications.
|
||||||
|
* Only implements what's absolutely necessary.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/kernel.h"
|
||||||
|
#include "kernel/console.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kernel main entry point
|
||||||
|
* Called by bootloader with boot information
|
||||||
|
*/
|
||||||
|
void kernel_main(BootInfo* boot_info) {
|
||||||
|
// Initialize basic console output using framebuffer
|
||||||
|
console_init(
|
||||||
|
(uint32_t*)boot_info->framebuffer_base,
|
||||||
|
boot_info->framebuffer_width,
|
||||||
|
boot_info->framebuffer_height,
|
||||||
|
boot_info->framebuffer_pitch
|
||||||
|
);
|
||||||
|
|
||||||
|
console_clear();
|
||||||
|
console_print("MetalOS Kernel v0.1.0\n");
|
||||||
|
console_print("=====================\n\n");
|
||||||
|
|
||||||
|
console_print("Initializing minimal kernel...\n");
|
||||||
|
|
||||||
|
// TODO: Initialize memory management
|
||||||
|
console_print("[ ] Memory management\n");
|
||||||
|
|
||||||
|
// TODO: Initialize interrupt handling
|
||||||
|
console_print("[ ] Interrupt handling\n");
|
||||||
|
|
||||||
|
// TODO: Initialize PCI bus
|
||||||
|
console_print("[ ] PCI enumeration\n");
|
||||||
|
|
||||||
|
// TODO: Initialize GPU driver
|
||||||
|
console_print("[ ] GPU driver (Radeon RX 6600)\n");
|
||||||
|
|
||||||
|
// TODO: Initialize input devices
|
||||||
|
console_print("[ ] Input devices\n");
|
||||||
|
|
||||||
|
// TODO: Setup system calls
|
||||||
|
console_print("[ ] System call interface\n");
|
||||||
|
|
||||||
|
// TODO: Load and run QT6 hello world application directly (no shell/init)
|
||||||
|
console_print("[ ] Loading QT6 Hello World application...\n");
|
||||||
|
|
||||||
|
console_print("\nKernel initialization complete.\n");
|
||||||
|
console_print("Booting directly into application (no shell)...\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");
|
||||||
|
}
|
||||||
|
}
|
||||||
53
scripts/create_image.sh
Executable file
53
scripts/create_image.sh
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# MetalOS - Create bootable disk image
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "MetalOS Image Creator"
|
||||||
|
echo "====================="
|
||||||
|
|
||||||
|
BUILD_DIR="build"
|
||||||
|
ISO_DIR="$BUILD_DIR/iso"
|
||||||
|
IMAGE="$BUILD_DIR/metalos.img"
|
||||||
|
|
||||||
|
# Check if bootloader and kernel exist
|
||||||
|
if [ ! -f "bootloader/bootx64.efi" ]; then
|
||||||
|
echo "Error: bootloader/bootx64.efi not found. Run 'make bootloader' first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "kernel/metalos.bin" ]; then
|
||||||
|
echo "Error: kernel/metalos.bin not found. Run 'make kernel' first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
mkdir -p "$ISO_DIR/EFI/BOOT"
|
||||||
|
|
||||||
|
# Copy files
|
||||||
|
echo "Copying bootloader..."
|
||||||
|
cp bootloader/bootx64.efi "$ISO_DIR/EFI/BOOT/"
|
||||||
|
|
||||||
|
echo "Copying kernel..."
|
||||||
|
cp kernel/metalos.bin "$ISO_DIR/"
|
||||||
|
|
||||||
|
# Create disk image (requires mtools and xorriso)
|
||||||
|
echo "Creating disk image..."
|
||||||
|
|
||||||
|
if command -v xorriso &> /dev/null; then
|
||||||
|
xorriso -as mkisofs \
|
||||||
|
-e EFI/BOOT/bootx64.efi \
|
||||||
|
-no-emul-boot \
|
||||||
|
-o "$IMAGE" \
|
||||||
|
"$ISO_DIR"
|
||||||
|
echo "Success! Created $IMAGE"
|
||||||
|
else
|
||||||
|
echo "Warning: xorriso not found. Image not created."
|
||||||
|
echo "Install with: sudo apt-get install xorriso"
|
||||||
|
echo ""
|
||||||
|
echo "Files are ready in $ISO_DIR/"
|
||||||
|
echo "You can manually create a bootable USB by:"
|
||||||
|
echo " 1. Format USB with GPT and FAT32 EFI partition"
|
||||||
|
echo " 2. Copy $ISO_DIR/EFI to the USB"
|
||||||
|
echo " 3. Copy $ISO_DIR/metalos.bin to the USB"
|
||||||
|
fi
|
||||||
54
userspace/apps/hello_world.cpp
Normal file
54
userspace/apps/hello_world.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* QT6 Hello World Application for MetalOS
|
||||||
|
*
|
||||||
|
* This is a minimal QT6 application that will run full-screen
|
||||||
|
* on MetalOS with Radeon RX 6600 GPU support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QFont>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
// Create main window
|
||||||
|
QWidget window;
|
||||||
|
window.setWindowTitle("MetalOS - QT6 Hello World");
|
||||||
|
|
||||||
|
// Create layout
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(&window);
|
||||||
|
|
||||||
|
// Create "Hello World" label
|
||||||
|
QLabel *label = new QLabel("Hello, World!");
|
||||||
|
QFont font = label->font();
|
||||||
|
font.setPointSize(48);
|
||||||
|
font.setBold(true);
|
||||||
|
label->setFont(font);
|
||||||
|
label->setAlignment(Qt::AlignCenter);
|
||||||
|
label->setStyleSheet("QLabel { color: white; background-color: black; }");
|
||||||
|
|
||||||
|
// Create info label
|
||||||
|
QLabel *infoLabel = new QLabel(
|
||||||
|
"MetalOS - A minimal OS for QT6 applications\n"
|
||||||
|
"AMD64 + Radeon RX 6600 GPU\n"
|
||||||
|
"UEFI Native Boot"
|
||||||
|
);
|
||||||
|
infoLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
infoLabel->setStyleSheet("QLabel { color: #00FF00; background-color: black; }");
|
||||||
|
|
||||||
|
// Add widgets to layout
|
||||||
|
layout->addWidget(label);
|
||||||
|
layout->addWidget(infoLabel);
|
||||||
|
|
||||||
|
// Set window properties
|
||||||
|
window.setLayout(layout);
|
||||||
|
window.setStyleSheet("QWidget { background-color: black; }");
|
||||||
|
|
||||||
|
// Show full screen
|
||||||
|
window.showFullScreen();
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
23
userspace/apps/hello_world.pro
Normal file
23
userspace/apps/hello_world.pro
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# QT6 Hello World Application
|
||||||
|
|
||||||
|
QT += core gui widgets
|
||||||
|
|
||||||
|
CONFIG += c++17
|
||||||
|
|
||||||
|
SOURCES += hello_world.cpp
|
||||||
|
|
||||||
|
TARGET = hello_world
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
# MetalOS specific configuration
|
||||||
|
# This would need significant work to actually run on MetalOS
|
||||||
|
|
||||||
|
QMAKE_CXXFLAGS += -ffreestanding
|
||||||
|
QMAKE_LFLAGS += -nostdlib
|
||||||
|
|
||||||
|
# Note: This is a placeholder .pro file
|
||||||
|
# Actual QT6 port to MetalOS would require:
|
||||||
|
# 1. QT Platform Abstraction (QPA) plugin for MetalOS
|
||||||
|
# 2. Custom event loop integration
|
||||||
|
# 3. Graphics backend using MetalOS framebuffer/GPU
|
||||||
|
# 4. Input device integration
|
||||||
Reference in New Issue
Block a user