diff options
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | src/alloc.rs | 92 | ||||
| -rw-r--r-- | src/kernel.rs | 12 | 
3 files changed, 108 insertions, 1 deletions
| @@ -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 { }  } | 
