source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+[[package]]
+name = "buddy_system_allocator"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d44d578cadd17312c75e7d0ef489361f160ace58f7139aa32001fee1a51b89b5"
+dependencies = [
+ "spin",
+]
+
[[package]]
name = "lock_api"
version = "0.4.12"
name = "riscv"
version = "0.1.0"
dependencies = [
+ "buddy_system_allocator",
"spinning_top",
"uart_16550",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
[[package]]
name = "spinning_top"
version = "0.3.0"
target = "riscv64gc-unknown-none-elf"
[dependencies]
+buddy_system_allocator = "0.9.1"
spinning_top = "0.3.0"
uart_16550 = "0.3.0"
--- /dev/null
+
+
+use buddy_system_allocator::LockedHeap;
+
+// The recommended order for the heap is 32, which to me says the largest
+// block size would be 2^32, or 4GiB. We don't actually have that available
+// but at the same time, when I tried to reduce the order down to 16 the init
+// simply stalled out. So...32 is is. ((shrug))
+
+#[global_allocator]
+static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::empty();
+
+pub unsafe fn init() {
+ let heap_start: usize;
+ let heap_size: usize;
+ // UNSAFE: This is fine, just loading some constants.
+ unsafe {
+ // using inline assembly is easier to access linker constants
+ use core::arch::asm;
+ asm!(
+ "la {heap_start}, _heap_start",
+ "la {heap_size}, _heap_size",
+ heap_start = out(reg) heap_start,
+ heap_size = out(reg) heap_size,
+ options(nomem)
+ )
+ };
+ println!("Kernel heap symbols: start: {:#x}, size: {}", heap_start, heap_size);
+
+ unsafe { HEAP_ALLOCATOR.lock().init(heap_start, heap_size); }
+}
*(.sbss .sbss.*) *(.bss .bss.*)
PROVIDE(_bss_end = .); # ... and one at the end
} >RAM AT>RAM :bss # and this goes into the bss segment
-
+ PROVIDE(_kernel_end = .);
+
+ # heap reserved space starts where the kernel ends and
+ # continues until it reaches the stack. Because the stack
+ # is a fixed size, as the kernel grows, the heap will shrink
+ PROVIDE(_heap_start = .);
+ PROVIDE(_heap_size = _stack_bottom - _heap_start);
+
# start the stack at the end of memory and let it grow downward
+ # capped at 1M
+ PROVIDE(_stack_bottom = ORIGIN(RAM) + LENGTH(RAM) - 1M);
PROVIDE(_stack_top = ORIGIN(RAM) + LENGTH(RAM));
}
#![no_main]
#![feature(naked_functions)] // enable functions that are pure inline assembly
+#[macro_use]
mod console;
+mod heap;
use core::panic::PanicInfo;
#[no_mangle] // Again, being mindful of the C calling convention
extern "C" fn entry() -> ! {
+ // Init serial console
use crate::console;
console::init_console();
println!("KIT-- hello works from println!");
+
+ // Init heap
+ use crate::heap;
+ // Safety: initialize once (and that's done now)
+ unsafe { heap::init() };
+
+ println!("Kernel init complete");
loop {}
}