menios icon indicating copy to clipboard operation
menios copied to clipboard

Create boot protocol abstraction layer for multi-platform support

Open pbalduino opened this issue 3 months ago • 0 comments

Summary

Create a boot protocol abstraction layer to enable multi-platform support while keeping Limine as the primary bootloader. This abstraction will allow meniOS to work with multiple bootloaders (Limine, GRUB, U-Boot) across different architectures, starting with Limine support for both x86_64 and ARM64.

Context

Important Discovery: Limine supports multiple architectures including ARM64/AArch64, x86_64, RISC-V, and more. Therefore, we don't need to migrate away from Limine for multi-platform support.

However, we still need a boot protocol abstraction layer to:

  1. Isolate bootloader-specific code from kernel initialization
  2. Support multiple bootloaders (Limine primary, GRUB/U-Boot optional)
  3. Enable easier testing with mock boot information
  4. Simplify future architecture ports

Current Limine Integration

Limine is deeply integrated into the meniOS build system and kernel initialization:

Limine Multi-Architecture Support:

  • IA-32 (32-bit x86)
  • x86-64 ✅ (currently used)
  • aarch64 (arm64) ✅ (target for #98)
  • riscv64 (future)
  • loongarch64 (future)

Limine Boot Protocols:

  • Limine protocol (native)
  • Linux boot protocol (for ARM64)
  • Multiboot 1 & 2 (for compatibility)

Current Integration Points:

  • include/boot/limine.h - Limine protocol header (277 references)
  • src/kernel/mem/pmm.c - Memory map via limine_memmap_request
  • src/kernel/framebuffer.c - Framebuffer via limine_framebuffer_request
  • src/kernel/acpi/uacpi_menios.c - RSDP via limine_rsdp_request
  • Build system (Makefile:253-586) - Image generation

Goals

Primary Goals

  1. Boot Abstraction Layer: Generic boot info structure independent of bootloader
  2. Limine x86_64 Adapter: Convert existing code to use abstraction (no functional changes)
  3. Limine ARM64 Support: Add ARM64 boot protocol support (Linux boot protocol)
  4. Optional GRUB Support: Enable GRUB as alternative bootloader (future enhancement)

Non-Goals

  • Replacing Limine (it works great and supports ARM64!)
  • Supporting every bootloader under the sun
  • Over-engineering the abstraction layer

Implementation Strategy

Phase 1: Research and Planning (1-2 weeks)

Understand Boot Information Needs

  • [ ] Audit all Limine protocol usage in kernel
  • [ ] Document memory layout requirements
  • [ ] Identify common boot info across bootloaders
  • [ ] Study Limine ARM64 boot protocol

Design Boot Abstraction Layer

  • [ ] Define generic boot_info_t structure
  • [ ] Design bootloader adapter interface
  • [ ] Plan zero-overhead abstraction approach
  • [ ] Document architecture decision records

Phase 2: Boot Abstraction Layer (2-3 weeks)

Create Boot Protocol Abstraction

// include/boot/boot_info.h
typedef struct boot_memory_region {
    uint64_t base;
    uint64_t length;
    uint32_t type;  // Usable, reserved, ACPI, etc.
} boot_memory_region_t;

typedef struct boot_framebuffer {
    void *address;
    uint32_t width;
    uint32_t height;
    uint32_t pitch;
    uint16_t bpp;
} boot_framebuffer_t;

typedef struct boot_info {
    // Memory information
    boot_memory_region_t *memory_map;
    size_t memory_map_entries;
    uint64_t hhdm_offset;
    
    // Framebuffer
    boot_framebuffer_t *framebuffer;
    
    // ACPI
    void *rsdp;
    
    // Device tree (for ARM64)
    void *dtb;
    size_t dtb_size;
    
    // Command line
    const char *cmdline;
    
    // Architecture-specific data
    void *arch_data;
} boot_info_t;

// Bootloader adapters
boot_info_t *limine_x86_64_get_boot_info(void);
boot_info_t *limine_aarch64_get_boot_info(void);
boot_info_t *multiboot2_get_boot_info(void);  // Optional GRUB support

Implement Abstraction for Current Limine Code

  • [ ] Create src/kernel/boot/boot_info.c
  • [ ] Create src/kernel/boot/limine_adapter.c
  • [ ] Convert PMM to use boot abstraction
  • [ ] Convert framebuffer to use boot abstraction
  • [ ] Convert ACPI initialization to use boot abstraction
  • [ ] Test with existing Limine bootloader (ensure no regression)

Phase 3: ARM64 Boot Support (2-3 weeks)

Limine ARM64 Adapter

  • [ ] Study Limine ARM64 boot protocol
  • [ ] Implement limine_aarch64_get_boot_info()
  • [ ] Handle device tree if provided by Limine
  • [ ] Parse ARM64-specific boot parameters
  • [ ] Update build system for ARM64 Limine images

Testing

  • [ ] Test x86_64 with abstraction (no regressions)
  • [ ] Test ARM64 boot info parsing in QEMU
  • [ ] Validate memory map conversion
  • [ ] Validate framebuffer info (if available)

Phase 4: Optional GRUB Support (Future - 3-4 weeks)

Multiboot2 Protocol Implementation (Optional)

  • [ ] Create src/kernel/boot/multiboot2_adapter.c
  • [ ] Implement Multiboot2 header in assembly
  • [ ] Parse Multiboot2 boot information tags
  • [ ] Implement multiboot2_get_boot_info() adapter
  • [ ] Add GRUB configuration files
  • [ ] Update build system for GRUB images

This phase is optional and can be deferred or skipped entirely.

Phase 5: Documentation and Cleanup (1 week)

Documentation

  • [ ] Document boot abstraction API
  • [ ] Document bootloader adapter interface
  • [ ] Update build documentation
  • [ ] Create architecture documentation
  • [ ] Document Limine configuration for both architectures

Cleanup

  • [ ] Remove any remaining direct Limine calls from kernel
  • [ ] Add compile-time checks for proper abstraction usage
  • [ ] Archive research notes for future bootloader support

Technical Details

Boot Abstraction Benefits

  1. Bootloader Independence: Kernel doesn't depend on specific bootloader
  2. Multiple Bootloaders: Easy to support Limine, GRUB, U-Boot, etc.
  3. Easier Testing: Mock boot info for unit tests
  4. Architecture Support: Same interface for x86_64, ARM64, RISC-V
  5. Cleaner Code: Separation of concerns

Limine Feature Mapping

Kernel Need Limine x86_64 Limine ARM64
Memory map limine_memmap_request Linux boot protocol + DT
Framebuffer limine_framebuffer_request Linux FB or DT
HHDM limine_hhdm_request Manual setup
RSDP (ACPI) limine_rsdp_request ACPI tables or DT
Device tree N/A (x86) Linux boot protocol
Entry point Limine protocol Linux kernel entry

Zero-Overhead Design

The abstraction should be zero-overhead through:

  • Inline functions where possible
  • Compile-time bootloader selection
  • No runtime bootloader detection overhead
  • Static boot info structure (no dynamic allocation)
// Boot time only - called once during early init
static boot_info_t boot_info;

void kernel_early_init(void) {
    #if defined(BOOTLOADER_LIMINE)
        #if defined(ARCH_X86_64)
            boot_info = *limine_x86_64_get_boot_info();
        #elif defined(ARCH_AARCH64)
            boot_info = *limine_aarch64_get_boot_info();
        #endif
    #elif defined(BOOTLOADER_MULTIBOOT2)
        boot_info = *multiboot2_get_boot_info();
    #endif
    
    // Rest of kernel uses generic boot_info
    pmm_init(boot_info.memory_map, boot_info.memory_map_entries);
    framebuffer_init(boot_info.framebuffer);
    acpi_init(boot_info.rsdp);
}

Dependencies

Blocked By

  • None (can start immediately)

Blocks

  • #98 - Port meniOS to ARM64/AArch64 architecture (partially - ARM64 boot support)

Related

  • #98 - ARM64 port needs ARM64 boot adapter
  • #97 - Architecture abstraction layer (if exists)

Risks and Mitigation

Risk: Abstraction Overhead

  • Mitigation: Zero-cost abstraction design
  • Mitigation: Inline functions and compile-time selection
  • Mitigation: Benchmark before/after

Risk: Breaking x86_64 Boot

  • Mitigation: Implement abstraction incrementally
  • Mitigation: Keep Limine working throughout
  • Mitigation: Extensive testing on x86_64

Risk: Limine ARM64 Differences

  • Mitigation: Research phase to understand ARM64 boot flow
  • Mitigation: Reference Limine documentation and examples
  • Mitigation: Test early and often on QEMU ARM64

Success Metrics

  • [ ] Boot abstraction layer implemented with zero overhead
  • [ ] x86_64 boots with abstraction (no regressions)
  • [ ] ARM64 boot info adapter ready for #98
  • [ ] Clean separation: no direct Limine calls in kernel code
  • [ ] Optional: GRUB support as alternative bootloader
  • [ ] Documentation complete and accurate

Timeline

  • Phase 1 (Research): 1-2 weeks
  • Phase 2 (Abstraction): 2-3 weeks
  • Phase 3 (ARM64): 2-3 weeks
  • Phase 4 (GRUB): Optional, 3-4 weeks if desired
  • Phase 5 (Documentation): 1 week

Total Estimated Effort: 6-9 weeks part-time (or 12-13 weeks if including optional GRUB support)

This is significantly faster than the original 14-19 week estimate for GRUB migration.

References

Notes

  • Limine's native multi-architecture support makes this much simpler than originally planned
  • The boot abstraction layer is still valuable for cleaner code and future flexibility
  • GRUB support is now optional rather than required
  • This approach allows faster progress on ARM64 port (#98)
  • The abstraction layer provides value even with a single bootloader (testability, cleaner code)

pbalduino avatar Oct 15 '25 13:10 pbalduino