aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--src/alloc.rs92
-rw-r--r--src/kernel.rs12
3 files changed, 108 insertions, 1 deletions
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 { }
}