mirror of
https://github.com/realmicrosoft/windows.git
synced 2024-08-14 22:46:44 +00:00
don't rely on allocator for basic stuff
This commit is contained in:
parent
9a5a004243
commit
3bb18ee8f7
11 changed files with 86 additions and 188 deletions
2
Makefile
2
Makefile
|
@ -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 $@)
|
||||||
|
|
29
serial.log
29
serial.log
|
@ -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
|
||||||
|
|
|
@ -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) {}
|
|
||||||
}
|
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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());
|
||||||
|
|
71
src/lib.rs
71
src/lib.rs
|
@ -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"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
#[repr(align(4096))]
|
|
||||||
pub struct PageTable {
|
|
||||||
entries: [PageTableEntry; 512],
|
|
||||||
}
|
|
|
@ -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};
|
||||||
|
|
|
@ -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(())
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue