mirror of
https://github.com/johndoe6345789/MetalOS.git
synced 2026-04-24 13:45:02 +00:00
- Implement proper memory detection by parsing UEFI memory map - Mark only usable memory regions as free (EfiConventionalMemory, Boot/Loader services) - Initialize bitmap with all pages marked as used, then free only available regions - Calculate totalPages based on highest usable address from memory map - Add 128MB fallback if memory map is unavailable - Now works correctly with any RAM amount from 0 to 64GB Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
296 lines
7.0 KiB
Markdown
296 lines
7.0 KiB
Markdown
# MetalOS Kernel - Quick Reference
|
|
|
|
## Kernel Modules Implemented
|
|
|
|
### Core System
|
|
- **GDT (gdt.c/h)**: Global Descriptor Table setup for x86_64
|
|
- **IDT (interrupts.c/h)**: Interrupt Descriptor Table with 32 exception handlers and IRQ support
|
|
- **Memory (memory.c/h)**: Physical memory manager and kernel heap allocator
|
|
- **PCI (pci.c/h)**: PCI bus enumeration and device configuration
|
|
- **Timer (timer.c/h)**: Programmable Interval Timer (PIT) with 1ms tick resolution
|
|
|
|
## Building the Kernel
|
|
|
|
### Quick Build
|
|
```bash
|
|
# With Ninja (fastest)
|
|
mkdir build && cd build
|
|
cmake -G Ninja ..
|
|
ninja kernel
|
|
|
|
# With Make
|
|
mkdir build && cd build
|
|
cmake ..
|
|
make kernel
|
|
```
|
|
|
|
### With Conan
|
|
```bash
|
|
conan install . --build=missing
|
|
conan build .
|
|
```
|
|
|
|
## Kernel API Reference
|
|
|
|
### Memory Management
|
|
|
|
```c
|
|
// Physical memory
|
|
void pmm_init(BootInfo* boot_info);
|
|
void* pmm_alloc_page(void);
|
|
void pmm_free_page(void* page);
|
|
|
|
// Kernel heap
|
|
void heap_init(void* start, size_t size);
|
|
void* kmalloc(size_t size);
|
|
void* kcalloc(size_t num, size_t size);
|
|
void kfree(void* ptr); // Not implemented in bump allocator
|
|
|
|
// Utilities
|
|
void* memset(void* dest, int val, size_t count);
|
|
void* memcpy(void* dest, const void* src, size_t count);
|
|
int memcmp(const void* s1, const void* s2, size_t count);
|
|
```
|
|
|
|
### PCI Bus
|
|
|
|
```c
|
|
void pci_init(void);
|
|
uint32_t pci_read_config(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset);
|
|
void pci_write_config(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value);
|
|
pci_device_t* pci_find_device(uint16_t vendor_id, uint16_t device_id);
|
|
void pci_enable_bus_mastering(pci_device_t* dev);
|
|
```
|
|
|
|
### Timer
|
|
|
|
```c
|
|
void timer_init(uint32_t frequency); // Initialize with frequency in Hz
|
|
uint64_t timer_get_ticks(void); // Get current tick count
|
|
void timer_wait(uint32_t ticks); // Wait for specified ticks
|
|
```
|
|
|
|
### Interrupts
|
|
|
|
```c
|
|
void gdt_init(void); // Initialize GDT
|
|
void idt_init(void); // Initialize IDT and enable interrupts
|
|
void interrupt_handler(registers_t* regs); // Generic handler
|
|
```
|
|
|
|
## Kernel Initialization Sequence
|
|
|
|
```c
|
|
void kernel_main(BootInfo* boot_info) {
|
|
gdt_init(); // 1. Setup GDT
|
|
idt_init(); // 2. Setup IDT and enable interrupts
|
|
pmm_init(boot_info); // 3. Initialize physical memory
|
|
heap_init(...); // 4. Initialize kernel heap
|
|
timer_init(1000); // 5. Setup timer (1000Hz = 1ms per tick)
|
|
pci_init(); // 6. Scan PCI bus
|
|
// ... continue with GPU and input setup
|
|
}
|
|
```
|
|
|
|
## Memory Layout
|
|
|
|
```
|
|
0x0000000000000000 - 0x0000000000000FFF : NULL guard page
|
|
0x0000000000001000 - 0x00000000000FFFFF : Bootloader (temporary)
|
|
0x0000000000100000 - 0x0000000000FFFFFF : Kernel code/data
|
|
0x0000000001000000 - 0x00000000FFFFFFFF : Physical memory pool
|
|
```
|
|
|
|
## PCI Device Finding Example
|
|
|
|
```c
|
|
// Find AMD RX 6600 GPU
|
|
// Vendor: 0x1002 (AMD)
|
|
// Device: Check AMD documentation for exact device ID
|
|
pci_device_t* gpu = pci_find_device(0x1002, device_id);
|
|
if (gpu) {
|
|
pci_enable_bus_mastering(gpu);
|
|
// Access BAR0 for MMIO
|
|
uint64_t mmio_base = gpu->bar[0] & ~0xF;
|
|
// ... initialize GPU
|
|
}
|
|
```
|
|
|
|
## Interrupt Handling
|
|
|
|
### Exception Handlers (ISR 0-31)
|
|
- ISR 0: Divide by zero
|
|
- ISR 6: Invalid opcode
|
|
- ISR 13: General protection fault
|
|
- ISR 14: Page fault
|
|
- ... (see interrupts.c for full list)
|
|
|
|
### IRQ Handlers (ISR 32-47)
|
|
- IRQ 0 (ISR 32): Timer interrupt
|
|
- IRQ 1 (ISR 33): Keyboard interrupt
|
|
- ... (add more as needed)
|
|
|
|
## Adding New Kernel Modules
|
|
|
|
1. Create header in `kernel/include/kernel/yourmodule.h`
|
|
2. Create implementation in `kernel/src/yourmodule.c`
|
|
3. Add to `kernel/CMakeLists.txt`:
|
|
```cmake
|
|
set(KERNEL_C_SOURCES
|
|
...
|
|
src/yourmodule.c
|
|
)
|
|
```
|
|
4. Include in `kernel/src/main.c` and call init function
|
|
5. Rebuild: `ninja kernel` or `make kernel`
|
|
|
|
## Constants
|
|
|
|
```c
|
|
#define PAGE_SIZE 4096 // 4KB pages
|
|
#define TIMER_FREQUENCY 1000 // 1ms per tick
|
|
#define PCI_CONFIG_ADDRESS 0xCF8
|
|
#define PCI_CONFIG_DATA 0xCFC
|
|
```
|
|
|
|
## Notes
|
|
|
|
- **No Console Module**: As requested, no console.c/h files are created
|
|
- **Minimal Design**: Only essential features for QT6 Hello World
|
|
- **Bump Allocator**: Current heap doesn't support freeing (upgrade later if needed)
|
|
- **Physical Memory**: Bitmap allocator with UEFI memory map parsing (supports up to 64GB, auto-detects available RAM)
|
|
- **PCI Scan**: Scans all 256 buses, 32 devices per bus
|
|
- **Timer**: Uses PIT in rate generator mode
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
# Build and check symbols
|
|
cd build
|
|
ninja kernel
|
|
nm kernel/metalos.bin | grep -E "(init|handler)"
|
|
|
|
# Expected output shows all init functions
|
|
```
|
|
|
|
## Future Enhancements
|
|
|
|
- [ ] Implement proper heap allocator with free support
|
|
- [ ] Parse UEFI memory map properly in pmm_init
|
|
- [ ] Add keyboard interrupt handler
|
|
- [ ] Add GPU driver initialization
|
|
- [ ] Set up page tables for virtual memory
|
|
- [ ] Add input device drivers
|
|
|
|
## SMP (Multicore) API
|
|
|
|
### Core Detection and Management
|
|
|
|
```c
|
|
// Initialize SMP and start all CPU cores
|
|
void smp_init(void);
|
|
|
|
// Get number of online CPUs
|
|
uint8_t smp_get_cpu_count(void);
|
|
|
|
// Get current CPU ID (0 = BSP, 1+ = APs)
|
|
uint8_t smp_get_current_cpu(void);
|
|
|
|
// Check if multicore is enabled
|
|
bool smp_is_enabled(void);
|
|
|
|
// Get CPU information
|
|
cpu_info_t* smp_get_cpu_info(uint8_t cpu_id);
|
|
```
|
|
|
|
### APIC (Interrupt Controller)
|
|
|
|
```c
|
|
// Check if APIC is available
|
|
bool apic_is_available(void);
|
|
|
|
// Initialize Local APIC
|
|
void apic_init(void);
|
|
|
|
// Get Local APIC ID
|
|
uint8_t apic_get_id(void);
|
|
|
|
// Send End of Interrupt
|
|
void apic_send_eoi(void);
|
|
|
|
// Send Inter-Processor Interrupt
|
|
void apic_send_ipi(uint8_t dest_apic_id, uint8_t vector, uint32_t delivery_mode);
|
|
```
|
|
|
|
### Spinlocks
|
|
|
|
```c
|
|
spinlock_t lock;
|
|
|
|
// Initialize spinlock
|
|
void spinlock_init(spinlock_t* lock);
|
|
|
|
// Acquire lock (blocking)
|
|
void spinlock_acquire(spinlock_t* lock);
|
|
|
|
// Try to acquire (non-blocking)
|
|
bool spinlock_try_acquire(spinlock_t* lock);
|
|
|
|
// Release lock
|
|
void spinlock_release(spinlock_t* lock);
|
|
|
|
// Check if locked
|
|
bool spinlock_is_locked(spinlock_t* lock);
|
|
```
|
|
|
|
### Example: Protected Critical Section
|
|
|
|
```c
|
|
// Initialize lock once
|
|
static spinlock_t my_lock;
|
|
spinlock_init(&my_lock);
|
|
|
|
// Use in critical section
|
|
void update_shared_data(void) {
|
|
spinlock_acquire(&my_lock);
|
|
|
|
// Protected code here
|
|
// Safe across all CPUs
|
|
|
|
spinlock_release(&my_lock);
|
|
}
|
|
```
|
|
|
|
### Multicore-Aware Initialization
|
|
|
|
```c
|
|
void kernel_main(BootInfo* boot_info) {
|
|
gdt_init();
|
|
idt_init();
|
|
pmm_init(boot_info);
|
|
heap_init(...);
|
|
timer_init(1000);
|
|
pci_init();
|
|
|
|
// Start all CPU cores
|
|
smp_init();
|
|
|
|
uint8_t num_cpus = smp_get_cpu_count();
|
|
// num_cpus = 12 on 6-core/12-thread system
|
|
|
|
// Continue with single-threaded initialization
|
|
// (APs are idle, waiting for work)
|
|
}
|
|
```
|
|
|
|
## Multicore Support
|
|
|
|
MetalOS now supports multicore processors with up to 16 logical CPUs. Features:
|
|
- Automatic CPU detection
|
|
- APIC-based interrupt handling
|
|
- Spinlocks for synchronization
|
|
- Per-CPU data structures
|
|
- Falls back to single-core if APIC unavailable
|
|
|
|
See [SMP_MULTICORE.md](SMP_MULTICORE.md) for detailed documentation.
|