Guidelines for AI agents working on Phoenix, a bare-metal AArch64 kernel in Rust.
Bare-metal AArch64 kernel with:
no_stdandno_mainfor bare-metal targets- High-half virtual addressing (0xffffff8000000000)
- Assembly boot code with EL initialization and MMU setup
- Custom linker script for kernel memory layout
- Conditional compilation for host vs bare-metal
- Linux-style memblock boot-time allocator
- Thread-safe memory management with spin locks
- Primary:
aarch64-unknown-none(bare-metal AArch64) - Host: Native for development/testing
# Build for bare-metal AArch64
cargo build --target aarch64-unknown-none
# Build for host (development)
cargo build
# Release build for AArch64
cargo build --target aarch64-unknown-none --release
# Check code without building
cargo check --target aarch64-unknown-none
# Clean build artifacts
cargo clean.cargo/config.toml: Target-specific rustflags with custom linker scriptbuild.rs: Tracks architecture-specific file changessrc/arch/aarch64/kernel.ld: Linker script for kernel memory layoutCargo.toml: Includesspin = "0.9"dependency for synchronization
# Run all tests on host
cargo test
# Run a specific test
cargo test test_target_guard
# Run tests with verbose output
cargo test -- --nocapture
# Test for AArch64 target
cargo test --target aarch64-unknown-none- Tests in
#[cfg(test)]modules within source files - Use
assert!,assert_eq!, etc. for assertions - Bare-metal tests may need QEMU/hardware
- Use
#[cfg(all(test, not(target_os = "none")))]for host-only tests
// Core imports first
use core::arch::global_asm;
use core::panic::PanicInfo;
// Module declarations
mod arch;
// External crates- Modules: snake_case (
arch,aarch64) - Functions: snake_case (
kernel_main,panic) - Constants: SCREAMING_SNAKE_CASE (
KERNEL_VIRTUAL_BASE) - Types: PascalCase
- Variables: snake_case
- Bare-metal: Use
panic!for unrecoverable errors - Implement
#[panic_handler]in architecture modules - Panic handlers should loop indefinitely
- Use
spin::Mutexfor thread-safe global data structures - Keep critical sections short to avoid deadlocks
- Document synchronization requirements for shared resources
- Example:
static MEMBLOCK: Mutex<Memblock> = Mutex::new(Memblock::new());
- Follow Linux memblock design: boot-time allocator before buddy system
- Use fixed-size arrays (e.g.,
MAX_REGIONS = 128) to avoid dynamic allocation - Implement core operations:
add(),reserve(),remove(),alloc() - Merge adjacent regions automatically
- Check for overlaps when adding/reserving regions
- Support alignment requirements in
alloc() - Provide global instance via
spin::Mutexfor thread safety
- Mark unsafe blocks with safety comments
- Use
unsafeonly for hardware access, raw pointers - Document memory safety assumptions
unsafe {
// Safety: 0xffff_ff80_0900_0000 is valid MMIO address for serial output
core::ptr::write_volatile(0xffff_ff80_0900_0000 as *mut u8, *byte);
}- Assembly files:
.Sextension (uppercase for preprocessor) - Include with
global_asm!(include_str!("boot.S")) - Add comprehensive comments explaining register operations
#[cfg(target_os = "none")] // Bare-metal code
#[cfg(not(target_os = "none"))] // Host code
#[cfg(target_arch = "aarch64")] // AArch64 specificsrc/
├── main.rs # Entry point with conditional compilation
├── arch/
│ ├── mod.rs # Architecture selector
│ └── aarch64/
│ ├── mod.rs # AArch64 implementation
│ ├── boot.S # Assembly boot code
│ └── kernel.ld # Linker script
├── mm/
│ ├── mod.rs # Memory management module
│ └── memblock.rs # Boot-time allocator implementation
- Each architecture in
src/arch/<arch-name>/ - Conditionally compile with
#[cfg(target_arch = "...")] - Assembly needs detailed ARM system register comments
- Linker scripts define memory layout
rustup target add aarch64-unknown-nonecargo objdump --target aarch64-unknown-none -- -dfor disassembly- Serial: 0xffff_ff80_0900_0000
cargo clippy --target aarch64-unknown-none
cargo fmt- Unsafe blocks with safety comments
- Correct conditional compilation
- Architecture-appropriate placement
- Well-commented assembly
- No std in bare-metal code
- Linker script matches memory map
- Use conventional commits:
feat:,fix:,chore:,docs:,test: - Reference architecture when applicable
- Keep commits focused on single logical changes
Project: Phoenix AArch64 Kernel