diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 5d30951..20ea562 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -6,7 +6,7 @@ version = 3 name = "api" version = "0.1.0" dependencies = [ - "num-derive 0.4.2", + "num-derive", "num-traits", ] @@ -30,9 +30,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "cfg-if" @@ -53,50 +53,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" [[package]] -name = "endian-type-rs" -version = "0.1.4" +name = "fdt" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6419a5c75e40011b9fe0174db3fe24006ab122fbe1b7e9cc5974b338a755c76" - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fdt-rs" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581d3afdd654deb68c19fcbe4bc411910cc64067d4a13d8637bda7722cb9c2ea" -dependencies = [ - "endian-type-rs", - "fallible-iterator", - "memoffset", - "num-derive 0.3.3", - "num-traits", - "rustc_version", - "static_assertions", - "unsafe_unwrap", -] +checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67" [[package]] name = "kernel" version = "0.1.0" dependencies = [ "api", - "bitflags 2.4.2", + "bitflags 2.5.0", "cfg-if", - "fdt-rs", + "fdt", "lazy_static", "log", - "num-derive 0.4.2", + "num-derive", "num-traits", "riscv", "sbi-rt", "spin 0.9.8", "static_assertions", "uart_16550", + "vspace", ] [[package]] @@ -120,29 +99,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "num-derive" @@ -152,7 +111,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -166,9 +125,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -201,15 +160,6 @@ dependencies = [ "embedded-hal", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "rustversion" version = "1.0.14" @@ -237,21 +187,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "spin" version = "0.5.2" @@ -275,20 +210,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -313,10 +237,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "unsafe_unwrap" +name = "vspace" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80" [[package]] name = "x86" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index a05a4cd..737889e 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -28,10 +28,11 @@ lto = "thin" [dependencies] api = { path = "../api" } +vspace = { path = "../lib/vspace" } bitflags = "2.4.2" cfg-if = "1.0.0" -fdt-rs = { version = "0.4.5", default-features = false } +fdt = "0.1" lazy_static = { version = "1.4.0", features = ["spin_no_std"] } log = "0.4" num-derive = "0.4" diff --git a/kernel/src/arch/riscv/layout.rs b/kernel/src/arch/riscv/layout.rs index 2c0dbcf..8f3239d 100644 --- a/kernel/src/arch/riscv/layout.rs +++ b/kernel/src/arch/riscv/layout.rs @@ -1,7 +1,6 @@ -pub use super::mm::page::PAGE_SIZE; - -pub const KERNEL_MEM_START: usize = 0x8030_0000; +use crate::utils::extern_addr::ExternSymbol; extern "C" { - static __kernel_end: u8; + static __kernel_start: ExternSymbol; + static __kernel_end: ExternSymbol; } diff --git a/kernel/src/arch/riscv/linker.ld b/kernel/src/arch/riscv/linker.ld index 96ecd7c..923af0e 100644 --- a/kernel/src/arch/riscv/linker.ld +++ b/kernel/src/arch/riscv/linker.ld @@ -4,19 +4,16 @@ ENTRY(_start) BASE_ADDRESS = 0x80200000; PAGE_SIZE = 0x1000; -MEMORY { - DRAM : ORIGIN = BASE_ADDRESS, LENGTH = 16M -} - SECTIONS { . = BASE_ADDRESS; + __kernel_start = .; .text : { __text_start = .; *(.text.entry) *(.text .text.*) __text_end = .; - } > DRAM + } .rodata : { . = ALIGN(8); @@ -24,7 +21,7 @@ SECTIONS { *(.rodata .rodata.*) *(.srodata .srodata.*) __rodata_end = .; - } > DRAM + } .data : { . = ALIGN(8); @@ -32,7 +29,7 @@ SECTIONS { *(.data .data.*) *(.sdata .sdata.*) __data_end = .; - } > DRAM + } .bss : { . = ALIGN(8); @@ -43,12 +40,13 @@ SECTIONS { *(.bss .bss.*) *(.sbss .sbss.*) __bss_end = .; - } > DRAM - - /DISCARD/ : { - *(.eh_frame) } . = ALIGN(PAGE_SIZE); __kernel_end = .; + + /DISCARD/ : { + *(.eh_frame_hdr) + *(.eh_frame) + } } diff --git a/kernel/src/arch/riscv/mod.rs b/kernel/src/arch/riscv/mod.rs index 1beaf7b..ca181c6 100644 --- a/kernel/src/arch/riscv/mod.rs +++ b/kernel/src/arch/riscv/mod.rs @@ -16,6 +16,5 @@ mod cpu; mod entry; pub mod layout; mod lowlevel; -mod mm; mod timer; pub mod trap; diff --git a/kernel/src/main.rs b/kernel/src/main.rs index a2eb91b..f25797a 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -3,6 +3,7 @@ #![no_main] // Features #![feature(asm_const)] +#![feature(extern_types)] #![feature(let_chains)] #![feature(naked_functions)] #![feature(panic_info_message)] @@ -24,9 +25,6 @@ pub mod lang; // entrypoint pub mod entry; -// page table -pub mod mm; - // plat pub mod plat; diff --git a/kernel/src/mm/bitmap.rs b/kernel/src/mm/bitmap.rs deleted file mode 100644 index 211bf3f..0000000 --- a/kernel/src/mm/bitmap.rs +++ /dev/null @@ -1,115 +0,0 @@ -pub trait BitmapOps: Copy + Clone { - const CAPACITY: usize; - const DEFAULT: Self; - // a workaround for const fn new() - fn alloc(&mut self) -> Option; - fn dealloc(&mut self, index: usize); -} - -const BITS_PER_LEVEL: usize = 32; - -#[derive(Copy, Clone)] -pub struct Bitmap32(u32); - -impl BitmapOps for Bitmap32 { - const CAPACITY: usize = u32::BITS as usize; - const DEFAULT: Self = Self(0); - - fn alloc(&mut self) -> Option { - // fast-path - let i = self.0.trailing_zeros() as usize; - if i > 0 { - self.0 |= 1u32 << (i - 1); - return Some(i - 1); - } - - // check full - if self.0 == u32::MAX { - return None; - } - - // slow-path - for i in (0..BITS_PER_LEVEL).rev() { - if self.0 & (1 << i) == 0 { - self.0 |= 1 << i; - return Some(i); - } - } - - None - } - - fn dealloc(&mut self, index: usize) { - if index < BITS_PER_LEVEL { - self.0 &= !(1 << index); - } - } -} - -#[derive(Copy, Clone)] -pub struct Bitmap { - bits: u32, - next: [B; BITS_PER_LEVEL], -} - -impl BitmapOps for Bitmap { - const CAPACITY: usize = BITS_PER_LEVEL * B::CAPACITY; - const DEFAULT: Self = Self { - bits: 0, - next: [B::DEFAULT; BITS_PER_LEVEL], - }; - - fn alloc(&mut self) -> Option { - if self.bits == u32::MAX { - return None; - } - - // fast-path - loop { - let i = self.bits.leading_zeros() as usize; - if i == 0 { - break; - } - - if let Some(index) = self.alloc_index(i - 1) { - return Some(index); - } - } - - // slow-path - for i in (0..BITS_PER_LEVEL).rev() { - if self.bits & (1 << i) == 0 { - if let Some(index) = self.alloc_index(i) { - return Some(index); - } - } - } - - None - } - - fn dealloc(&mut self, index: usize) { - let i = index / B::CAPACITY; - if i < BITS_PER_LEVEL { - self.next[i].dealloc(index % B::CAPACITY); - self.bits &= !(1 << i); - } - } -} - -impl Bitmap { - fn alloc_index(&mut self, i: usize) -> Option { - if let Some(sub) = self.next[i].alloc() { - return Some(i * B::CAPACITY + sub); - } - self.bits |= 1 << i; - None - } -} - -#[allow(unused)] -pub type Bitmap1K = Bitmap; -#[allow(unused)] -pub type Bitmap32K = Bitmap; -#[allow(unused)] -pub type Bitmap1M = Bitmap; diff --git a/kernel/src/mm/frame.rs b/kernel/src/mm/frame.rs deleted file mode 100644 index db389d5..0000000 --- a/kernel/src/mm/frame.rs +++ /dev/null @@ -1,84 +0,0 @@ -use cfg_if::cfg_if; -use log::trace; -use spin::mutex::SpinMutex; - -use crate::arch::layout::*; -use crate::mm::addr::{AddressOps, PhysAddr}; - -cfg_if! { - if #[cfg(feature = "frame_bitmap")] { - use crate::mm::bitmap::{Bitmap1K, BitmapOps}; - - // 1k * 4k = 4MB, currently enough for kernel data - static ALLOCATOR: SpinMutex = SpinMutex::new(Bitmap1K::DEFAULT); - } else { // fallback to freelist - use lazy_static::lazy_static; - use crate::mm::freelist::FreeList; - - lazy_static! { - static ref ALLOCATOR: SpinMutex = { - let mut list = FreeList::new(); - - for i in 0..1024 { - let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START); - list.push(addr.into()); - } - - SpinMutex::new(list) - }; - } - } -} - -pub struct FrameAllocator; - -impl FrameAllocator { - pub fn alloc(&self) -> Option { - cfg_if! { - if #[cfg(feature = "frame_bitmap")] { - let addr = ALLOCATOR - .lock() - .alloc() - .map(|i| PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START)); - } else { - let addr = ALLOCATOR.lock().pop().map(|addr| addr.into()); - } - } - - trace!("[mm/frame] alloc frame: {:?}", addr); - - #[cfg(debug_assertions)] - fill_page(addr, 0xaa); - - addr - } - - pub fn dealloc(&self, addr: PhysAddr) { - debug_assert!(addr.is_aligned(PAGE_SIZE)); - debug_assert!(addr.as_usize() >= KERNEL_MEM_START); - - trace!("[mm/frame] dealloc frame: {:?}", addr); - - #[cfg(debug_assertions)] - fill_page(Some(addr), 0x55); - - cfg_if! { - if #[cfg(feature = "frame_bitmap")] { - ALLOCATOR - .lock() - .dealloc((addr.as_usize() - KERNEL_MEM_START) / PAGE_SIZE); - } else { - ALLOCATOR.lock().push(addr.into()); - } - } - } -} - -fn fill_page(addr: Option, val: u8) { - unsafe { - // fill with val - if let Some(addr) = addr { - core::ptr::write_bytes(addr.as_usize() as *mut u8, val, PAGE_SIZE); - } - } -} diff --git a/kernel/src/mm/freelist.rs b/kernel/src/mm/freelist.rs deleted file mode 100644 index d4eab1d..0000000 --- a/kernel/src/mm/freelist.rs +++ /dev/null @@ -1,94 +0,0 @@ -use core::num::NonZeroUsize; - -pub struct FreeList { - next: Option, -} - -impl FreeList { - pub const fn new() -> Self { - Self { next: None } - } - - pub fn push(&mut self, ptr: NonZeroUsize) { - unsafe { - let raw: *mut usize = ptr.get() as *mut usize; - *raw = self.next.map_or(0, |next| next.get()); - } - self.next = Some(ptr); - } - - pub fn pop(&mut self) -> Option { - let popped = self.next.take(); - if let Some(next) = popped { - let raw: *const usize = next.get() as *const usize; - self.next = NonZeroUsize::new(unsafe { *raw }); - } - - popped - } -} - -#[cfg(test)] -mod tests { - use crate::arch::layout::{KERNEL_MEM_START, PAGE_SIZE}; - use crate::mm::addr::PhysAddr; - - use super::*; - - #[test_case] - fn test_freelist_serial() { - let mut list = FreeList::new(); - - for i in 0..1024 { - let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START); - list.push(addr.into()); - } - - for i in 0..1024 { - let addr: Option = list.pop().map(|addr| addr.into()); - let expected = PhysAddr((1023 - i) * PAGE_SIZE + KERNEL_MEM_START); - assert_eq!(addr, Some(expected)); - } - - let addr: Option = list.pop().map(|addr| addr.into()); - assert_eq!(addr, None); - - for i in 0..1024 { - let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START); - list.push(addr.into()); - } - } - - #[test_case] - fn test_freelist_complex() { - let mut list = FreeList::new(); - - for i in 0..1024 { - let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START); - list.push(addr.into()); - } - - // pop 2 with 1 push - let mut cnt = 0; - for i in 0..1024 + 512 + 256 + 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 + 1 { - let addr: Option = list.pop().map(|addr| addr.into()); - let expected = PhysAddr((1023 - cnt) * PAGE_SIZE + KERNEL_MEM_START); - assert_eq!(addr, Some(expected)); - - if i % 2 == 0 { - list.push(addr.unwrap().into()); - } else { - cnt += 1; - } - } - - let addr: Option = list.pop().map(|addr| addr.into()); - assert_eq!(addr, None); - assert_eq!(cnt, 1024); - - for i in 0..1024 { - let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START); - list.push(addr.into()); - } - } -} diff --git a/kernel/src/mm/mod.rs b/kernel/src/mm/mod.rs deleted file mode 100644 index 20dd779..0000000 --- a/kernel/src/mm/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod addr; -mod bitmap; -pub mod frame; -mod freelist; -pub mod page; diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs deleted file mode 100644 index 9ebd519..0000000 --- a/kernel/src/mm/page.rs +++ /dev/null @@ -1,55 +0,0 @@ -use core::marker::PhantomData; - -use bitflags::bitflags; - -use crate::mm::addr::{AddressOps, PhysAddr, VirtAddr}; - -#[derive(Debug)] -pub enum PagingError { - AddressNotAligned, -} - -bitflags! { - pub struct MapAttr: usize { - const READABLE = 1 << 1; - const WRITABLE = 1 << 2; - const EXECUTABLE = 1 << 3; - const USER_ACCESSIBLE = 1 << 4; - } -} - -pub trait PageTableEntry { - fn new_page(paddr: PhysAddr, attr: MapAttr) -> Self; - fn new_table(paddr: PhysAddr) -> Self; - - fn addr(&self) -> PhysAddr; - fn attr(&self) -> MapAttr; - - fn set_addr(&mut self, addr: PhysAddr); - fn set_attr(&mut self, attr: MapAttr); - - fn is_valid(&self) -> bool; -} - -pub trait PageSize { - // Arch should implement this - // For example, 4KiB / 2MiB / 1GiB in sv39 - - const SIZE: usize; -} - -pub struct Page { - start_address: VirtAddr, - size: PhantomData, -} - -impl Page { - pub const SIZE: usize = S::SIZE; - - pub fn new(addr: VirtAddr) -> Self { - Self { - start_address: addr.align_down(Self::SIZE), - size: PhantomData, - } - } -} diff --git a/kernel/src/objects/mod.rs b/kernel/src/objects/mod.rs index 951e188..5ad9cc1 100644 --- a/kernel/src/objects/mod.rs +++ b/kernel/src/objects/mod.rs @@ -21,7 +21,6 @@ use core::marker::PhantomData; pub mod cap; pub mod null; -pub mod untyped; /// Cap is the high-level wrapper of RawCap, it's a typed reference to RawCap (which is untyped in Rust) /// For the typed objects, we should bound it with an empty traits `KernelObject` diff --git a/kernel/src/utils/extern_addr.rs b/kernel/src/utils/extern_addr.rs new file mode 100644 index 0000000..94c1395 --- /dev/null +++ b/kernel/src/utils/extern_addr.rs @@ -0,0 +1,19 @@ +use vspace::addr::PhysAddr; + +extern "C" { + pub type ExternSymbol; +} + +impl ExternSymbol { + pub fn as_ptr(&'static self) -> *const u8 { + self as *const Self as *const u8 + } + + pub fn as_usize(&'static self) -> usize { + self.as_ptr() as usize + } + + pub fn as_phys_addr(&'static self) -> PhysAddr { + PhysAddr::from(self.as_usize()) + } +} diff --git a/kernel/src/utils/mod.rs b/kernel/src/utils/mod.rs index 09e6a99..af212e3 100644 --- a/kernel/src/utils/mod.rs +++ b/kernel/src/utils/mod.rs @@ -1 +1,2 @@ +pub mod extern_addr; pub mod function_name; diff --git a/lib/vspace/Cargo.lock b/lib/vspace/Cargo.lock new file mode 100644 index 0000000..8a2dc71 --- /dev/null +++ b/lib/vspace/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "vspace" +version = "0.1.0" diff --git a/lib/vspace/Cargo.toml b/lib/vspace/Cargo.toml new file mode 100644 index 0000000..87ee28d --- /dev/null +++ b/lib/vspace/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "vspace" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/kernel/src/mm/addr.rs b/lib/vspace/src/addr.rs similarity index 97% rename from kernel/src/mm/addr.rs rename to lib/vspace/src/addr.rs index b829b88..c22fd80 100644 --- a/kernel/src/mm/addr.rs +++ b/lib/vspace/src/addr.rs @@ -1,7 +1,7 @@ -use core::fmt::{Debug, Display, Formatter, LowerHex, Result, UpperHex}; -use core::hash::Hash; -use core::num::NonZeroUsize; -use core::ops::{Add, AddAssign, Sub, SubAssign}; +use core::fmt::*; +use core::hash::*; +use core::num::*; +use core::ops::*; #[inline(always)] pub fn align_up(addr: usize, align: usize) -> usize { diff --git a/lib/vspace/src/lib.rs b/lib/vspace/src/lib.rs new file mode 100644 index 0000000..167926e --- /dev/null +++ b/lib/vspace/src/lib.rs @@ -0,0 +1,3 @@ +#![no_std] + +pub mod addr;