don't rely on allocator for basic stuff

This commit is contained in:
fekhesk 2022-10-26 15:50:22 -07:00
parent 9a5a004243
commit 3bb18ee8f7
No known key found for this signature in database
GPG key ID: 6B3D8CB511646891
11 changed files with 86 additions and 188 deletions

View file

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

View file

@ -6,16 +6,19 @@ BdsDxe: starting Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1
WARNING: no console will be available to OS WARNING: no console will be available to OS
error: no suitable video mode found. error: no suitable video mode found.
hello from wukkOS!
welcome to wukkOS! welcome to wukkOS!
(c) 2022 Real Microsoft, LLC (c) 2022 Real Microsoft, LLC
initialising memory maps...[OK] initialising memory maps...[OK]
memory map: memory map:
0 - a0000 : Available 0 - a0000 : available
100000 - 800000 : Available 100000 - 800000 : available
808000 - 80b000 : Available 800000 - 808000 : reserved for hibernation
80c000 - 810000 : Available 808000 - 80b000 : available
900000 - 78ef000 : Available 80b000 - 80c000 : reserved for hibernation
7bff000 - 7f58000 : Available 80c000 - 810000 : available
810000 - 900000 : reserved for hibernation
900000 - 78ef000 : available
78ef000 - 79ef000 : reserved

View file

@ -1,55 +0,0 @@
use core::alloc::{GlobalAlloc, Layout};
use core::cell::UnsafeCell;
use core::ptr::null_mut;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::SeqCst;
const ARENA_SIZE: usize = 128 * 1024;
const MAX_SUPPORTED_ALIGN: usize = 4096;
#[repr(C, align(4096))] // 4096 == MAX_SUPPORTED_ALIGN
struct SimpleAllocator {
arena: UnsafeCell<[u8; ARENA_SIZE]>,
remaining: AtomicUsize, // we allocate from the top, counting down
}
#[global_allocator]
static ALLOCATOR: SimpleAllocator = SimpleAllocator {
arena: UnsafeCell::new([0x55; ARENA_SIZE]),
remaining: AtomicUsize::new(ARENA_SIZE),
};
unsafe impl Sync for SimpleAllocator {}
unsafe impl GlobalAlloc for SimpleAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let align = layout.align();
// `Layout` contract forbids making a `Layout` with align=0, or align not power of 2.
// So we can safely use a mask to ensure alignment without worrying about UB.
let align_mask_to_round_down = !(align - 1);
if align > MAX_SUPPORTED_ALIGN {
return null_mut();
}
let mut allocated = 0;
if self
.remaining
.fetch_update(SeqCst, SeqCst, |mut remaining| {
if size > remaining {
return None;
}
remaining -= size;
remaining &= align_mask_to_round_down;
allocated = remaining;
Some(remaining)
})
.is_err()
{
return null_mut();
};
(self.arena.get() as *mut u8).add(allocated)
}
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}

View file

@ -1,27 +1,26 @@
use alloc::vec::Vec; use core::marker::PhantomData;
use crate::KernelArgs; use crate::KernelArgs;
#[cfg(feature = "f_multiboot2")] #[cfg(feature = "f_multiboot2")]
pub mod multiboot2; use multiboot2::{load, MemoryMapTag, BootInformation};
pub enum MemoryType { pub struct KernelInfo {
Available, #[cfg(feature = "f_multiboot2")]
Reserved, boot_info: BootInformation,
AcpiReclaimable,
Nvs,
BadMemory,
Kernel,
Bootloader,
Unknown(u32)
} }
pub struct MemoryArea { impl KernelInfo {
pub start: usize, pub fn init_from_kernel_args(args: KernelArgs) -> Self {
pub end: usize, let mut kernel_info = KernelInfo {
pub area_type: MemoryType, #[cfg(feature = "f_multiboot2")]
} boot_info: unsafe { load(args.multiboot_information_address).expect("ERR ARGS BAD!") },
};
kernel_info
}
pub trait KernelInfo { #[cfg(feature = "f_multiboot2")]
fn init_from_kernel_args(&mut self, args: KernelArgs); pub fn memory_areas(&self) -> impl Iterator<Item = &multiboot2::MemoryArea> {
fn get_memory_areas(&self) -> Vec<MemoryArea>; let mm_tag = self.boot_info.memory_map_tag().expect("ERR NO MEM MAP TAG!");
mm_tag.all_memory_areas()
}
} }

View file

