From 58bf01f1efc9935014bc077a0b4f800efa267bc2 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Thu, 16 Jan 2025 21:43:46 -0500 Subject: [PATCH] Updates to APS segment of Bare-Metal (#2560) --- src/bare-metal/aps.md | 17 ++++++++++++----- src/bare-metal/aps/examples/entry.S | 18 +++++++++++++----- src/bare-metal/aps/inline-assembly.md | 4 ++++ src/bare-metal/aps/mmio.md | 3 ++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/bare-metal/aps.md b/src/bare-metal/aps.md index 82ebf7f5..d73661fd 100644 --- a/src/bare-metal/aps.md +++ b/src/bare-metal/aps.md @@ -4,18 +4,25 @@ session: Afternoon # Application processors -So far we've talked about microcontrollers, such as the Arm Cortex-M series. Now -let's try writing something for Cortex-A. For simplicity we'll just work with -QEMU's aarch64 +So far we've talked about microcontrollers, such as the Arm Cortex-M series. +These are typically small systems with very limited resources. + +Larger systems with more resources are typically called application processors, +built around processors such as the ARM Cortex-A or Intel Atom. + +For simplicity we'll just work with QEMU's aarch64 ['virt'](https://qemu-project.gitlab.io/qemu/system/arm/virt.html) board.
- Broadly speaking, microcontrollers don't have an MMU or multiple levels of - privilege (exception levels on Arm CPUs, rings on x86), while application - processors do. + privilege (exception levels on Arm CPUs, rings on x86). +- Application processors have more resources, and often run an operating system, + instead of directly executing the target application on startup. - QEMU supports emulating various different machines or board models for each architecture. The 'virt' board doesn't correspond to any particular real hardware, but is designed purely for virtual machines. +- We will still address this board as bare-metal, as if we were writing an + operating system.
diff --git a/src/bare-metal/aps/examples/entry.S b/src/bare-metal/aps/examples/entry.S index 387a4024..b302e7c6 100644 --- a/src/bare-metal/aps/examples/entry.S +++ b/src/bare-metal/aps/examples/entry.S @@ -77,15 +77,23 @@ .set .Lsctlrval, .L_SCTLR_ELx_M | .L_SCTLR_ELx_C | .L_SCTLR_ELx_SA | .L_SCTLR_EL1_ITD | .L_SCTLR_EL1_SED .set .Lsctlrval, .Lsctlrval | .L_SCTLR_ELx_I | .L_SCTLR_EL1_SPAN | .L_SCTLR_EL1_RES1 +// ANCHOR: entry /** * This is a generic entry point for an image. It carries out the * operations required to prepare the loaded image to be run. - * Specifically, it zeroes the bss section using registers x25 and - * above, prepares the stack, enables floating point, and sets up the - * exception vector. It preserves x0-x3 for the Rust entry point, as - * these may contain boot parameters. + * Specifically, it + * + * - sets up the MMU with an identity map of virtual to physical + * addresses, and enables caching + * - enables floating point + * - zeroes the bss section using registers x25 and above + * - prepares the stack, pointing to a section within the image + * - sets up the exception vector + * - branches to the Rust `main` function + * + * It preserves x0-x3 for the Rust entry point, as these may contain + * boot parameters. */ -// ANCHOR: entry .section .init.entry, "ax" .global entry entry: diff --git a/src/bare-metal/aps/inline-assembly.md b/src/bare-metal/aps/inline-assembly.md index 3b14f0f2..94d0b823 100644 --- a/src/bare-metal/aps/inline-assembly.md +++ b/src/bare-metal/aps/inline-assembly.md @@ -22,6 +22,10 @@ for all these functions.) contents of the registers. - This `main` function needs to be `#[unsafe(no_mangle)]` and `extern "C"` because it is called from our entry point in `entry.S`. + - Just `#[no_mangle]` would be sufficient but + [RFC3325](https://rust-lang.github.io/rfcs/3325-unsafe-attributes.html) uses + this notation to draw reviewer attention to attributes which might cause + undesired behavior if used incorrectly. - `_x0`–`_x3` are the values of registers `x0`–`x3`, which are conventionally used by the bootloader to pass things like a pointer to the device tree. According to the standard aarch64 calling convention (which is what diff --git a/src/bare-metal/aps/mmio.md b/src/bare-metal/aps/mmio.md index 1375aa8e..72cc083f 100644 --- a/src/bare-metal/aps/mmio.md +++ b/src/bare-metal/aps/mmio.md @@ -1,7 +1,8 @@ # Volatile memory access for MMIO - Use [`pointer::read_volatile`] and [`pointer::write_volatile`]. -- Never hold a reference. +- Never hold a reference to a location being accessed with these methods. Rust + may read from (or write to, for `&mut`) a reference at any time. - Use `&raw` to get fields of structs without creating an intermediate reference.