Skip to content

Commit

Permalink
Minor updates to bare-metal afternoon session
Browse files Browse the repository at this point in the history
These are some minor updates from walking through the session myself.

 * Add some context to the `entry.S` slide, which is otherwise a bit
   terrifying for someone who does not speak ARM assembly.
 * Include a simple, fake example of MMIO.
 * Add a "Using It" section to the minimal UART segment, parallel to the
   better UART
 * Better explanation of the `unwrap` calls in the logging example.
   Unwrap is never "unsafe", so remove that word.
 * Allow dead code in some `.rs` files.
 * Remove redundant warning about use of memory before MMU setup.
 * Rephase text about buddy-system
 * Fix lint warning in spin slide.
  • Loading branch information
djmitche committed Jan 7, 2025
1 parent 3764569 commit 23fd0e6
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 28 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@
- [MMIO](bare-metal/aps/mmio.md)
- [Let's Write a UART Driver](bare-metal/aps/uart.md)
- [More Traits](bare-metal/aps/uart/traits.md)
- [Using It](bare-metal/aps/uart/using.md)
- [A Better UART Driver](bare-metal/aps/better-uart.md)
- [Bitflags](bare-metal/aps/better-uart/bitflags.md)
- [Multiple Registers](bare-metal/aps/better-uart/registers.md)
Expand Down
3 changes: 0 additions & 3 deletions src/bare-metal/aps/better-uart/using.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ echo incoming bytes.

<details>

- As in the [inline assembly](../inline-assembly.md) example, this `main`
function is called from our entry point code in `entry.S`. See the speaker
notes there for details.
- Run the example in QEMU with `make qemu` under `src/bare-metal/aps/examples`.

</details>
4 changes: 4 additions & 0 deletions src/bare-metal/aps/entry-point.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Before we can start running Rust code, we need to do some initialisation.

<details>

This code is in `src/bare-metal/aps/examples/entry.S`. It's not necessary to
understand this in detail -- the takeaway is that typically some low-level setup
is needed to meet Rust's expectations of the system.

- This is the same as it would be for C: initialising the processor state,
zeroing the BSS, and setting up the stack pointer.
- The BSS (block starting symbol, for historical reasons) is the part of the
Expand Down
1 change: 1 addition & 0 deletions src/bare-metal/aps/examples/src/pl011.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(dead_code)]

use core::fmt::{self, Write};

Expand Down
5 changes: 3 additions & 2 deletions src/bare-metal/aps/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ We can do this by implementing the `Log` trait.

<details>

- The unwrap in `log` is safe because we initialise `LOGGER` before calling
`set_logger`.
- The first unwrap in `log` will succeed because we initialise `LOGGER` before
calling `set_logger`. The second will succeed because `Uart::write_str` always
returns `Ok`.

</details>

Expand Down
10 changes: 10 additions & 0 deletions src/bare-metal/aps/mmio.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
- Use `&raw` to get fields of structs without creating an intermediate
reference.

```rust
const SOME_DEVICE_REGISTER: *mut u64 = 0x800_0000 as _;
// SAFETY: Some device is mapped at this address.
unsafe {
SOME_DEVICE_REGISTER.write_volatile(0xff);
SOME_DEVICE_REGISTER.write_volatile(0x80);
assert_eq!(SOME_DEVICE_REGISTER.read_volatile(), 0xaa);
}
```

[`pointer::read_volatile`]: https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.read_volatile
[`pointer::write_volatile`]: https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write_volatile
[`addr_of!`]: https://doc.rust-lang.org/stable/core/ptr/macro.addr_of.html
Expand Down
15 changes: 3 additions & 12 deletions src/bare-metal/aps/other-projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,8 @@
<details>

- The RaspberryPi OS tutorial runs Rust code before the MMU and caches are
enabled. This will read and write memory (e.g. the stack). However:
- Without the MMU and cache, unaligned accesses will fault. It builds with
`aarch64-unknown-none` which sets `+strict-align` to prevent the compiler
generating unaligned accesses so it should be alright, but this is not
necessarily the case in general.
- If it were running in a VM, this can lead to cache coherency issues. The
problem is that the VM is accessing memory directly with the cache disabled,
while the host has cacheable aliases to the same memory. Even if the host
doesn't explicitly access the memory, speculative accesses can lead to cache
fills, and then changes from one or the other will get lost. Again this is
alright in this particular case (running directly on the hardware with no
hypervisor), but isn't a good pattern in general.
enabled. This will read and write memory (e.g. the stack). However, this has
the problems mentioned at the beginning of this session regarding unaligned
access and cache coherency.

</details>
5 changes: 3 additions & 2 deletions src/bare-metal/aps/uart/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ too.

- Implementing `Write` lets us use the `write!` and `writeln!` macros with our
`Uart` type.
- Run the example in QEMU with `make qemu_minimal` under
`src/bare-metal/aps/examples`.

- `Send` is an auto-trait, but not implemented automatically because it is not
implemented for pointers.

</details>
17 changes: 17 additions & 0 deletions src/bare-metal/aps/uart/using.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Using it

Let's write a small program using our driver to write to the serial console.

```rust,editable,compile_fail
{{#include ../examples/src/main_minimal.rs:main}}
```

<details>

- As in the [inline assembly](../inline-assembly.md) example, this `main`
function is called from our entry point code in `entry.S`. See the speaker
notes there for details.
- Run the example in QEMU with `make qemu_minimal` under
`src/bare-metal/aps/examples`.

</details>
2 changes: 1 addition & 1 deletion src/bare-metal/useful-crates.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Useful crates

We'll go over a few crates which solve some common problems in bare-metal
We'll look at a few crates which solve some common problems in bare-metal
programming.
10 changes: 6 additions & 4 deletions src/bare-metal/useful-crates/buddy_system_allocator.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# `buddy_system_allocator`

[`buddy_system_allocator`][1] is a crate implementing a basic buddy system
allocator. It can be used both for [`LockedHeap`][2] implementing
[`GlobalAlloc`][3] so you can use the standard `alloc` crate (as we saw
[before][4]), or for allocating other address space. For example, we might want
to allocate MMIO space for PCI BARs:
allocator. It can be used both to implement [`GlobalAlloc`][3] (using
[`LockedHeap`][2]) so you can use the standard `alloc` crate (as we saw
[before][4]), or for allocating other address space (using
[`FrameAllocator`][5]) . For example, we might want to allocate MMIO space for
PCI BARs:

<!-- mdbook-xgettext: skip -->

Expand All @@ -25,3 +26,4 @@ to allocate MMIO space for PCI BARs:
[2]: https://docs.rs/buddy_system_allocator/0.9.0/buddy_system_allocator/struct.LockedHeap.html
[3]: https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html
[4]: ../alloc.md
[5]: https://docs.rs/buddy_system_allocator/0.9.0/buddy_system_allocator/struct.FrameAllocator.html
8 changes: 4 additions & 4 deletions src/bare-metal/useful-crates/spin.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ primitives.
```rust,editable,compile_fail
use spin::mutex::SpinMutex;
static counter: SpinMutex<u32> = SpinMutex::new(0);
static COUNTER: SpinMutex<u32> = SpinMutex::new(0);
fn main() {
println!("count: {}", counter.lock());
*counter.lock() += 2;
println!("count: {}", counter.lock());
println!("count: {}", COUNTER.lock());
*COUNTER.lock() += 2;
println!("count: {}", COUNTER.lock());
}
```

Expand Down

0 comments on commit 23fd0e6

Please sign in to comment.