@ -1,41 +0,0 @@
extern crate multiboot2;
use alloc::vec;
use alloc::vec::Vec;
use multiboot2::{BootInformation, load, MemoryAreaType};
use crate::boot::{KernelInfo, MemoryArea, MemoryType};
use crate::KernelArgs;
#[derive(Default)]
pub struct Multiboot2Bootloader {
pub boot_info: Option<BootInformation>,
}
impl KernelInfo for Multiboot2Bootloader {
fn init_from_kernel_args(&mut self, args: KernelArgs) {
let boot_info = unsafe {
load(args.multiboot_information_address)
}.expect("invalid kernel args!");
self.boot_info = Some(boot_info);
}
fn get_memory_areas(&self) -> Vec<MemoryArea> {
let mut memory_areas = vec![];
let boot_info = self.boot_info.as_ref().unwrap();
let memory_map_tag = boot_info.memory_map_tag().expect("memory map tag required but not found!");
for area in memory_map_tag.memory_areas() {
memory_areas.push(MemoryArea {
start: area.start_address() as usize,
end: area.end_address() as usize,
area_type: match area.typ() {
MemoryAreaType::Available => MemoryType::Available,
MemoryAreaType::Reserved => MemoryType::Reserved,
MemoryAreaType::AcpiAvailable => MemoryType::AcpiReclaimable,
MemoryAreaType::ReservedHibernate => MemoryType::Reserved,
MemoryAreaType::Defective => MemoryType::BadMemory,
}
})
}
memory_areas
}
}

View file

