diff --git a/Cargo.toml b/Cargo.toml index 3e7a059..40dd6b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,11 @@ [package] -name = "nonx" +name = "kernel" version = "0.1.0" edition = "2021" [dependencies] +nonx-api = { path = "../nonx_api" } +nonx = { path = "../nonx" } [features] default = ["large"] diff --git a/src/lib.rs b/src/lib.rs index 24e4ea8..cd9fbf1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,8 @@ extern crate alloc; use core::panic::PanicInfo; -pub mod memm; pub mod plugin; +pub mod rust_mm; #[panic_handler] fn panic_handler(_panic: &PanicInfo) -> ! { diff --git a/src/memm/manager.rs b/src/memm/manager.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/memm/mod.rs b/src/memm/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/plugin/api_bus.rs b/src/plugin/api_bus.rs index 0c9f54f..fbf9ec2 100644 --- a/src/plugin/api_bus.rs +++ b/src/plugin/api_bus.rs @@ -1,6 +1,30 @@ -use alloc::string::String; +use core::ptr::addr_of_mut; -struct APIRegister{ - name: String, - call: *mut fn(), +use alloc::{ + collections::btree_map::BTreeMap, + string::{String, ToString}, +}; + +pub struct APIBus { + map: BTreeMap, +} + +unsafe impl Sync for APIBus {} + +pub static mut APIBUS: APIBus = APIBus { + map: BTreeMap::new(), +}; + +impl APIBus { + pub unsafe fn get() -> *mut APIBus { + addr_of_mut!(APIBUS) + } + + pub unsafe fn register(name: &str, rfn: *mut fn()) { + APIBUS.map.insert(name.to_string(), rfn); + } + + pub fn api(&self, name: &str) -> *mut fn() { + self.map.get(name).unwrap().clone() + } } diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index a355c48..1c581b6 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -1 +1 @@ -pub mod api_bus; \ No newline at end of file +pub mod api_bus; diff --git a/src/rust_mm.rs b/src/rust_mm.rs new file mode 100644 index 0000000..409fc9f --- /dev/null +++ b/src/rust_mm.rs @@ -0,0 +1,84 @@ +use core::{ + alloc::{GlobalAlloc, Layout}, + ops::BitAnd, + ptr::{addr_of_mut, null_mut}, +}; +use nonx_api::nonx_api; + +struct PreInitializeAllocator { + base: [u128; 1024], + inited: bool, +} + +/// This global object must be aligned by 4096 +static mut PREINITALLOC: PreInitializeAllocator = PreInitializeAllocator { + base: [0; 1024], + inited: false, +}; + +pub static mut MEMPLUGIN_INITED: bool = false; + +impl PreInitializeAllocator { + unsafe fn alloc(&mut self, size: usize, align: usize) -> *mut u8 { + if !self.inited { + self.inited = true; + self.base[0] = 0xff; + } + let obj_count = (size + 15) / 16; + let index_align = if align / 16 < 1 { 1 } else { align / 16 }; + let mut start = 0; + for i in 8..self.base.len() { + if i % index_align == 0 && self.base[i / 128].bitand(1 << (i % 128)) == 0 { + start = i; + } + if start != 0 && self.base[i / 128].bitand(1 << (i % 128)) != 0 { + start = 0; + } + if start != 0 && i - start == obj_count { + for j in start..i { + self.base[j / 128] |= 1 << (j % 128); + } + break; + } + } + if start == 0 { + null_mut() + } else { + addr_of_mut!(self.base[start]) as *mut u8 + } + } + + unsafe fn dealloc(&mut self, ptr: *mut u8, size: usize, align: usize) { + let obj_count = (size + 15) / 16; + let index_align = if align / 16 < 1 { 1 } else { align / 16 }; + let start = (ptr as *mut u128).offset_from(addr_of_mut!(self.base[0])) as usize; + if start % index_align == 0 { + for i in start..start + obj_count { + self.base[i / 128] &= !(1 << (i % 128)); + } + } + } +} + +struct GlobalAllocator; + +unsafe impl GlobalAlloc for GlobalAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if MEMPLUGIN_INITED { + nonx_api!(nonx::mem::alloc, layout.size(), layout.align()) + } else { + PREINITALLOC.alloc(layout.size(), layout.align()) + } + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + if MEMPLUGIN_INITED { + nonx_api!(nonx::mem::free, ptr, layout.size(), layout.align()); + } else { + PREINITALLOC.dealloc(ptr, layout.size(), layout.align()); + } + } +} + +#[global_allocator] +static GLOBAL_ALLOCATOR: GlobalAllocator = GlobalAllocator;