Initializing heap

This commit is contained in:
gil 2024-05-14 10:03:08 -05:00
parent f43f41800f
commit c22e3e4376
6 changed files with 77 additions and 1 deletions

21
Cargo.lock generated
View file

@ -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"

View file

@ -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
View 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) };
}

View file

@ -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

View file

@ -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
}

View file

@ -1,3 +1,4 @@
// src/uart.rs
//! This module provides access to the UART console.
use spinning_top::Spinlock;