From 538cc327667c3c34cafce420ab9d74303fb2d87e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 18 Apr 2017 14:58:41 +0200 Subject: [PATCH 1/2] A Xargo.toml is required as soon as we use alloc/collections --- blog/content/post/08-kernel-heap.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/blog/content/post/08-kernel-heap.md b/blog/content/post/08-kernel-heap.md index 3cd6d1e4..31b2c1a1 100644 --- a/blog/content/post/08-kernel-heap.md +++ b/blog/content/post/08-kernel-heap.md @@ -307,6 +307,27 @@ The `collections` crate provides the [format!] and [vec!] macros, so we use `#[m [format!]: //doc.rust-lang.org/nightly/collections/macro.format!.html [vec!]: https://doc.rust-lang.org/nightly/collections/macro.vec!.html +When we try to compile it, the following error occurs: + +``` +error[E0463]: can't find crate for `alloc` + --> src/lib.rs:16:1 + | +16 | extern crate alloc; + | ^^^^^^^^^^^^^^^^^^^ can't find crate +``` + +The problem is that [`xargo`] only cross compiles `libcore` by default. To also cross compile the `alloc` and `collections` crates, we need to create a file named `Xargo.toml` in our project root (right next to the `Cargo.toml`) with the following content: + +[`xargo`]: https://github.com/japaric/xargo + +```toml +[target.x86_64-blog_os.dependencies] +collections = {} +``` + +This instructs `xargo` that we also need `collections` and `alloc` (a dependency of `collections`). Now it should compile again. + ### Testing Now we should be able to allocate memory on the heap. Let's try it in our `rust_main`: From f5d9766868106ce2bd7275c7a6b5630287373752 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 18 Apr 2017 14:58:52 +0200 Subject: [PATCH 2/2] Add missing unsafe --- blog/content/post/08-kernel-heap.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/blog/content/post/08-kernel-heap.md b/blog/content/post/08-kernel-heap.md index 31b2c1a1..384b0802 100644 --- a/blog/content/post/08-kernel-heap.md +++ b/blog/content/post/08-kernel-heap.md @@ -715,7 +715,9 @@ extern crate linked_list_allocator; pub const HEAP_START: usize = 0o_000_001_000_000_0000; pub const HEAP_SIZE: usize = 100 * 1024; // 100 KiB -static HEAP: Mutex = Mutex::new(Heap::new(HEAP_START, HEAP_SIZE)); +static HEAP: Mutex = Mutex::new(unsafe { + Heap::new(HEAP_START, HEAP_SIZE) +}); ``` Note that we use the same values for `HEAP_START` and `HEAP_SIZE` as in the `bump_allocator`. @@ -729,10 +731,12 @@ We need to add the extern crates to our `Cargo.toml`: However, we get an error when we try to compile it: ``` -error: function calls in statics are limited to constant functions, - struct and enum constructors [E0015] -static HEAP: Mutex = Mutex::new(Heap::new(HEAP_START, HEAP_SIZE)); - ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +error[E0015]: calls in statics are limited to constant functions, + struct and enum constructors + --> src/lib.rs:17:5 + | +17 | Heap::new(HEAP_START, HEAP_SIZE) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` The reason is that the `Heap::new` function needs to initialize the first hole (like described [above](#initialization)). This can't be done at compile time, so the function can't be a `const` function. Therefore we can't use it to initialize a static.