aarch64-rt
aarch64-rt crate は、以前に実装したアセンブリのエントリポイントと例外ベクターを提供します。必要なのは、entry! マクロで main 関数をマークすることだけです。
また、以前のようにアセンブリコードで定義するのではなく、Rust で初期の静的ページテーブルを定義できる initial_pagetable! マクロも提供します。
さらに、独自に実装する代わりに、arm-pl011-uart crate の UART ドライバーも使用できます。
// Copyright 2025 Google LLC // SPDX-License-Identifier: Apache-2.0 #![no_main] #![no_std] mod exceptions_rt; use aarch64_paging::descriptor::El1Attributes; use aarch64_rt::{InitialPagetable, entry, initial_pagetable}; use arm_pl011_uart::{PL011Registers, Uart, UniqueMmioPointer}; use core::fmt::Write; use core::panic::PanicInfo; use core::ptr::NonNull; use smccc::Hvc; use smccc::psci::system_off; /// Base address of the primary PL011 UART. const PL011_BASE_ADDRESS: NonNull<PL011Registers> = NonNull::new(0x900_0000 as _).unwrap(); /// Attributes to use for device memory in the initial identity map. const DEVICE_ATTRIBUTES: El1Attributes = El1Attributes::VALID .union(El1Attributes::ATTRIBUTE_INDEX_0) .union(El1Attributes::ACCESSED) .union(El1Attributes::UXN); /// Attributes to use for normal memory in the initial identity map. const MEMORY_ATTRIBUTES: El1Attributes = El1Attributes::VALID .union(El1Attributes::ATTRIBUTE_INDEX_1) .union(El1Attributes::INNER_SHAREABLE) .union(El1Attributes::ACCESSED) .union(El1Attributes::NON_GLOBAL); initial_pagetable!({ let mut idmap = [0; 512]; // 1 GiB of device memory. idmap[0] = DEVICE_ATTRIBUTES.bits(); // 1 GiB of normal memory. idmap[1] = MEMORY_ATTRIBUTES.bits() | 0x40000000; // Another 1 GiB of device memory starting at 256 GiB. idmap[256] = DEVICE_ATTRIBUTES.bits() | 0x4000000000; InitialPagetable(idmap) }); entry!(main); fn main(x0: u64, x1: u64, x2: u64, x3: u64) -> ! { // SAFETY: `PL011_BASE_ADDRESS` is the base address of a PL011 device, and // nothing else accesses that address range. let mut uart = unsafe { Uart::new(UniqueMmioPointer::new(PL011_BASE_ADDRESS)) }; writeln!(uart, "main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})").unwrap(); system_off::<Hvc>().unwrap(); panic!("system_off returned"); } #[panic_handler] fn panic(_info: &PanicInfo) -> ! { system_off::<Hvc>().unwrap(); loop {} }
src/bare-metal/aps/examplesでmake qemu_rtを実行して、このサンプルを QEMU で動かします。