mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-03-22 14:59:37 +02:00
APS updates (#2528)
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.
This commit is contained in:
parent
3764569198
commit
c04d2860e8
@ -336,6 +336,7 @@
|
|||||||
- [MMIO](bare-metal/aps/mmio.md)
|
- [MMIO](bare-metal/aps/mmio.md)
|
||||||
- [Let's Write a UART Driver](bare-metal/aps/uart.md)
|
- [Let's Write a UART Driver](bare-metal/aps/uart.md)
|
||||||
- [More Traits](bare-metal/aps/uart/traits.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)
|
- [A Better UART Driver](bare-metal/aps/better-uart.md)
|
||||||
- [Bitflags](bare-metal/aps/better-uart/bitflags.md)
|
- [Bitflags](bare-metal/aps/better-uart/bitflags.md)
|
||||||
- [Multiple Registers](bare-metal/aps/better-uart/registers.md)
|
- [Multiple Registers](bare-metal/aps/better-uart/registers.md)
|
||||||
|
@ -9,9 +9,6 @@ echo incoming bytes.
|
|||||||
|
|
||||||
<details>
|
<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`.
|
- Run the example in QEMU with `make qemu` under `src/bare-metal/aps/examples`.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@ -8,6 +8,10 @@ Before we can start running Rust code, we need to do some initialisation.
|
|||||||
|
|
||||||
<details>
|
<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,
|
- This is the same as it would be for C: initialising the processor state,
|
||||||
zeroing the BSS, and setting up the stack pointer.
|
zeroing the BSS, and setting up the stack pointer.
|
||||||
- The BSS (block starting symbol, for historical reasons) is the part of the
|
- The BSS (block starting symbol, for historical reasons) is the part of the
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use core::fmt::{self, Write};
|
use core::fmt::{self, Write};
|
||||||
|
|
||||||
|
@ -9,8 +9,9 @@ We can do this by implementing the `Log` trait.
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
- The unwrap in `log` is safe because we initialise `LOGGER` before calling
|
- The first unwrap in `log` will succeed because we initialise `LOGGER` before
|
||||||
`set_logger`.
|
calling `set_logger`. The second will succeed because `Uart::write_str` always
|
||||||
|
returns `Ok`.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -5,6 +5,16 @@
|
|||||||
- Use `&raw` to get fields of structs without creating an intermediate
|
- Use `&raw` to get fields of structs without creating an intermediate
|
||||||
reference.
|
reference.
|
||||||
|
|
||||||
|
```rust,editable,ignore
|
||||||
|
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::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
|
[`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
|
[`addr_of!`]: https://doc.rust-lang.org/stable/core/ptr/macro.addr_of.html
|
||||||
|
@ -15,17 +15,8 @@
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- The RaspberryPi OS tutorial runs Rust code before the MMU and caches are
|
- 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:
|
enabled. This will read and write memory (e.g. the stack). However, this has
|
||||||
- Without the MMU and cache, unaligned accesses will fault. It builds with
|
the problems mentioned at the beginning of this session regarding unaligned
|
||||||
`aarch64-unknown-none` which sets `+strict-align` to prevent the compiler
|
access and cache coherency.
|
||||||
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.
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@ -11,7 +11,8 @@ too.
|
|||||||
|
|
||||||
- Implementing `Write` lets us use the `write!` and `writeln!` macros with our
|
- Implementing `Write` lets us use the `write!` and `writeln!` macros with our
|
||||||
`Uart` type.
|
`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>
|
</details>
|
||||||
|
17
src/bare-metal/aps/uart/using.md
Normal file
17
src/bare-metal/aps/uart/using.md
Normal file
@ -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>
|
@ -1,4 +1,4 @@
|
|||||||
# Useful crates
|
# 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.
|
programming.
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
# `buddy_system_allocator`
|
# `buddy_system_allocator`
|
||||||
|
|
||||||
[`buddy_system_allocator`][1] is a crate implementing a basic buddy system
|
[`buddy_system_allocator`][1] is a crate implementing a basic buddy system
|
||||||
allocator. It can be used both for [`LockedHeap`][2] implementing
|
allocator. It can be used both to implement [`GlobalAlloc`][3] (using
|
||||||
[`GlobalAlloc`][3] so you can use the standard `alloc` crate (as we saw
|
[`LockedHeap`][2]) so you can use the standard `alloc` crate (as we saw
|
||||||
[before][4]), or for allocating other address space. For example, we might want
|
[before][4]), or for allocating other address space (using
|
||||||
to allocate MMIO space for PCI BARs:
|
[`FrameAllocator`][5]) . For example, we might want to allocate MMIO space for
|
||||||
|
PCI BARs:
|
||||||
|
|
||||||
<!-- mdbook-xgettext: skip -->
|
<!-- mdbook-xgettext: skip -->
|
||||||
|
|
||||||
@ -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
|
[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
|
[3]: https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html
|
||||||
[4]: ../alloc.md
|
[4]: ../alloc.md
|
||||||
|
[5]: https://docs.rs/buddy_system_allocator/0.9.0/buddy_system_allocator/struct.FrameAllocator.html
|
||||||
|
@ -12,12 +12,12 @@ primitives.
|
|||||||
```rust,editable,compile_fail
|
```rust,editable,compile_fail
|
||||||
use spin::mutex::SpinMutex;
|
use spin::mutex::SpinMutex;
|
||||||
|
|
||||||
static counter: SpinMutex<u32> = SpinMutex::new(0);
|
static COUNTER: SpinMutex<u32> = SpinMutex::new(0);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("count: {}", counter.lock());
|
println!("count: {}", COUNTER.lock());
|
||||||
*counter.lock() += 2;
|
*COUNTER.lock() += 2;
|
||||||
println!("count: {}", counter.lock());
|
println!("count: {}", COUNTER.lock());
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user