⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/arch/x86_64/
multiboot.rs

1// Multiboot2 header for GRUB compatibility
2
3use core::arch::global_asm;
4
5// Simplified multiboot2 header without problematic relocations
6global_asm!(
7    r#"
8.section .multiboot_header, "aw"
9.align 8
10
11multiboot_header_start:
12    .long 0xe85250d6                // magic number (multiboot2)
13    .long 0                         // architecture (0 = i386/x86_64)
14    .long multiboot_header_end - multiboot_header_start  // header length
15
16    // checksum
17    .long -(0xe85250d6 + 0 + (multiboot_header_end - multiboot_header_start))
18
19    // Information request tag
20    .word 1                         // type
21    .word 0                         // flags
22    .long 20                        // size
23    .long 4                         // basic memory info
24    .long 6                         // memory map
25
26    // End tag
27    .word 0                         // type
28    .word 0                         // flags  
29    .long 8                         // size
30multiboot_header_end:
31
32.section .text.boot, "ax"
33.global _multiboot_entry
34_multiboot_entry:
35    // Set up stack
36    mov rsp, 0xFFFFFFFF80200000     // Use higher-half stack
37    
38    // Save multiboot info
39    push rdi                        // multiboot2 magic
40    push rsi                        // multiboot2 info struct
41    
42    // Enable SSE for Rust
43    mov rax, cr0
44    and ax, 0xFFFB                  // Clear coprocessor emulation CR0.EM
45    or ax, 0x0002                   // Set coprocessor monitoring  CR0.MP
46    mov cr0, rax
47    mov rax, cr4
48    or ax, 3 << 9                   // Set CR4.OSFXSR and CR4.OSXMMEXCPT
49    mov cr4, rax
50
51    // Call our multiboot main
52    pop rsi                         // multiboot info
53    pop rdi                         // multiboot magic  
54    call multiboot_main
55    
56.halt_loop:
57    hlt
58    jmp .halt_loop
59"#
60);
61
62#[no_mangle]
63pub extern "C" fn multiboot_main(magic: u64, info_addr: u64) -> ! {
64    // SAFETY: 0xb8000 is the standard VGA text buffer address on x86 PCs.
65    // write_volatile ensures the write is not optimized away. The buffer is
66    // always mapped during early boot and each u16 encodes a character + attribute.
67    unsafe {
68        let vga = 0xb8000 as *mut u16;
69        vga.write_volatile(0x0F4D); // 'M' for multiboot
70        vga.offset(1).write_volatile(0x0F42); // 'B'
71    }
72
73    // Verify multiboot2 magic
74    if magic != 0x36d76289 {
75        // SAFETY: VGA text buffer at 0xb8000 is always mapped during early boot.
76        // write_volatile ensures the error indicator is displayed.
77        unsafe {
78            let vga = 0xb8000 as *mut u16;
79            vga.offset(2).write_volatile(0x4F45); // 'E' in red (error)
80            vga.offset(3).write_volatile(0x4F52); // 'R'
81        }
82        loop {
83            // SAFETY: hlt halts the CPU until the next interrupt. Safe in a panic loop.
84            unsafe { core::arch::asm!("hlt") };
85        }
86    }
87
88    // Initialize early serial for debugging
89    let mut serial_port = crate::arch::x86_64::serial_init();
90    use core::fmt::Write;
91    let _ = writeln!(serial_port, "[MULTIBOOT] Multiboot2 entry successful!");
92    let _ = writeln!(
93        serial_port,
94        "[MULTIBOOT] Magic: 0x{:x}, Info: 0x{:x}",
95        magic, info_addr
96    );
97
98    // Set up minimal boot info structure
99    // For now, we'll skip the full multiboot info parsing and use defaults
100    // SAFETY: BOOT_INFO is a static mut Option written once during early boot
101    // before any other code runs. No concurrent access is possible at this stage.
102    unsafe {
103        crate::arch::x86_64::boot::BOOT_INFO = None; // Multiboot doesn't use
104                                                     // bootloader_api BootInfo
105    }
106
107    // Initialize early architecture
108    crate::arch::x86_64::entry::arch_early_init();
109
110    let _ = writeln!(
111        serial_port,
112        "[MULTIBOOT] Starting bootstrap initialization..."
113    );
114
115    // Run bootstrap directly
116    crate::bootstrap::run();
117}