diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 10d36277..de770f3c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -238,8 +238,7 @@ - [Welcome](welcome-bare-metal.md) - [`no_std`](bare-metal/no_std.md) - [A minimal example](bare-metal/minimal.md) - - [`core`]() - - [`alloc`]() + - [`alloc`](bare-metal/alloc.md) - [Microcontrollers]() - [PACs]() - [HAL crates]() diff --git a/src/bare-metal/alloc-example/.cargo/config.toml b/src/bare-metal/alloc-example/.cargo/config.toml new file mode 100644 index 00000000..724febae --- /dev/null +++ b/src/bare-metal/alloc-example/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "aarch64-unknown-none" diff --git a/src/bare-metal/alloc-example/Cargo.lock b/src/bare-metal/alloc-example/Cargo.lock new file mode 100644 index 00000000..22cfc3db --- /dev/null +++ b/src/bare-metal/alloc-example/Cargo.lock @@ -0,0 +1,57 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "alloc-example" +version = "0.1.0" +dependencies = [ + "buddy_system_allocator", + "panic-halt", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "buddy_system_allocator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f9365b6b0c9e1663ca4ca9440c00eda46bc85a3407070be8b5e0d8d1f29629" +dependencies = [ + "spin", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "panic-halt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] diff --git a/src/bare-metal/alloc-example/Cargo.toml b/src/bare-metal/alloc-example/Cargo.toml new file mode 100644 index 00000000..b63a223c --- /dev/null +++ b/src/bare-metal/alloc-example/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "alloc-example" +version = "0.1.0" +edition = "2021" + +[dependencies] +buddy_system_allocator = "0.9.0" +panic-halt = "0.2.0" + +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" diff --git a/src/bare-metal/alloc-example/rust-toolchain.toml b/src/bare-metal/alloc-example/rust-toolchain.toml new file mode 100644 index 00000000..ce4bff11 --- /dev/null +++ b/src/bare-metal/alloc-example/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "beta" diff --git a/src/bare-metal/alloc-example/src/main.rs b/src/bare-metal/alloc-example/src/main.rs new file mode 100644 index 00000000..7ec0f0b2 --- /dev/null +++ b/src/bare-metal/alloc-example/src/main.rs @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// 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. + +// ANCHOR: Alloc +#![no_main] +#![no_std] + +extern crate alloc; + +use alloc::{string::ToString, vec::Vec}; +use core::panic::PanicInfo; +use buddy_system_allocator::LockedHeap; + +#[global_allocator] +static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new(); + +static mut HEAP: [u8; 65536] = [0; 65536]; + +pub fn entry() { + // Safe because `HEAP` is only used here and `entry` is only called once. + unsafe { + // Give the allocator some memory to allocate. + HEAP_ALLOCATOR + .lock() + .init(HEAP.as_mut_ptr() as usize, HEAP.len()); + } + + // Now we can do things that require heap allocation. + let mut v = Vec::new(); + v.push("A string".to_string()); +} +// ANCHOR_END: Alloc + +#[panic_handler] +fn panic(_panic: &PanicInfo) -> ! { + loop {} +} diff --git a/src/bare-metal/alloc.md b/src/bare-metal/alloc.md new file mode 100644 index 00000000..50889a5d --- /dev/null +++ b/src/bare-metal/alloc.md @@ -0,0 +1,16 @@ +# `alloc` + +To use `alloc` you must implement a global (heap) allocator. + +```rust,editable +{{#include alloc-example/src/main.rs:Alloc}} +``` + +
+ +* `buddy_system_allocator` is a third-party crate implementing a basic buddy system allocator. Other + crates are available, or you can write your own or hook into your existing allocator. +* The const parameter of `LockedHeap` is the max order of the allocator; i.e. in this case it can + allocate regions of up to 2**32 bytes. + +