From ffdcd4524f6940bb1d6d40b45eb7bf8c6f756223 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Thu, 18 Aug 2022 21:11:17 -0700 Subject: Include fixed allocation scheme TODO: Upgrade to queue scheme --- Makefile | 5 +++- src/alloc.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/kernel.rs | 12 ++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/alloc.rs diff --git a/Makefile b/Makefile index 9beb347..d2b6c52 100644 --- a/Makefile +++ b/Makefile @@ -20,10 +20,13 @@ COMPILER_ARGS=--target=$(TARGET) $(FEATURES) --release RUSTC_CMD=cargo rustc $(COMPILER_ARGS) export LINKER_FILE -.PHONY: build clean +.PHONY: build clean run build: @RUSTFLAGS="$(RUSTFLAGS_PEDANTIC)" $(RUSTC_CMD) clean: rm -rf target + +run: build + qemu-system-arm -cpu cortex-a7 -m 1G -kernel target/armv7a-none-eabi/release/kernel -machine raspi2b -serial mon:stdio -nographic diff --git a/src/alloc.rs b/src/alloc.rs new file mode 100644 index 0000000..4fe44ee --- /dev/null +++ b/src/alloc.rs @@ -0,0 +1,92 @@ +use crate::sync::NullLock; +use crate::sync::interface::Mutex; + +const CHAR_COUNT: usize = 20; +const CHAR_POOL_SIZE: usize = CHAR_COUNT + 2; + +#[derive(Copy,Clone)] +pub struct CharCell { + pub data: char, + next: Option<*mut CharCell>, +} + +impl CharCell { + pub const fn new() -> Self { + Self { + data: '\0', + next: None, + } + } +} + +use core::fmt::{Debug,Formatter,Result}; +impl Debug for CharCell { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + write!(f, "{}", self.data) + } +} + +unsafe impl Send for CharCell {} + +pub struct CharAllocator(NullLock<[CharCell; CHAR_POOL_SIZE]>); + +impl CharAllocator { + pub const fn new() -> Self { + Self(NullLock::new([CharCell::new(); CHAR_POOL_SIZE])) + } + + pub fn init(&self) { + self.0.lock(|char_pool| { + for idx in 2..CHAR_POOL_SIZE { + if idx != CHAR_POOL_SIZE - 1 { + char_pool[idx].next = Some(&mut char_pool[idx+1] as *mut CharCell); + } else { + char_pool[idx].next = None; + } + } + char_pool[0].next = Some(&mut char_pool[2] as *mut CharCell); + char_pool[1].next = Some(&mut char_pool[CHAR_POOL_SIZE-1] as *mut CharCell); + }); + } + + pub fn alloc(&self) -> Option<&mut CharCell> { + return self.0.lock(|char_pool| { + if let Some(char_cell) = char_pool[0].next { + char_pool[0].next = unsafe{(*char_cell).next}; + unsafe { + (*char_cell).next = None; + } + return Some(unsafe{&mut *char_cell as &mut CharCell}); + } else { + return None; + } + }); + } + + pub fn free(&self, cell: &mut CharCell) { + self.0.lock(|char_pool| { + cell.next = None; + match char_pool[1].next { + None => { + char_pool[0].next = Some(cell as *mut CharCell); + } + Some(ocell) => { + unsafe { + (*ocell).next = Some(cell as *mut CharCell); + } + } + } + char_pool[1].next = Some(cell as *mut CharCell); + }); + } +} + +impl Debug for CharAllocator { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + self.0.lock(|pool| { + write!(f, "{:?}", pool) + }) + } +} + +pub static CHAR_ALLOCATOR: CharAllocator = CharAllocator::new(); diff --git a/src/kernel.rs b/src/kernel.rs index 56f53c1..9377eb5 100644 --- a/src/kernel.rs +++ b/src/kernel.rs @@ -9,6 +9,7 @@ #![no_main] #![no_std] +mod alloc; mod console; mod cpu; mod panic_wait; @@ -16,15 +17,26 @@ mod print; mod sync; mod uart; use crate::console::console; +use crate::alloc::CHAR_ALLOCATOR; /// Initialization Code unsafe fn kernel_init() -> ! { console().init().unwrap(); + CHAR_ALLOCATOR.init(); kernel_main() } /// Post init fn kernel_main() -> ! { + for idx in 0..30 { + if let Some(cell) = CHAR_ALLOCATOR.alloc() { + cell.data = ('0' as u8 + idx as u8) as char; + println!("SUCCESS: Allocated a char! {:?} {:?}", cell, CHAR_ALLOCATOR); + CHAR_ALLOCATOR.free(cell); + } else { + println!("ERROR: No more chars remaining! {:?}", CHAR_ALLOCATOR); + } + } println!("I should be able to print {} here!", 5); loop { } } -- cgit v1.2.1