This commit is contained in:
fekhesk 2022-10-26 17:21:58 -07:00
parent 1d810657ff
commit 10df1c6cfa
No known key found for this signature in database
GPG key ID: 6B3D8CB511646891
8 changed files with 149 additions and 27 deletions

View file

@ -1,7 +0,0 @@
[target.'cfg(target_os = "none")']
runner = "cargo run --package simple_boot --"
[alias]
kbuild = "build --target x86_64-custom.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem"
kimage = "run --target x86_64-custom.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem -- --no-run"
krun = "run --target x86_64-custom.json -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem"

View file

@ -11,10 +11,12 @@ spin = "0.9.1"
x86_64 = "0.14.10"
rlibc = "1.0"
multiboot2 = { version = "0.14.0", optional = true }
linked_list_allocator = { version = "0.9.0", optional = true }
[dependencies.lazy_static]
version = "1.4.0"
features = ["spin_no_std"]
[features]
default = ["f_multiboot2"]
f_multiboot2 = ["dep:multiboot2"]
default = ["f_multiboot2", "f_ll_alloc"]
f_multiboot2 = ["dep:multiboot2"]
f_ll_alloc = ["dep:linked_list_allocator"]

View file

@ -44,7 +44,7 @@ $(final): $(kernel) $(linker_script) $(assembly_object_files)
--gc-sections
$(kernel):
@RUST_TARGET_PATH=$(shell pwd) xargo build --target $(target) -Zbuild-std=core --features "f_multiboot2"
@RUST_TARGET_PATH=$(shell pwd) xargo build --target $(target) -Zbuild-std=core,alloc --features "f_multiboot2"
build/arch/$(arch)/%.o: arch/$(arch)/%.asm
@mkdir -p $(shell dirname $@)

View file

@ -12,5 +12,7 @@ BdsDxe: starting Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1
welcome to wukkOS!
(c) 2022 Real Microsoft, LLC
initialising memory maps...[OK]
L4 entry 0: PageTableEntry { addr: PhysAddr(0x128000), flags: PRESENT | WRITABLE | ACCESSED }
initialising mapper...[OK]
initialising frame allocator...[OK]
initialising heap...[OK]
testing heap...[OK]

View file

