Serial Logging Library (serial_logging)
This crate provides robust serial port logging for x86_64 kernel and bootloader development, with a strong focus on QEMU-based debugging. It enables formatted and raw output to the serial port (COM1, 0x3F8), making it possible to see kernel logs even before graphics or higher-level output is available.
Overview
Serial logging is a critical tool for OS developers, especially in early boot stages or when debugging in virtual machines like QEMU. This library offers:
- Macros for formatted serial output (
serial_print!,serial_println!,serial_log!, etc.). - Log level support (info, warning, error, hex output).
- A minimal, dependency-free
kprint!macro for very early boot orno_stdcontexts. - Thread-safe output using a spinlock and the
uart_16550crate. - Runtime enable/disable of logging.
All output is sent to the first serial port (COM1, 0x3F8), which QEMU can redirect to your terminal or a file for easy debugging.
Why Serial Logging?
- Early Debugging: Serial output works before graphics or even memory allocators are initialized.
- QEMU Integration: QEMU can redirect serial output to your terminal with
-serial stdio, making it easy to see kernel logs in real time. - Minimal Dependencies: The
kprint!macro works with onlycore::fmt, making it ideal for the earliest boot stages. - Thread Safety: The main driver uses a spinlock to ensure output is not garbled by concurrent writes.
Features
- Formatted Output: Use Rust-style formatting macros for serial output.
- Log Levels: Macros for info, warning, error, and hex output.
- Minimal Output:
kprint!for direct, dependency-free serial output. - Enable/Disable Logging: Control output at runtime for silent or verbose modes.
- QEMU-Friendly: Designed for use with QEMU's
-serial stdioor-serial file:...options.
How to Use in OS Development
1. Add as a Dependency
If using as part of a workspace:
[]
= { = "../serial_logging" }
2. QEMU Setup
Run QEMU with serial redirection to see logs in your terminal:
3. Basic Usage in Kernel Code
use *;
serial_println!;
serial_log!;
info;
warn;
error!;
4. Early Boot Output
For output before the main serial driver is initialized, use the minimal macro:
kprint!;
This writes directly to the serial port using inline assembly and does not require the full driver or any heap.
Implementation Details
- Serial Port: Uses
uart_16550for main output, and direct port I/O forkprint!. - Thread Safety: Uses a spinlock (
spin::Mutex) to guard the serial port. - No-Std: Fully compatible with
#![no_std]environments. - Macros: Provide both high-level (formatted, log-level) and low-level (raw) output.
- Runtime Control: Logging can be enabled or disabled at runtime.
When to Use This Library
- Writing a custom OS kernel or bootloader in Rust for x86_64 hardware.
- Need to debug early boot code or kernel logic in QEMU or other VMs.
- Require output before graphics or higher-level drivers are available.
- Want thread-safe, formatted logging in a
no_stdenvironment.
License
This crate is licensed under the zlib License. See the root LICENSE file for details.
References & Acknowledgments
For questions or contributions, see the main Polished OS repository.