Initializing heap
This commit is contained in:
parent
f43f41800f
commit
c22e3e4376
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -12,7 +12,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
|||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"spinning_top",
|
||||
"linked_list_allocator",
|
||||
"spinning_top 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
|
||||
dependencies = [
|
||||
"spinning_top 0.2.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -31,6 +41,15 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "spinning_top"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spinning_top"
|
||||
version = "0.3.0"
|
||||
|
|
|
@ -4,4 +4,5 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
linked_list_allocator = "0.10.5"
|
||||
spinning_top = "0.3.0"
|
||||
|
|
36
src/heap.rs
Normal file
36
src/heap.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
// src/heap.rs
|
||||
//! Provides the kernel heap.
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use linked_list_allocator::LockedHeap;
|
||||
|
||||
use crate::println;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||
|
||||
/// Initialise the kernel heap.
|
||||
/// # Safety
|
||||
/// Must be called at most once.
|
||||
pub unsafe fn init() {
|
||||
let heap_bottom;
|
||||
let heap_size;
|
||||
// UNSAFE: This is fine, just loading some constants.
|
||||
unsafe {
|
||||
// using inline assembly is easier to access linker constants
|
||||
asm!(
|
||||
"la {heap_bottom}, _kernel_heap_bottom",
|
||||
"la {heap_size}, _kernel_heap_size",
|
||||
heap_bottom = out(reg) heap_bottom,
|
||||
heap_size = out(reg) heap_size,
|
||||
options(nomem)
|
||||
)
|
||||
};
|
||||
println!(
|
||||
"Initialising kernel heap (bottom: {:#x}, size: {:#x})",
|
||||
heap_bottom as usize, heap_size
|
||||
);
|
||||
// UNSAFE: Fine to call at most once.
|
||||
unsafe { ALLOCATOR.lock().init(heap_bottom, heap_size) };
|
||||
}
|
15
src/main.rs
15
src/main.rs
|
@ -1,9 +1,11 @@
|
|||
// src/main.rs
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(naked_functions)]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
mod heap;
|
||||
mod uart;
|
||||
|
||||
#[naked]
|
||||
|
@ -43,6 +45,17 @@ unsafe extern "C" fn _start() -> ! {
|
|||
}
|
||||
|
||||
extern "C" fn entry() -> ! {
|
||||
// UNSAFE: Called exactly once, right here.
|
||||
unsafe { heap::init() };
|
||||
|
||||
// Now we're free to use dynamic allocation!
|
||||
{
|
||||
extern crate alloc;
|
||||
use alloc::boxed::Box;
|
||||
let _my_heap_pointer = Box::new(10);
|
||||
// _my_heap_pointer lives on the heap!
|
||||
}
|
||||
|
||||
println!("This should not print because the console is not initialised.");
|
||||
unsafe { uart::init_console(0x1000_0000) };
|
||||
println!("Hello, world!");
|
||||
|
@ -59,3 +72,5 @@ extern "C" fn entry() -> ! {
|
|||
fn on_panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
// TODO unit testing
|
|
@ -39,4 +39,8 @@ SECTIONS {
|
|||
|
||||
. = ALIGN(16); # our stack needs to be 16-byte aligned, per the C calling convention
|
||||
PROVIDE(_init_stack_top = . + 0x1000); # reserve 0x1000 bytes for the initialisation stack
|
||||
|
||||
PROVIDE(_kernel_heap_bottom = _init_stack_top); # allocate heap to remaining physical memory
|
||||
PROVIDE(_kernel_heap_top = ORIGIN(ram) + LENGTH(ram)); # top of heap is end of ram
|
||||
PROVIDE(_kernel_heap_size = _kernel_heap_top - _kernel_heap_bottom); # capture size of heap
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// src/uart.rs
|
||||
//! This module provides access to the UART console.
|
||||
|
||||
use spinning_top::Spinlock;
|
||||
|
|
Loading…
Reference in a new issue