#![no_std] Rust, Paging & Hardware Interrupts (IDT)
The Philosophy of Freedom OS
Freedom OS (30 Rust kernel modules, zero external dependencies, UEFI boot, custom GUI window compositor, integrated NexusCode IDE, and in-kernel TCP/IP stack) is an open-source bare-metal operating system written from scratch in #![no_std] Rust. In this environment, there is no libc, no OS thread scheduler, and no host runtime—you program directly against bare-metal x86_64 silicon.
Disabling the Runtime & Handling Panics
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
// Print panic message directly to serial port or VGA memory
unsafe {
write_vga_error("KERNEL PANIC: Unrecoverable CPU fault");
}
loop {
// Halt CPU to prevent execution runaway
x86_64::instructions::hlt();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn _start() -> ! {
// Entry point invoked by bootloader
init_gdt();
init_idt();
unsafe { init_page_tables(); }
loop {
x86_64::instructions::hlt();
}
}
UEFI Boot Handoff & 4-Level x86_64 Paging (PML4 → PDPT → PD → PT)
In modern uefi (v0.33+ through 2026 releases), the legacy SystemTable<Boot> entry parameter was removed in favor of global freestanding boot helpers. Exiting boot services returns an owned physical memory map while fencing off invalid boot-time protocols:
use uefi::prelude::*;
use uefi::mem::memory_map::MemoryMapOwned;
#[entry]
fn efi_main() -> Status {
// Locate GOP framebuffer before exiting UEFI Boot Services...
// Safely exit boot services (None defaults to MemoryType::LOADER_DATA)
let memory_map: MemoryMapOwned = unsafe { uefi::boot::exit_boot_services(None) };
kernel_handoff(memory_map)
}
Once in 64-bit Long Mode, physical register CR3 points to the 512-entry Page-Map Level-4 (PML4) table. Every canonical 48-bit virtual address translates through four 9-bit page-table indices (PML4[47:39] → PDPT[38:30] → PD[29:21] → PT[20:12]) plus a 12-bit offset (4 KiB frames, or 2 MiB / 1 GiB huge pages), isolating kernel space alongside the GDT and Local APIC / IOAPIC interrupt controllers.
Interrupt Descriptor Table (IDT) Configuration
When a hardware timer fires or a page fault occurs, the CPU jumps to a vector table indexed by the IDT. Rust handles this cleanly through the x86-interrupt ABI:
extern "x86-interrupt" fn page_fault_handler(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
) {
let fault_address = x86_64::registers::control::Cr2::read();
serial_println!("PAGE FAULT at {:#x}, error: {:?}", fault_address, error_code);
loop { x86_64::instructions::hlt(); }
}
Compile a #![no_std] Rust kernel, build an ELF image, and boot inside the QEMU x86_64 virtualization sandbox.