Skip to content

Commit 59068a9

Browse files
retragerbradford
authored andcommitted
efi: Add GlobalAlloc for heap allocation support
Rust requires GlobalAlloc implementation to use heap allocated standard library features. This firmware already has a dedicated page allocator for EFI, but not implemented to satisfy GlobalAlloc trait bounds. This commit introduces GlobalAlloc using linked_list_allocator crate. The page allocator allocates 256 MiB for the heap allocator during the initialization. Signed-off-by: Akira Moroo <retrage01@gmail.com>
1 parent 5abb3f1 commit 59068a9

File tree

8 files changed

+60
-7
lines changed

8 files changed

+60
-7
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ install:
2020
- ./make-test-disks.sh
2121

2222
script:
23-
- cargo build --target target.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem
24-
- cargo build --release --target target.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem
25-
- cargo clippy --target target.json -Zbuild-std=core
23+
- cargo build --target target.json -Zbuild-std=core,alloc -Zbuild-std-features=compiler-builtins-mem
24+
- cargo build --release --target target.json -Zbuild-std=core,alloc -Zbuild-std-features=compiler-builtins-mem
25+
- cargo clippy --target target.json -Zbuild-std=core,alloc
2626
- cargo clippy --all-targets --all-features
2727
- cargo fmt --all -- --check
2828
- cargo test

Cargo.lock

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ x86_64 = "0.13.1"
3030
atomic_refcell = "0.1"
3131
r-efi = "3.2.0"
3232
uart_16550 = "0.2.10"
33+
linked_list_allocator = "0.8.11"
3334

3435
[dev-dependencies]
3536
rand = "0.8.2"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ all the way into the OS.
2424

2525
To compile:
2626

27-
cargo build --release --target target.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem
27+
cargo build --release --target target.json -Zbuild-std=core,alloc -Zbuild-std-features=compiler-builtins-mem
2828

2929
The result will be in:
3030

run_coreboot_integration_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -xeuf
44
source "${CARGO_HOME:-$HOME/.cargo}/env"
55

66
rustup component add rust-src
7-
cargo build --release --target target.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem --features "coreboot"
7+
cargo build --release --target target.json -Zbuild-std=core,alloc -Zbuild-std-features=compiler-builtins-mem --features "coreboot"
88

99
FW_BIN="$(pwd)/target/target/release/hypervisor-fw"
1010

run_integration_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -xeuf
44
source "${CARGO_HOME:-$HOME/.cargo}/env"
55

66
rustup component add rust-src
7-
cargo build --release --target target.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem
7+
cargo build --release --target target.json -Zbuild-std=core,alloc -Zbuild-std-features=compiler-builtins-mem
88

99
CH_VERSION="v0.8.0"
1010
CH_URL="https://github.com/cloud-hypervisor/cloud-hypervisor/releases/download/$CH_VERSION/cloud-hypervisor"

src/efi/mod.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use core::{ffi::c_void, mem::transmute};
15+
use core::{alloc as heap_alloc, ffi::c_void, mem::transmute};
1616

1717
use atomic_refcell::AtomicRefCell;
18+
use linked_list_allocator::LockedHeap;
1819
use r_efi::{
1920
efi::{
2021
self, AllocateType, Boolean, CapsuleHeader, Char16, Event, EventNotify, Guid, Handle,
@@ -52,6 +53,16 @@ struct HandleWrapper {
5253

5354
pub static ALLOCATOR: AtomicRefCell<Allocator> = AtomicRefCell::new(Allocator::new());
5455

56+
#[cfg(not(test))]
57+
#[global_allocator]
58+
pub static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
59+
60+
#[cfg(not(test))]
61+
#[alloc_error_handler]
62+
fn heap_alloc_error_handler(layout: heap_alloc::Layout) -> ! {
63+
panic!("heap allocation error: {:?}", layout);
64+
}
65+
5566
static mut RS: efi::RuntimeServices = efi::RuntimeServices {
5667
hdr: efi::TableHeader {
5768
signature: efi::RUNTIME_SERVICES_SIGNATURE,
@@ -722,6 +733,7 @@ extern "win64" fn image_unload(_: Handle) -> Status {
722733
}
723734

724735
const PAGE_SIZE: u64 = 4096;
736+
const HEAP_SIZE: usize = 256 * 1024 * 1024;
725737

726738
// Populate allocator from E820, fixed ranges for the firmware and the loaded binary.
727739
fn populate_allocator(info: &dyn boot::Info, image_address: u64, image_size: u64) {
@@ -752,8 +764,28 @@ fn populate_allocator(info: &dyn boot::Info, image_address: u64, image_size: u64
752764
image_size / PAGE_SIZE,
753765
image_address,
754766
);
767+
768+
// Initialize heap allocator
769+
init_heap_allocator(HEAP_SIZE);
770+
}
771+
772+
#[cfg(not(test))]
773+
fn init_heap_allocator(size: usize) {
774+
let (status, heap_start) = ALLOCATOR.borrow_mut().allocate_pages(
775+
AllocateType::AllocateAnyPages,
776+
MemoryType::BootServicesCode,
777+
size as u64 / PAGE_SIZE,
778+
0,
779+
);
780+
assert!(status == Status::SUCCESS);
781+
unsafe {
782+
HEAP_ALLOCATOR.lock().init(heap_start as usize, size);
783+
}
755784
}
756785

786+
#[cfg(test)]
787+
fn init_heap_allocator(_: usize) {}
788+
757789
#[repr(C)]
758790
struct LoadedImageWrapper {
759791
hw: HandleWrapper,

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#![feature(alloc_error_handler)]
1516
#![feature(global_asm, const_in_array_repeat_expressions)]
1617
#![cfg_attr(not(test), no_std)]
1718
#![cfg_attr(not(test), no_main)]

0 commit comments

Comments
 (0)