Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Kernel Panics

A kernel panic is when a fault occurs in the kernel resulting in the halting of operations. Quite simply, if something goes wrong, we print a message and start an infinite loop to stop the CPU from doing any more damage.

Not all panics are equal though. Some errors are severe enough to warrant a full halt — corrupted memory, invalid CPU state, unrecoverable hardware faults. Others are recoverable — a failed allocation, an invalid argument, a missing resource. So we implement two versions.

Fatal Panic

This is the non-recoverable version. When this occurs there has to be a definite stop, resulting in the user physically restarting the kernel. The -> ! return type tells Rust this function never returns.

#![allow(unused)]
fn main() {
pub fn kernel_panic(msg: &str) -> ! {
    writer().printc("\n\n!!! KERNEL PANIC !!!", Color::White, Color::Red);
    println!("{}", msg);
    loop {}
}
}

This is also tied to Rust’s #[panic_handler] — a required function in any no_std environment that tells the compiler what to do when a Rust panic!() fires. Without it, the kernel won’t compile. We hook it into kernel_panic so there’s only one code path:

#![allow(unused)]
fn main() {
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
    kernel_panic(info.message().as_str().unwrap_or("unknown panic"));
}
}

info.message().as_str() extracts the panic message as a string slice. The .unwrap_or("unknown panic") is a fallback in case no message was provided — for example a bare panic!() with no arguments.

Non-Fatal Panic

In this version, we are simply notifying that an error has occurred but the severity is low enough to allow the CPU to proceed. Good candidates for this are things like failed allocations or invalid input — situations where the caller might be able to recover.

#![allow(unused)]
fn main() {
pub fn kernel_warn(msg: &str) {
    writer().printc("\n\n!!! KERNEL WARNING !!!", Color::Black, Color::Yellow);
    println!("{}", msg);
}
}

The key difference from kernel_panic is that this function returns normally, letting execution continue. No loop {}, no -> !.