@ -32,6 +32,12 @@ impl KernelInfo {
}
}
#[cfg(feature = "f_multiboot2")]
pub fn get_memory_tag(&self) -> &MemoryMapTag {
let mm_tag = self.boot_info.memory_map_tag().expect("no memory map tag").clone();
mm_tag
}
#[cfg(feature = "f_multiboot2")]
pub fn memory_areas(&self) -> impl Iterator<Item = &multiboot2::MemoryArea> {
let mm_tag = self.boot_info.memory_map_tag().expect("ERR NO MEM MAP TAG!");
@ -41,4 +47,8 @@ impl KernelInfo {
pub fn is_safe_memory(&self, addr: u64) -> bool {
addr >= self.safe_mem_start && addr >= self.kernel_end
}
pub fn safe_memory_start(&self) -> u64 {
self.safe_mem_start
}
}

View file

@ -2,19 +2,24 @@
#![feature(default_alloc_error_handler)]
#![feature(panic_info_message)]
#![feature(asm_const)]
#![feature(alloc_error_handler)]
#![no_std]
#![no_main]
extern crate rlibc;
extern crate alloc;
use alloc::rc::Rc;
use alloc::vec;
use lazy_static::lazy_static;
use core::panic::PanicInfo;
use multiboot2::MemoryAreaType;
use spin::Mutex;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
use x86_64::VirtAddr;
use x86_64::{PhysAddr, VirtAddr};
use x86_64::structures::paging::Translate;
use crate::boot::KernelInfo;
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
use crate::memory::active_level_4_table;
use crate::serial::terminal::ST;
mod font;
@ -38,6 +43,10 @@ lazy_static! {
const RAINBOW : [Colour; 6] = [Colour{r:255,g:0,b:0}, Colour{r:255,g:127,b:0}, Colour{r:255,g:255,b:0}, Colour{r:0,g:255,b:0}, Colour{r:0,g:255,b:255}, Colour{r:0,g:0,b:255}];
#[alloc_error_handler]
fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
panic!("allocation error: {:?}", layout)
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
@ -89,17 +98,29 @@ pub extern fn kernel_main(args: KernelArgs) -> ! {
println!();
println!("welcome to wukkOS!");
println!("(c) 2022 Real Microsoft, LLC");
print!("initialising memory maps...");
let kern_info = KernelInfo::init_from_kernel_args(args);
let mut mem_areas = kern_info.memory_areas();
let kern_info = Mutex::new(KernelInfo::init_from_kernel_args(args));
print!("initialising mapper...");
let mut mapper = unsafe { memory::init(VirtAddr::new(0)) };
println!("[OK]");
print!("initialising frame allocator...");
let mut frame_allocator = unsafe { memory::BootInfoFrameAllocator::init(kern_info) };
println!("[OK]");
print!("initialising heap...");
memory::allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap init failed");
println!("[OK]");
let l4_table = active_level_4_table(VirtAddr::new(0));
for (i, entry) in l4_table.iter().enumerate() {
if !entry.is_unused() {
println!("L4 entry {}: {:?}", i, entry);
}
print!("testing heap...");
let reference_counted = Rc::new(vec![1, 2, 3]);
let cloned = reference_counted.clone();
let test_1 = Rc::strong_count(&reference_counted) == 2;
drop(cloned);
let test_2 = Rc::strong_count(&reference_counted) == 1;
if test_1 && test_2 {
println!("[OK]");
} else {
println!("[FAIL]");
}
drop(reference_counted);
loop {}
}

41
src/memory/allocator.rs Normal file
View file

@ -0,0 +1,41 @@
use x86_64::structures::paging::{FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB};
use x86_64::structures::paging::mapper::MapToError;
use x86_64::VirtAddr;
pub const HEAP_START: u64 = 0x_4444_4444_0000;
pub const HEAP_SIZE: u64 = 100 * 1024; // 100 KiB
#[cfg(feature = "f_ll_alloc")]
use linked_list_allocator::LockedHeap;
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub fn init_heap(
mapper: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
) -> Result<(), MapToError<Size4KiB>> {
let page_range = {
let heap_start = VirtAddr::new(HEAP_START as u64);
let heap_end = heap_start + HEAP_SIZE - 1u64;
let heap_start_page = Page::containing_address(heap_start);
let heap_end_page = Page::containing_address(heap_end);
Page::range_inclusive(heap_start_page, heap_end_page)
};
for page in page_range {
let frame = frame_allocator
.allocate_frame()
.ok_or(MapToError::FrameAllocationFailed)?;
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
unsafe {
mapper.map_to(page, frame, flags, frame_allocator)?.flush()
};
}
unsafe {
ALLOCATOR.lock().init(HEAP_START as usize, HEAP_SIZE as usize);
}
Ok(())
}

View file

@ -1,15 +1,68 @@
use x86_64::registers::control::Cr3;
use x86_64::structures::paging::PageTable;
use x86_64::VirtAddr;
pub mod allocator;
pub fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable {
use x86_64::structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB};
use x86_64::{PhysAddr, VirtAddr};
pub unsafe fn init(phys_mem_offset: VirtAddr) -> OffsetPageTable<'static> {
let level_4_table = active_level_4_table(phys_mem_offset);
OffsetPageTable::new(level_4_table, phys_mem_offset)
}
unsafe fn active_level_4_table(phys_mem_offset: VirtAddr) -> &'static mut PageTable {
use x86_64::registers::control::Cr3;
let (level_4_table_frame, _) = Cr3::read();
let phys = level_4_table_frame.start_address();
let virt = physical_memory_offset + phys.as_u64();
let virt = phys_mem_offset + phys.as_u64();
let page_table_ptr: *mut PageTable = virt.as_mut_ptr();
unsafe { &mut *page_table_ptr } // unsafe
}
#[cfg(feature = "f_multiboot2")]
use multiboot2::{MemoryMapTag, BootInformation};
use spin::Mutex;
use crate::boot::KernelInfo;
pub struct BootInfoFrameAllocator {
kern_info: Mutex<KernelInfo>,
next: usize,
}
impl BootInfoFrameAllocator {
#[cfg(feature = "f_multiboot2")]
pub unsafe fn init(kern_info: Mutex<crate::boot::KernelInfo>) -> Self {
Self {
kern_info,
next: 0,
}
}
}
unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
fn allocate_frame(&mut self) -> Option<PhysFrame> {
#[cfg(feature = "f_multiboot2")] {
let mut kern_lock = self.kern_info.lock();
let mut usable_frames = kern_lock
.memory_areas();
let mut usable_frames = usable_frames
.map(|area| {
let frame_addr = area.start_address();
let frame_end = area.end_address();
let frame_size = frame_end - frame_addr;
let num_frames = frame_size / 4096;
let start_frame = PhysFrame::containing_address(PhysAddr::new(frame_addr));
(0..num_frames).map(move |i| start_frame + i)
})
.flatten();
let frame = usable_frames.nth(self.next).clone();
self.next += 1;
// ensure unlock
unsafe { self.kern_info.force_unlock() };
frame
}
}
}