clean up and use own heap
This commit is contained in:
35
kernel/Cargo.lock
generated
35
kernel/Cargo.lock
generated
@@ -83,7 +83,6 @@ dependencies = [
|
||||
"bootloader_api",
|
||||
"embedded-graphics",
|
||||
"lazy_static",
|
||||
"linked_list_allocator",
|
||||
"pc-keyboard",
|
||||
"pic8259",
|
||||
"uart_16550",
|
||||
@@ -99,25 +98,6 @@ dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
|
||||
dependencies = [
|
||||
"spinning_top",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "micromath"
|
||||
version = "2.1.0"
|
||||
@@ -163,27 +143,12 @@ version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spinning_top"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uart_16550"
|
||||
version = "0.3.0"
|
||||
|
||||
@@ -11,7 +11,6 @@ bench = false
|
||||
[dependencies]
|
||||
embedded-graphics = "0.8.1"
|
||||
pc-keyboard = "0.5.0"
|
||||
linked_list_allocator = "0.10.5"
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
pic8259 = "0.10.1"
|
||||
|
||||
@@ -1,30 +1,60 @@
|
||||
use core::alloc::Allocator;
|
||||
use core::{alloc::GlobalAlloc, ops::Range, ptr::null_mut};
|
||||
|
||||
use crate::util::mutex::Mutex;
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: Alloc = Alloc::empty();
|
||||
static ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||
|
||||
struct Alloc {
|
||||
base: *mut u8,
|
||||
struct Heap {
|
||||
cur: *mut u8,
|
||||
end: *mut u8,
|
||||
}
|
||||
|
||||
unsafe impl Allocator for Alloc {
|
||||
fn allocate(&self, layout: core::alloc::Layout) -> Result<core::ptr::NonNull<[u8]>, core::alloc::AllocError> {
|
||||
|
||||
impl Heap {
|
||||
pub const fn empty() -> Self {
|
||||
Self {
|
||||
cur: null_mut(),
|
||||
end: null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
impl Alloc {
|
||||
pub fn empty() -> Self {
|
||||
}
|
||||
|
||||
pub fn init(&mut self, start: *mut u8, len: usize) {
|
||||
|
||||
pub fn init(&mut self, start: *mut u8, end: *mut u8) {
|
||||
self.cur = start;
|
||||
self.end = end;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_heap() {
|
||||
unsafe {
|
||||
ALLOCATOR.init(crate::arch::paging::first_free(), crate::arch::paging::free_len());
|
||||
pub fn init_heap(range: Range<*mut u8>) {
|
||||
ALLOCATOR.init(range.start, range.end);
|
||||
}
|
||||
|
||||
struct LockedHeap(Mutex<Heap>);
|
||||
|
||||
// should look into why I need this, didn't see it in linked list alloc crate
|
||||
unsafe impl Sync for LockedHeap {}
|
||||
|
||||
impl LockedHeap {
|
||||
pub const fn empty() -> Self {
|
||||
Self(Mutex::new(Heap::empty()))
|
||||
}
|
||||
pub fn init(&self, start: *mut u8, end: *mut u8) {
|
||||
self.0.lock().init(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl GlobalAlloc for LockedHeap {
|
||||
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||
// blazing fast implementation :sunglasses:
|
||||
// (gonna switch to my own linked list later)
|
||||
let mut heap = self.0.lock();
|
||||
let pointer = heap.cur;
|
||||
heap.cur = heap.cur.add(layout.size());
|
||||
if heap.cur >= heap.end {
|
||||
return null_mut();
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
|
||||
// bet ur impl is slower
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use core::ptr::null_mut;
|
||||
use core::{arch::asm, ops::Range};
|
||||
|
||||
use crate::{
|
||||
arch::{asm, csr, interrupts, paging, wait},
|
||||
@@ -6,13 +6,11 @@ use crate::{
|
||||
main,
|
||||
};
|
||||
|
||||
static mut DT_ADDR: *mut FDT = null_mut();
|
||||
|
||||
#[no_mangle]
|
||||
#[link_section = ".text.init"]
|
||||
#[naked]
|
||||
unsafe extern "C" fn _start() -> ! {
|
||||
core::arch::asm!(
|
||||
asm!(
|
||||
// disable interrupts
|
||||
"csrw mie, zero",
|
||||
// set up gp & sp
|
||||
@@ -32,10 +30,15 @@ unsafe extern "C" fn _start() -> ! {
|
||||
"csrw mstatus, t0",
|
||||
"la t0, {init}",
|
||||
"csrw mepc, t0",
|
||||
"la ra, 2f",
|
||||
"mret",
|
||||
|
||||
"2:",
|
||||
init = sym init,
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
|
||||
pub unsafe fn to_supervisor() {
|
||||
asm!(
|
||||
"li t0, (1 << 8) | (1 << 5)",
|
||||
"csrw sstatus, t0",
|
||||
"li t0, (7 << 0) | (1 << 3)",
|
||||
@@ -45,18 +48,14 @@ unsafe extern "C" fn _start() -> ! {
|
||||
"li t2, (1 << 1) | (1 << 5) | (1 << 9)",
|
||||
"csrw mideleg, t2",
|
||||
"csrw sie, t2",
|
||||
"la t0, {start}",
|
||||
"mv t0, ra",
|
||||
"csrw sepc, t0",
|
||||
"sfence.vma",
|
||||
"sret",
|
||||
|
||||
start = sym start,
|
||||
init = sym init,
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
pub unsafe fn init() -> ! {
|
||||
let dt_addr = asm::reg!("a1") as *mut u8;
|
||||
let hart = csr::hartid::read();
|
||||
if hart != 0 {
|
||||
@@ -64,9 +63,12 @@ pub fn init() {
|
||||
}
|
||||
interrupts::init();
|
||||
let fdt = FDT::from_addr(dt_addr);
|
||||
paging::init(fdt);
|
||||
}
|
||||
|
||||
pub fn start() {
|
||||
main(unsafe { DT_ADDR });
|
||||
let raw_mem_range = fdt.mem_range();
|
||||
let heap_start = paging::init(raw_mem_range.end());
|
||||
let heap_mem = Range {
|
||||
start: heap_start,
|
||||
end: raw_mem_range.end(),
|
||||
};
|
||||
to_supervisor();
|
||||
main(heap_mem, fdt);
|
||||
}
|
||||
|
||||
3
kernel/src/arch/riscv64/mem.rs
Normal file
3
kernel/src/arch/riscv64/mem.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
use super::asm::linker_static;
|
||||
|
||||
linker_static!(PROGRAM_END: usize, ".dword _end");
|
||||
@@ -4,6 +4,7 @@ pub mod asm;
|
||||
pub mod interrupts;
|
||||
pub mod paging;
|
||||
pub mod qemu;
|
||||
pub mod mem;
|
||||
|
||||
pub fn wait() -> ! {
|
||||
loop {
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
use super::asm::linker_static;
|
||||
use crate::{
|
||||
arch::csr::{self, satp},
|
||||
fdt::FDT,
|
||||
println,
|
||||
util::bits::get_bits,
|
||||
};
|
||||
use core::{ptr::null_mut, slice};
|
||||
use core::slice;
|
||||
|
||||
use super::mem::PROGRAM_END;
|
||||
|
||||
linker_static!(END: usize, ".dword _end");
|
||||
const PAGE_SIZE: usize = 4096;
|
||||
const TABLE_LEN: usize = 2usize.pow(9);
|
||||
const TABLE_SIZE: usize = core::mem::size_of::<Table>();
|
||||
|
||||
static mut FIRST_FREE: *mut u8 = null_mut();
|
||||
static mut MEM_END: *mut u8 = null_mut();
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Entry(usize);
|
||||
|
||||
@@ -53,19 +48,12 @@ pub struct Table {
|
||||
pub entries: [Entry; TABLE_LEN],
|
||||
}
|
||||
|
||||
pub fn init(fdt: FDT) {
|
||||
pub fn init(mem_end: *mut u8) -> *mut u8 {
|
||||
unsafe {
|
||||
println!("program end: 0x{:x}", END);
|
||||
let range = fdt.mem_range();
|
||||
let start = range.start.get();
|
||||
let len = range.len.get();
|
||||
let end = start + len;
|
||||
MEM_END = end as *mut u8;
|
||||
println!("memory range: 0x{:x} -> 0x{:x}", start, end);
|
||||
let total_pages = end / 4096;
|
||||
let total_pages = mem_end as usize / 4096;
|
||||
let lvl1_count = (total_pages.saturating_sub(1)) / TABLE_LEN + 1;
|
||||
let lvl2_count = (lvl1_count.saturating_sub(1)) / TABLE_LEN + 1;
|
||||
let lvl2 = &mut *(END as *mut Table);
|
||||
let lvl2 = &mut *(PROGRAM_END as *mut Table);
|
||||
let lvl1_arr = slice::from_raw_parts_mut((lvl2 as *mut Table).add(TABLE_SIZE), lvl2_count);
|
||||
let lvl0_arr = slice::from_raw_parts_mut(
|
||||
lvl1_arr.as_ptr().add(lvl1_arr.len()) as *mut Table,
|
||||
@@ -106,10 +94,8 @@ pub fn init(fdt: FDT) {
|
||||
asid: 0,
|
||||
ppn: lvl2,
|
||||
});
|
||||
let satp = csr::satp::read();
|
||||
println!("satp: {satp:?}");
|
||||
let end = lvl0_arr.as_ptr().add(lvl0_arr.len()) as *mut u8;
|
||||
FIRST_FREE = end;
|
||||
let table_end = lvl0_arr.as_ptr().add(lvl0_arr.len()) as *mut u8;
|
||||
table_end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,11 +114,3 @@ pub fn virt_to_physical(table: &Table, addr: usize) -> usize {
|
||||
addr
|
||||
}
|
||||
}
|
||||
|
||||
pub fn first_free() -> *mut u8 {
|
||||
unsafe { FIRST_FREE }
|
||||
}
|
||||
|
||||
pub fn free_len() -> usize {
|
||||
unsafe { MEM_END.offset_from(FIRST_FREE) as usize }
|
||||
}
|
||||
|
||||
1
kernel/src/dev/mod.rs
Normal file
1
kernel/src/dev/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod uart;
|
||||
0
kernel/src/dev/uart.rs
Normal file
0
kernel/src/dev/uart.rs
Normal file
@@ -1,14 +1,11 @@
|
||||
// NOTE: basically none of this is safe rn, ideally it's eventually made safe / able to recover
|
||||
// also, I do a ton of slice.try_into and then transmuting which I'm pretty sure is bad and
|
||||
// I really should be transmuting into references but I cannot be bothered rn
|
||||
// garbage .1% finished FDT implementation
|
||||
|
||||
use crate::{
|
||||
println,
|
||||
util::bits::{u32_from_bytes, Be},
|
||||
};
|
||||
use core::{
|
||||
mem::{size_of, transmute},
|
||||
slice,
|
||||
fmt::Debug, mem::{size_of, transmute}, ops::Range, slice
|
||||
};
|
||||
|
||||
const MAGIC: u32 = 0xd00dfeed;
|
||||
@@ -161,12 +158,12 @@ impl FDT {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn mem_range(&self) -> MemRange {
|
||||
pub fn mem_range(&self) -> FDTMemRange {
|
||||
if let Some(node) = self.into_iter().find(|n| n.name.starts_with("memory@")) {
|
||||
let prop = node.find_prop("reg");
|
||||
if let Some(prop) = prop {
|
||||
for d in prop.data.chunks(size_of::<MemRange>()) {
|
||||
let d: [u8; size_of::<MemRange>()] = d.try_into().unwrap();
|
||||
for d in prop.data.chunks(size_of::<FDTMemRange>()) {
|
||||
let d: [u8; size_of::<FDTMemRange>()] = d.try_into().unwrap();
|
||||
// just return first one for now
|
||||
return unsafe { transmute(d) };
|
||||
}
|
||||
@@ -177,11 +174,38 @@ impl FDT {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct MemRange {
|
||||
pub start: Be<usize>,
|
||||
pub struct FDTMemRange {
|
||||
pub start: Be<*mut u8>,
|
||||
pub len: Be<usize>,
|
||||
}
|
||||
|
||||
impl FDTMemRange {
|
||||
pub fn start(&self) -> *mut u8 {
|
||||
self.start.get()
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.len.get()
|
||||
}
|
||||
pub fn end(&self) -> *mut u8 {
|
||||
unsafe { self.start().add(self.len.get()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FDTMemRange {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:?}..{:?}", self.start(), self.end())
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Range<*mut u8>> for FDTMemRange {
|
||||
fn into(self) -> Range<*mut u8> {
|
||||
Range {
|
||||
start: self.start(),
|
||||
end: self.end(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Node {
|
||||
pub name: &'static str,
|
||||
pub strings: &'static [u8],
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#![feature(naked_functions)]
|
||||
#![feature(fn_align)]
|
||||
|
||||
use core::ops::Range;
|
||||
|
||||
use fdt::FDT;
|
||||
|
||||
extern crate alloc;
|
||||
@@ -14,10 +16,16 @@ pub mod fdt;
|
||||
pub mod log;
|
||||
pub mod qemu;
|
||||
pub mod util;
|
||||
pub mod dev;
|
||||
|
||||
pub fn main(dt_addr: *mut FDT) -> ! {
|
||||
pub fn main(heap_mem: Range<*mut u8>, fdt: FDT) -> ! {
|
||||
println!("we out here vibin");
|
||||
allocator::init_heap();
|
||||
println!("memory range: {:?}", fdt.mem_range());
|
||||
println!("heap range: {:?}", heap_mem);
|
||||
for node in &fdt {
|
||||
|
||||
}
|
||||
allocator::init_heap(heap_mem);
|
||||
let mut test = alloc::vec![1, 2, 3];
|
||||
test.push(3);
|
||||
println!("{:?}", test);
|
||||
@@ -25,6 +33,10 @@ pub fn main(dt_addr: *mut FDT) -> ! {
|
||||
let x = *(0x3000 as *const u8);
|
||||
println!("{}", x);
|
||||
}
|
||||
for i in 0..10000 {
|
||||
let test2: alloc::vec::Vec<i32> = alloc::vec::Vec::with_capacity(10_000_000);
|
||||
println!("{}", i);
|
||||
}
|
||||
// for _ in 0..40000000 {}
|
||||
// let x = unsafe { *(0x10000000000 as *mut u8) };
|
||||
// println!("we got {x}");
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use core::mem::transmute;
|
||||
use core::{
|
||||
fmt::{Debug, Display},
|
||||
mem::transmute,
|
||||
};
|
||||
|
||||
macro_rules! get_bits {
|
||||
($name:ident[$high:expr,$low:expr]) => {{
|
||||
@@ -38,6 +41,24 @@ impl BeRep for usize {
|
||||
}
|
||||
}
|
||||
|
||||
impl BeRep for *mut u8 {
|
||||
fn _from_be(&self) -> Self {
|
||||
(*self as usize).to_be() as *mut u8
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Debug + BeRep> Debug for Be<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:?}", self.get())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Display + BeRep> Display for Be<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{}", self.get())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn u32_from_bytes(bytes: &[u8]) -> Option<u32> {
|
||||
if bytes.len() < 4 {
|
||||
return None;
|
||||
|
||||
@@ -27,7 +27,7 @@ fn main() {
|
||||
fn run_qemu(target: &Target, gdb: Option<Option<u16>>) {
|
||||
let mut qemu = target.qemu();
|
||||
qemu.args(["-d", "guest_errors"]);
|
||||
qemu.args(["-m", "4G"]);
|
||||
qemu.args(["-m", "1G"]);
|
||||
qemu.args(["-monitor", "telnet:127.0.0.1:1235,server,nowait"]);
|
||||
if let Some(port) = gdb {
|
||||
let port = port.unwrap_or(1234);
|
||||
|
||||
Reference in New Issue
Block a user