Create boot protocol abstraction layer for multi-platform support
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:
- Isolate bootloader-specific code from kernel initialization
- Support multiple bootloaders (Limine primary, GRUB/U-Boot optional)
- Enable easier testing with mock boot information
- 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 vialimine_memmap_request -
src/kernel/framebuffer.c- Framebuffer vialimine_framebuffer_request -
src/kernel/acpi/uacpi_menios.c- RSDP vialimine_rsdp_request - Build system (Makefile:253-586) - Image generation
Goals
Primary Goals
- Boot Abstraction Layer: Generic boot info structure independent of bootloader
- Limine x86_64 Adapter: Convert existing code to use abstraction (no functional changes)
- Limine ARM64 Support: Add ARM64 boot protocol support (Linux boot protocol)
- 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_tstructure - [ ] 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
- Bootloader Independence: Kernel doesn't depend on specific bootloader
- Multiple Bootloaders: Easy to support Limine, GRUB, U-Boot, etc.
- Easier Testing: Mock boot info for unit tests
- Architecture Support: Same interface for x86_64, ARM64, RISC-V
- 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
- Limine Protocol Specification
- Limine Repository
- Limine ARM64 Support
- Linux ARM64 Boot Protocol
- Multiboot2 Specification (optional)
- Device Tree Specification
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)