@ -21,7 +21,7 @@ pub extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, _er
loop {} loop {}
} }
pub extern "x86-interrupt" fn page_fault(stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode) -> ! { pub extern "x86-interrupt" fn page_fault(stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode) {
println!("---KERNEL FUCKY WUKKY UWU---"); println!("---KERNEL FUCKY WUKKY UWU---");
println!("page fault!"); println!("page fault!");
println!("accessed address: {:?}", Cr2::read()); println!("accessed address: {:?}", Cr2::read());

View file

@ -1,33 +1,23 @@
#![feature(abi_x86_interrupt)] #![feature(abi_x86_interrupt)]
#![feature(default_alloc_error_handler)] #![feature(default_alloc_error_handler)]
#![feature(panic_info_message)] #![feature(panic_info_message)]
#![feature(asm_const)]
#![no_std] #![no_std]
#![no_main] #![no_main]
use alloc::boxed::Box;
use alloc::format;
use alloc::string::ToString;
use alloc::sync::Arc;
use allocator::*;
extern crate alloc;
extern crate rlibc; extern crate rlibc;
use alloc::vec::Vec;
use spin::Mutex;
use core::arch::asm;
use core::ops::Deref;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use core::panic::PanicInfo; use core::panic::PanicInfo;
use multiboot2::MemoryAreaType;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
use crate::boot::KernelInfo; use crate::boot::KernelInfo;
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*; use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
use crate::serial::{Port, potential_serial_ports, terminal_helpers, terminal::ST}; use crate::serial::terminal::ST;
mod font; mod font;
mod serial; mod serial;
mod internals; mod internals;
mod allocator;
mod security; mod security;
mod boot; mod boot;
mod memory; mod memory;
@ -49,25 +39,26 @@ const RAINBOW : [Colour; 6] = [Colour{r:255,g:0,b:0}, Colour{r:255,g:127,b:0}, C
#[panic_handler] #[panic_handler]
fn panic(info: &PanicInfo) -> ! { fn panic(info: &PanicInfo) -> ! {
ST.logln("---KERNEL FUCKY WUKKY UWU (panic)---"); println!("---KERNEL FUCKY WUKKY UWU (panic)---");
ST.logln(if let Some(s) = info.payload().downcast_ref::<&str>() { if let Some(s) = info.payload().downcast_ref::<&str>() {
format!("panic payload: {s:?}") println!("panic payload: {s:?}")
} else { } else {
format!("no panic payload") println!("no panic payload")
}.as_str()); };
ST.logln(if let Some(msg) = info.message() { if let Some(msg) = info.message() {
format!("panic msg: {}", msg.as_str().unwrap_or("no message")) println!("panic msg: {}", msg.as_str().unwrap_or("no message"))
} else { } else {
"no message".to_string() println!("no message");
}.as_str()); }
ST.logln(if let Some(location) = info.location() { if let Some(location) = info.location() {
format!("location: file {} line {}", location.file(), location.line()) println!("location: file {} line {}", location.file(), location.line());
} else { } else {
"no location".to_string() println!("no location");
}.as_str()); };
loop {} loop {}
} }
#[repr(C)]
pub struct KernelArgs { pub struct KernelArgs {
#[cfg(feature = "f_multiboot2")] #[cfg(feature = "f_multiboot2")]
multiboot_information_address: usize multiboot_information_address: usize
@ -89,14 +80,6 @@ pub extern fn kernel_main(args: KernelArgs) -> ! {
ST.init_from_port(*port); ST.init_from_port(*port);
} }
let kern_info: Box<dyn boot::KernelInfo> = {
#[cfg(feature = "f_multiboot2")]
{
let mut kern_info = boot::multiboot2::Multiboot2Bootloader::default();
kern_info.init_from_kernel_args(args);
Box::new(kern_info)
}
};
println!(); println!();
println!(); println!();
@ -104,19 +87,17 @@ pub extern fn kernel_main(args: KernelArgs) -> ! {
println!("welcome to wukkOS!"); println!("welcome to wukkOS!");
println!("(c) 2022 Real Microsoft, LLC"); println!("(c) 2022 Real Microsoft, LLC");
print!("initialising memory maps..."); print!("initialising memory maps...");
let mem_areas = kern_info.get_memory_areas(); let kern_info = KernelInfo::init_from_kernel_args(args);
let mut mem_areas = kern_info.memory_areas();
println!("[OK]"); println!("[OK]");
println!("memory map:"); println!("memory map:");
for area in mem_areas { while let Some(area) = mem_areas.next() {
println!("{:x} - {:x} : {}", area.start, area.end, match area.area_type { println!("{:x} - {:x} : {}", area.start_address(), area.end_address(), match area.typ() {
boot::MemoryType::Available => "Available", MemoryAreaType::Available => "available",
boot::MemoryType::Reserved => "Reserved", MemoryAreaType::Reserved => "reserved",
boot::MemoryType::AcpiReclaimable => "ACPI Reclaimable", MemoryAreaType::AcpiAvailable => "ACPI available",
boot::MemoryType::Nvs => "NVS", MemoryAreaType::ReservedHibernate => "reserved for hibernation",
boot::MemoryType::BadMemory => "Bad Memory", MemoryAreaType::Defective => "defective",
boot::MemoryType::Kernel => "Kernel",
boot::MemoryType::Bootloader => "Bootloader",
boot::MemoryType::Unknown(_) => "Unknown"
}); });
} }

View file

@ -1,6 +1,4 @@
use alloc::fmt::format;
use core::fmt; use core::fmt;
use std::fmt::format;
use crate::serial::terminal::ST; use crate::serial::terminal::ST;
#[macro_export] #[macro_export]
@ -17,6 +15,5 @@ macro_rules! println {
#[doc(hidden)] #[doc(hidden)]
pub fn _print(args: fmt::Arguments) { pub fn _print(args: fmt::Arguments) {
use core::fmt::Write; use core::fmt::Write;
let string = format(args); ST.writer.lock().write_fmt(args).unwrap();
ST.log(string.as_str());
} }

View file

@ -1,4 +0,0 @@
#[repr(align(4096))]
pub struct PageTable {
entries: [PageTableEntry; 512],
}

View file

@ -1,4 +1,4 @@
#![feature(asm_const)]
use core::arch::asm; use core::arch::asm;
use core::borrow::{Borrow, BorrowMut}; use core::borrow::{Borrow, BorrowMut};

View file

@ -1,17 +1,25 @@
use alloc::sync::Arc; use core::fmt;
use core::ops::Deref; use core::ops::Deref;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use spin::Mutex; use spin::Mutex;
use crate::serial::Port; use crate::serial::Port;
pub struct SerialTerminal { pub struct SerialTerminal {
pub port: Arc<Mutex<Option<Port>>>, pub port: Mutex<Option<Port>>,
pub writer: Mutex<SerialTerminalWriter>,
}
pub struct SerialTerminalWriter {
pub port: Mutex<Option<Port>>,
} }
lazy_static! { lazy_static! {
pub static ref ST: SerialTerminal = { pub static ref ST: SerialTerminal = {
let mut serial_terminal = SerialTerminal { let serial_terminal: SerialTerminal = SerialTerminal {
port: Arc::new(Mutex::new(None)), port: Mutex::new(None),
writer: Mutex::new(SerialTerminalWriter {
port: Mutex::new(None),
}),
}; };
serial_terminal serial_terminal
}; };
@ -20,6 +28,7 @@ lazy_static! {
impl SerialTerminal { impl SerialTerminal {
pub fn init_from_port(&self, port: Port) { pub fn init_from_port(&self, port: Port) {
self.port.lock().replace(port); self.port.lock().replace(port);
self.writer.lock().port.lock().replace(port);
} }
pub fn log(&self, message: &str) { pub fn log(&self, message: &str) {
@ -34,4 +43,13 @@ impl SerialTerminal {
port.transmit_string("\r\n"); port.transmit_string("\r\n");
} }
} }
}
impl fmt::Write for SerialTerminalWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
if let Some(port) = self.port.lock().deref() {
port.transmit_string(s);
}
Ok(())
}
} }