1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-03-19 22:19:29 +02:00

Updates to APS segment of Bare-Metal (#2560)

This commit is contained in:
Dustin J. Mitchell 2025-01-16 21:43:46 -05:00 committed by GitHub
parent 5af4a74591
commit 58bf01f1ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 31 additions and 11 deletions

View File

@ -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.
<details>
- 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.
</details>

View File

@ -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:

View File

@ -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

View File

@ -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.