Create foundational structure for MetalOS - Phase 1 complete

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-28 17:43:20 +00:00
parent 7548ab87cc
commit e66ef697f7
23 changed files with 2580 additions and 12 deletions

79
kernel/Makefile Normal file
View 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)"

View 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

View 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
View 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
View 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
View 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");
}
}