mirror of
https://github.com/realmicrosoft/windows.git
synced 2024-08-14 22:46:44 +00:00
FUCK we have to convert this all to 64 bit (,:
This commit is contained in:
parent
a1483ad6e1
commit
2c740c9d8a
9 changed files with 485 additions and 25 deletions
12
.idea/customTargets.xml
Normal file
12
.idea/customTargets.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CLionExternalBuildManager">
|
||||||
|
<target id="a92c96a0-6678-4b07-b208-a3b8818b9d4c" name="Xargo" defaultType="TOOL">
|
||||||
|
<configuration id="d781dfcc-e8c6-4528-b0ad-20eeb2514d1e" name="Xargo" toolchainName="Default">
|
||||||
|
<build type="TOOL">
|
||||||
|
<tool actionId="Tool_External Tools_Xargo" />
|
||||||
|
</build>
|
||||||
|
</configuration>
|
||||||
|
</target>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/misc.xml
Normal file
8
.idea/misc.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="SwUserDefinedSpecifications">
|
||||||
|
<option name="specTypeByUrl">
|
||||||
|
<map />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/tools/External Tools.xml
Normal file
9
.idea/tools/External Tools.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<toolSet name="External Tools">
|
||||||
|
<tool name="Xargo" description="idk it's kinda like cargo" showInMainMenu="false" showInEditor="false" showInProject="false" showInSearchPopup="false" disabled="false" useConsole="true" showConsoleOnStdOut="false" showConsoleOnStdErr="false" synchronizeAfterRun="true">
|
||||||
|
<exec>
|
||||||
|
<option name="COMMAND" value="$USER_HOME$/.cargo/bin/xargo" />
|
||||||
|
<option name="PARAMETERS" />
|
||||||
|
<option name="WORKING_DIRECTORY" />
|
||||||
|
</exec>
|
||||||
|
</tool>
|
||||||
|
</toolSet>
|
|
@ -4,6 +4,9 @@
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/simple_boot/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/simple_boot/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/alloc/benches" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/alloc/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/alloc/tests" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
|
@ -9,4 +9,8 @@ members = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bootloader = "0.10.12"
|
bootloader = "0.10.12"
|
||||||
|
spin = "0.9.1"
|
||||||
|
[dependencies.lazy_static]
|
||||||
|
version = "1.4.0"
|
||||||
|
features = ["spin_no_std"]
|
55
src/allocator/mod.rs
Normal file
55
src/allocator/mod.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
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) {}
|
||||||
|
}
|
160
src/internals/errors.rs
Normal file
160
src/internals/errors.rs
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
|
||||||
|
use core::borrow::{BorrowMut};
|
||||||
|
|
||||||
|
|
||||||
|
use crate::{InterruptStackFrame, font, FACEBOOK};
|
||||||
|
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::{COMMUNIST_RED, CUM_WHITE, Colour};
|
||||||
|
|
||||||
|
fn draw_box(x: usize, y: usize, width: usize, height: usize, color: Colour, mut fb: &mut [u8]) {
|
||||||
|
let pixelwidth = FACEBOOK.fb_pixelwidth.lock();
|
||||||
|
let pitch = FACEBOOK.fb_pitch.lock();
|
||||||
|
let colourtype = FACEBOOK.fb_colourtype.lock();
|
||||||
|
|
||||||
|
for i in 0..width {
|
||||||
|
for j in 0..height {
|
||||||
|
let pixel = (y * &*pitch) + (x * &*pixelwidth) + (i * &*pixelwidth) + (j * &*pitch);
|
||||||
|
if *colourtype == 0 { //BGR
|
||||||
|
unsafe {
|
||||||
|
fb[pixel + 0] = color.b;
|
||||||
|
fb[pixel + 1] = color.g;
|
||||||
|
fb[pixel + 2] = color.r;
|
||||||
|
}
|
||||||
|
} else if *colourtype == 1 { //RGB
|
||||||
|
unsafe {
|
||||||
|
fb[pixel + 0] = color.r;
|
||||||
|
fb[pixel + 1] = color.g;
|
||||||
|
fb[pixel + 2] = color.b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// average values
|
||||||
|
let avg = (color.r as u16 + color.g as u16 + color.b as u16) / 3;
|
||||||
|
unsafe {fb[pixel + 0] = avg as u8;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(pixelwidth);
|
||||||
|
drop(pitch);
|
||||||
|
drop(colourtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put_pixel(x: usize, y: usize, color: Colour, mut fb: &mut [u8]) {
|
||||||
|
let pixelwidth = FACEBOOK.fb_pixelwidth.lock();
|
||||||
|
let pitch = FACEBOOK.fb_pitch.lock();
|
||||||
|
let colourtype = FACEBOOK.fb_colourtype.lock();
|
||||||
|
|
||||||
|
let pixel = (y * &*pitch) + (x * &*pixelwidth);
|
||||||
|
|
||||||
|
if *colourtype == 0 { //BGR
|
||||||
|
unsafe {
|
||||||
|
fb[pixel + 0] = color.b;
|
||||||
|
fb[pixel + 1] = color.g;
|
||||||
|
fb[pixel + 2] = color.r;
|
||||||
|
}
|
||||||
|
} else if *colourtype == 1 { //RGB
|
||||||
|
unsafe {
|
||||||
|
fb[pixel + 0] = color.r;
|
||||||
|
fb[pixel + 1] = color.g;
|
||||||
|
fb[pixel + 2] = color.b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// average values
|
||||||
|
let avg = (color.r as u16 + color.g as u16 + color.b as u16) / 3;
|
||||||
|
unsafe {fb[pixel + 0] = avg as u8;}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(pixelwidth);
|
||||||
|
drop(pitch);
|
||||||
|
drop(colourtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn draw_char(x: usize, y: usize, c: char, color: Colour, mut fb: &mut [u8]) {
|
||||||
|
let font = font::BASIC_LEGACY;
|
||||||
|
// font is 8x8, stored in a 2d array of bytes
|
||||||
|
let char_width = 8;
|
||||||
|
let char_height = 8;
|
||||||
|
|
||||||
|
let char_index = c as usize;
|
||||||
|
let char_data = font[char_index];
|
||||||
|
|
||||||
|
for row in 0..char_height {
|
||||||
|
for col in 0..char_width {
|
||||||
|
let bit = (char_data[row] >> col) & 1;
|
||||||
|
if bit >= 1 {
|
||||||
|
put_pixel(x + col, y + row, color, fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_horizcentre_string(y: usize, s: &str, color: Colour, fb: &mut [u8]) {
|
||||||
|
let fb_width = FACEBOOK.fb_width.lock();
|
||||||
|
|
||||||
|
let mut x_tmp = (*fb_width - s.len() * 8) / 2;
|
||||||
|
let mut y_tmp = y;
|
||||||
|
|
||||||
|
for c in s.chars() {
|
||||||
|
if c == '\n' {
|
||||||
|
x_tmp = (*fb_width - s.len() * 8) / 2;
|
||||||
|
y_tmp += 8;
|
||||||
|
} else {
|
||||||
|
draw_char(x_tmp, y_tmp, c, color, fb.borrow_mut());
|
||||||
|
x_tmp += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(fb_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn generic_error(stack_frame: InterruptStackFrame) {
|
||||||
|
// cover the screen in a nice communist red (:
|
||||||
|
let mut fb = FACEBOOK.fb_mutex.lock();
|
||||||
|
let fb_width = FACEBOOK.fb_width.lock();
|
||||||
|
let fb_height = FACEBOOK.fb_height.lock();
|
||||||
|
|
||||||
|
draw_box(0,0,*fb_width,*fb_height, COMMUNIST_RED, fb.borrow_mut());
|
||||||
|
// draw our funny text
|
||||||
|
draw_horizcentre_string((*fb_height / 2) - ((3 * 8)/2), "OOPSY WOOPSY, THE KERNEL HAD A FUCKY WUCKY UWU", CUM_WHITE, fb.borrow_mut());
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn generic_error_with_code(stack_frame: InterruptStackFrame, error_code: u32) {
|
||||||
|
// cover the screen in a nice communist red (:
|
||||||
|
let mut fb = FACEBOOK.fb_mutex.lock();
|
||||||
|
let fb_width = FACEBOOK.fb_width.lock();
|
||||||
|
let fb_height = FACEBOOK.fb_height.lock();
|
||||||
|
|
||||||
|
draw_box(0,0,*fb_width,*fb_height, COMMUNIST_RED, fb.borrow_mut());
|
||||||
|
// draw our funny text
|
||||||
|
draw_horizcentre_string((*fb_height / 2) - ((3 * 8)/2), "OOPSY WOOPSY, THE KERNEL HAD A FUCKY WUCKY UWU", CUM_WHITE, fb.borrow_mut());
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn super_fuck_up_error(stack_frame: InterruptStackFrame) -> ! {
|
||||||
|
// cover the screen in a nice communist red (:
|
||||||
|
let mut fb = FACEBOOK.fb_mutex.lock();
|
||||||
|
let fb_width = FACEBOOK.fb_width.lock();
|
||||||
|
let fb_height = FACEBOOK.fb_height.lock();
|
||||||
|
|
||||||
|
draw_box(0,0,*fb_width,*fb_height, COMMUNIST_RED, fb.borrow_mut());
|
||||||
|
// draw our funny text
|
||||||
|
draw_horizcentre_string((*fb_height / 2) - ((3 * 8)/2), "OOPSY WOOPSY, THE KERNEL HAD A FUCKY WUCKY UWU", CUM_WHITE, fb.borrow_mut());
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn super_fuck_up_error_with_code(stack_frame: InterruptStackFrame, error_code: u32) -> ! {
|
||||||
|
// cover the screen in a nice communist red (:
|
||||||
|
let mut fb = FACEBOOK.fb_mutex.lock();
|
||||||
|
let fb_width = FACEBOOK.fb_width.lock();
|
||||||
|
let fb_height = FACEBOOK.fb_height.lock();
|
||||||
|
|
||||||
|
draw_box(0,0,*fb_width,*fb_height, COMMUNIST_RED, fb.borrow_mut());
|
||||||
|
// draw our funny text
|
||||||
|
draw_horizcentre_string((*fb_height / 2) - ((3 * 8)/2), "OOPSY WOOPSY, THE KERNEL HAD A FUCKY WUCKY UWU", CUM_WHITE, fb.borrow_mut());
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
|
pub mod errors;
|
||||||
|
|
||||||
pub mod WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood {
|
pub mod WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood {
|
||||||
|
use core::arch::asm;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -19,35 +22,141 @@ pub mod WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood {
|
||||||
pub const COMMUNIST_RED: Colour = Colour{r:245,g:77,b:30};
|
pub const COMMUNIST_RED: Colour = Colour{r:245,g:77,b:30};
|
||||||
pub const CUM_WHITE: Colour = Colour{r:255,g:255,b:255};
|
pub const CUM_WHITE: Colour = Colour{r:255,g:255,b:255};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct IDTEntry<F> {
|
pub struct IDTEntry<F> {
|
||||||
based_offset: u16,
|
based_offset: u16,
|
||||||
code_selector: u16,
|
code_selector: u16,
|
||||||
ist_offset_wastes_6_bits: u8,
|
ist_offset_wastes_6_bits: u8,
|
||||||
attributes: u8,
|
attributes: u8,
|
||||||
mid_offset: u16,
|
offset_popping_off: u16,
|
||||||
offset_popping_off: u32,
|
|
||||||
what: PhantomData<F>
|
what: PhantomData<F>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InterruptDescriptorTable {
|
impl<F> IDTEntry<F> {
|
||||||
pub divide_error: IDTEntry<ErrorHandler>,
|
pub fn default() -> Self {
|
||||||
pub debug: IDTEntry<ErrorHandler>,
|
IDTEntry {
|
||||||
pub dream_mask_sus_version: IDTEntry<ErrorHandler>, // non-maskable interrupt
|
based_offset: 0,
|
||||||
pub breakpoint: IDTEntry<ErrorHandler>,
|
code_selector: 0,
|
||||||
pub into_detected_overflow: IDTEntry<ErrorHandler>,
|
ist_offset_wastes_6_bits: 0,
|
||||||
pub in_the_fortnite_storm: IDTEntry<ErrorHandler>, // bound range exceeded
|
attributes: 0,
|
||||||
pub owo_whats_this: IDTEntry<ErrorHandler>, // invalid opcode
|
offset_popping_off: 0,
|
||||||
pub device_not_available: IDTEntry<ErrorHandler>,
|
what: PhantomData
|
||||||
pub fucky_wucky_twice: IDTEntry<ErrorHandler>, // double fault
|
}
|
||||||
we_are_all_about_backwards_compatibility: IDTEntry<ErrorHandler>, // coprocessor segment overrun
|
}
|
||||||
pub invalid_tss: IDTEntry<ErrorHandler>,
|
|
||||||
pub segment_not_present: IDTEntry<ErrorHandler>,
|
|
||||||
pub stack_segment_fault: IDTEntry<ErrorHandler>,
|
|
||||||
pub uh_oh_we_gotta_hacker_here: IDTEntry<ErrorHandler>, // general protection fault
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrorHandler(());
|
macro_rules! impl_idtentry {
|
||||||
|
($f:ty) => {
|
||||||
|
impl IDTEntry<$f> {
|
||||||
|
pub fn set_handler(&mut self, handler: $f) {
|
||||||
|
unsafe { // no shit this is unsafe, i wrote it (:
|
||||||
|
let handler_addr = handler as u32;
|
||||||
|
self.based_offset = handler_addr as u16;
|
||||||
|
self.offset_popping_off = (handler_addr >> 16) as u16;
|
||||||
|
let code_selector : u16;
|
||||||
|
asm!("mov {0:x}, cs", out(reg) code_selector, options(nomem, nostack, preserves_flags));
|
||||||
|
self.code_selector = code_selector;
|
||||||
|
self.attributes = 0b10001110;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct InterruptDescriptorTable {
|
||||||
|
pub divide_error: IDTEntry<InterruptHandler>,
|
||||||
|
pub debug: IDTEntry<InterruptHandler>,
|
||||||
|
pub dream_mask_sus_version: IDTEntry<InterruptHandler>, // non-maskable interrupt
|
||||||
|
pub breakpoint: IDTEntry<InterruptHandler>,
|
||||||
|
pub into_detected_overflow: IDTEntry<InterruptHandler>,
|
||||||
|
pub in_the_fortnite_storm: IDTEntry<InterruptHandler>, // bound range exceeded
|
||||||
|
pub owo_whats_this: IDTEntry<InterruptHandler>, // invalid opcode
|
||||||
|
pub device_not_available: IDTEntry<InterruptHandler>,
|
||||||
|
pub fucky_wucky_twice: IDTEntry<SeriousFuckUpWithErrorCodeHandler>, // double fault
|
||||||
|
we_are_all_about_backwards_compatibility: IDTEntry<InterruptHandler>, // coprocessor segment overrun
|
||||||
|
pub invalid_tss: IDTEntry<ErrorWithErrorCodeHandler>,
|
||||||
|
pub segment_not_present: IDTEntry<ErrorWithErrorCodeHandler>,
|
||||||
|
pub stack_segment_fault: IDTEntry<ErrorWithErrorCodeHandler>,
|
||||||
|
pub uh_oh_we_gotta_hacker_here: IDTEntry<ErrorWithErrorCodeHandler>, // general protection fault
|
||||||
|
pub page_fault: IDTEntry<ErrorWithErrorCodeHandler>,
|
||||||
|
reserved_1: IDTEntry<InterruptHandler>, // what the fuck is this?? the only comment is "vector nr.15"
|
||||||
|
pub x87_floating_point_exception: IDTEntry<InterruptHandler>, // compatibility B)
|
||||||
|
pub alignment_check: IDTEntry<ErrorWithErrorCodeHandler>,
|
||||||
|
pub machine_check: IDTEntry<SeriousFuckUpHandler>,
|
||||||
|
pub the_point_of_the_mask_float_exception: IDTEntry<InterruptHandler>, // simd floating point exception
|
||||||
|
pub virtualization_exception: IDTEntry<InterruptHandler>, // qemu WILL be added to windows 12 B)
|
||||||
|
reserved_2: IDTEntry<InterruptHandler>, // another reserved
|
||||||
|
pub vmm_communication_exception: IDTEntry<ErrorWithErrorCodeHandler>, // honestly too tired to check what this is
|
||||||
|
pub security_exception: IDTEntry<ErrorWithErrorCodeHandler>,
|
||||||
|
reserved_3: IDTEntry<InterruptHandler>,
|
||||||
|
|
||||||
|
pub interrupts: [IDTEntry<InterruptHandler>; 256 - 32], // the original one didn't make this public, but who care (:
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InterruptDescriptorTable {
|
||||||
|
pub fn new() -> InterruptDescriptorTable {
|
||||||
|
InterruptDescriptorTable {
|
||||||
|
divide_error: IDTEntry::default(),
|
||||||
|
debug: IDTEntry::default(),
|
||||||
|
dream_mask_sus_version: IDTEntry::default(),
|
||||||
|
breakpoint: IDTEntry::default(),
|
||||||
|
into_detected_overflow: IDTEntry::default(),
|
||||||
|
in_the_fortnite_storm: IDTEntry::default(),
|
||||||
|
owo_whats_this: IDTEntry::default(),
|
||||||
|
device_not_available: IDTEntry::default(),
|
||||||
|
fucky_wucky_twice: IDTEntry::default(),
|
||||||
|
we_are_all_about_backwards_compatibility: IDTEntry::default(),
|
||||||
|
invalid_tss: IDTEntry::default(),
|
||||||
|
segment_not_present: IDTEntry::default(),
|
||||||
|
stack_segment_fault: IDTEntry::default(),
|
||||||
|
uh_oh_we_gotta_hacker_here: IDTEntry::default(),
|
||||||
|
page_fault: IDTEntry::default(),
|
||||||
|
reserved_1: IDTEntry::default(),
|
||||||
|
x87_floating_point_exception: IDTEntry::default(),
|
||||||
|
alignment_check: IDTEntry::default(),
|
||||||
|
machine_check: IDTEntry::default(),
|
||||||
|
the_point_of_the_mask_float_exception: IDTEntry::default(),
|
||||||
|
virtualization_exception: IDTEntry::default(),
|
||||||
|
reserved_2: IDTEntry::default(),
|
||||||
|
vmm_communication_exception: IDTEntry::default(),
|
||||||
|
security_exception: IDTEntry::default(),
|
||||||
|
reserved_3: IDTEntry::default(),
|
||||||
|
interrupts: [IDTEntry::default(); 256 - 32]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(&'static self) {
|
||||||
|
unsafe {
|
||||||
|
// load the IDT
|
||||||
|
let idt_ptr = &self as *const _ as *const _;
|
||||||
|
asm!("lidt [{}]", in(reg) idt_ptr, options(readonly, nostack, preserves_flags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type InterruptHandler = extern "x86-interrupt" fn(_: InterruptStackFrame);
|
||||||
|
pub type ErrorWithErrorCodeHandler = extern "x86-interrupt" fn(_: InterruptStackFrame, error_code: u32);
|
||||||
|
pub type SeriousFuckUpHandler = extern "x86-interrupt" fn(_: InterruptStackFrame) -> !;
|
||||||
|
pub type SeriousFuckUpWithErrorCodeHandler = extern "x86-interrupt" fn(_: InterruptStackFrame, error_code: u32) -> !;
|
||||||
|
|
||||||
|
impl_idtentry!(InterruptHandler);
|
||||||
|
impl_idtentry!(ErrorWithErrorCodeHandler);
|
||||||
|
impl_idtentry!(SeriousFuckUpHandler);
|
||||||
|
impl_idtentry!(SeriousFuckUpWithErrorCodeHandler);
|
||||||
|
|
||||||
|
// y'know the x86 crate has a point with doing it this way, so i'm gonna do the same (:
|
||||||
|
|
||||||
|
pub struct InterruptStackFrame {
|
||||||
|
pub value: InterruptStackValues,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InterruptStackValues {
|
||||||
|
pub instruction_pointer: u32,
|
||||||
|
pub code_segment: u32,
|
||||||
|
pub cpu_flags: u32,
|
||||||
|
pub stack_pointer: u32,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum ErrorKind {
|
pub enum ErrorKind {
|
||||||
HardwareFuckUp,
|
HardwareFuckUp,
|
||||||
|
|
110
src/main.rs
110
src/main.rs
|
@ -1,6 +1,16 @@
|
||||||
|
#![feature(abi_x86_interrupt)]
|
||||||
|
#![feature(default_alloc_error_handler)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
use allocator::*;
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use spin::Mutex;
|
||||||
|
use core::arch::asm;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use bootloader::{entry_point, BootInfo, boot_info};
|
use bootloader::{entry_point, BootInfo, boot_info};
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use bootloader::boot_info::{FrameBuffer, FrameBufferInfo, PixelFormat};
|
use bootloader::boot_info::{FrameBuffer, FrameBufferInfo, PixelFormat};
|
||||||
|
@ -10,7 +20,58 @@ use crate::serial::potential_serial_ports;
|
||||||
mod font;
|
mod font;
|
||||||
mod serial;
|
mod serial;
|
||||||
mod internals;
|
mod internals;
|
||||||
|
mod allocator;
|
||||||
|
|
||||||
|
pub struct FBInfo {
|
||||||
|
pub fb_mutex: Mutex<Vec<u8>>,
|
||||||
|
pub fb_pixelwidth: Mutex<usize>,
|
||||||
|
pub fb_colourtype: Mutex<u8>,
|
||||||
|
pub fb_pitch: Mutex<usize>,
|
||||||
|
pub fb_width: Mutex<usize>,
|
||||||
|
pub fb_height: Mutex<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS IS THE ONLY GLOBAL VARIABLE WE WILL EVER HAVE, MARK THIS ON MY FUCKING GRAVE
|
||||||
|
//pub static mut FRAMEBUFFER: Option<FBInfo> = None;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref IDT : InterruptDescriptorTable = {
|
||||||
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
|
idt.divide_error.set_handler(internals::errors::generic_error);
|
||||||
|
idt.debug.set_handler(internals::errors::generic_error);
|
||||||
|
idt.dream_mask_sus_version.set_handler(internals::errors::generic_error);
|
||||||
|
idt.breakpoint.set_handler(internals::errors::generic_error);
|
||||||
|
idt.into_detected_overflow.set_handler(internals::errors::generic_error);
|
||||||
|
idt.in_the_fortnite_storm.set_handler(internals::errors::generic_error);
|
||||||
|
idt.owo_whats_this.set_handler(internals::errors::generic_error);
|
||||||
|
idt.device_not_available.set_handler(internals::errors::generic_error);
|
||||||
|
idt.fucky_wucky_twice.set_handler(internals::errors::super_fuck_up_error_with_code);
|
||||||
|
idt.invalid_tss.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.segment_not_present.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.stack_segment_fault.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.uh_oh_we_gotta_hacker_here.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.page_fault.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.x87_floating_point_exception.set_handler(internals::errors::generic_error);
|
||||||
|
idt.alignment_check.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.machine_check.set_handler(internals::errors::super_fuck_up_error);
|
||||||
|
idt.the_point_of_the_mask_float_exception.set_handler(internals::errors::generic_error);
|
||||||
|
idt.virtualization_exception.set_handler(internals::errors::generic_error);
|
||||||
|
idt.vmm_communication_exception.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt.security_exception.set_handler(internals::errors::generic_error_with_code);
|
||||||
|
idt
|
||||||
|
};
|
||||||
|
|
||||||
|
static ref FACEBOOK : FBInfo = {
|
||||||
|
FBInfo {
|
||||||
|
fb_mutex: Mutex::new(Vec::new()),
|
||||||
|
fb_pixelwidth: Mutex::new(0),
|
||||||
|
fb_colourtype: Mutex::new(0),
|
||||||
|
fb_pitch: Mutex::new(0),
|
||||||
|
fb_width: Mutex::new(0),
|
||||||
|
fb_height: Mutex::new(0),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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}];
|
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}];
|
||||||
|
@ -28,7 +89,7 @@ fn KernelPanic(msg: KernelError, fb: &mut FrameBuffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_pixel(x: usize, y: usize, color: Colour, fb: &mut FrameBuffer) {
|
pub fn put_pixel(x: usize, y: usize, color: Colour, fb: &mut FrameBuffer) {
|
||||||
let pixelwidth = fb.info().bytes_per_pixel;
|
let pixelwidth = fb.info().bytes_per_pixel;
|
||||||
let pitch = fb.info().stride * pixelwidth;
|
let pitch = fb.info().stride * pixelwidth;
|
||||||
|
|
||||||
|
@ -49,7 +110,7 @@ fn put_pixel(x: usize, y: usize, color: Colour, fb: &mut FrameBuffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_box(x: usize, y: usize, width: usize, height: usize, color: Colour, fb: &mut FrameBuffer) {
|
pub fn draw_box(x: usize, y: usize, width: usize, height: usize, color: Colour, fb: &mut FrameBuffer) {
|
||||||
let pixelwidth = fb.info().bytes_per_pixel;
|
let pixelwidth = fb.info().bytes_per_pixel;
|
||||||
let pitch = fb.info().stride * pixelwidth;
|
let pitch = fb.info().stride * pixelwidth;
|
||||||
|
|
||||||
|
@ -92,7 +153,7 @@ fn draw_char(x: usize, y: usize, c: char, color: Colour, fb: &mut FrameBuffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_string(x: usize, y: usize, s: &str, color: Colour, fb: &mut FrameBuffer) {
|
pub fn draw_string(x: usize, y: usize, s: &str, color: Colour, fb: &mut FrameBuffer) {
|
||||||
let mut x_tmp = x;
|
let mut x_tmp = x;
|
||||||
let mut y_tmp = y;
|
let mut y_tmp = y;
|
||||||
|
|
||||||
|
@ -107,7 +168,7 @@ fn draw_string(x: usize, y: usize, s: &str, color: Colour, fb: &mut FrameBuffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_horizcentre_string(y: usize, s: &str, color: Colour, fb: &mut FrameBuffer) {
|
pub fn draw_horizcentre_string(y: usize, s: &str, color: Colour, fb: &mut FrameBuffer) {
|
||||||
let mut x_tmp = (fb.info().horizontal_resolution - s.len() * 8) / 2;
|
let mut x_tmp = (fb.info().horizontal_resolution - s.len() * 8) / 2;
|
||||||
let mut y_tmp = y;
|
let mut y_tmp = y;
|
||||||
|
|
||||||
|
@ -122,7 +183,7 @@ fn draw_horizcentre_string(y: usize, s: &str, color: Colour, fb: &mut FrameBuffe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_rainbow_string(x: usize, y: usize, s: &str, fb: &mut FrameBuffer) {
|
pub fn draw_rainbow_string(x: usize, y: usize, s: &str, fb: &mut FrameBuffer) {
|
||||||
let mut x_tmp = x;
|
let mut x_tmp = x;
|
||||||
let mut y_tmp = y;
|
let mut y_tmp = y;
|
||||||
|
|
||||||
|
@ -141,23 +202,62 @@ fn draw_rainbow_string(x: usize, y: usize, s: &str, fb: &mut FrameBuffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
entry_point!(main);
|
entry_point!(main);
|
||||||
|
|
||||||
fn main(boot_info: &'static mut BootInfo) -> ! {
|
fn main(boot_info: &'static mut BootInfo) -> ! {
|
||||||
|
|
||||||
if let Some(framebuffer) = boot_info.framebuffer.as_mut() {
|
if let Some(framebuffer) = boot_info.framebuffer.as_mut() {
|
||||||
|
// set up the framebuffer
|
||||||
|
unsafe {
|
||||||
|
let mut colourtype: u8;
|
||||||
|
if framebuffer.info().pixel_format == PixelFormat::RGB {
|
||||||
|
colourtype = 1;
|
||||||
|
} else {
|
||||||
|
colourtype = 0;
|
||||||
|
}
|
||||||
|
let mut temp_fb = FACEBOOK.fb_mutex.lock();
|
||||||
|
*temp_fb = Vec::from_raw_parts(framebuffer.buffer_mut().as_mut_ptr(), framebuffer.buffer_mut().len(), framebuffer.buffer_mut().len());
|
||||||
|
drop(temp_fb);
|
||||||
|
|
||||||
|
let mut temp_fb_pixel_width = FACEBOOK.fb_pixelwidth.lock();
|
||||||
|
*temp_fb_pixel_width = framebuffer.info().bytes_per_pixel;
|
||||||
|
drop(temp_fb_pixel_width);
|
||||||
|
|
||||||
|
let mut temp_fb_fb_colourtype = FACEBOOK.fb_colourtype.lock();
|
||||||
|
*temp_fb_fb_colourtype = colourtype;
|
||||||
|
drop(temp_fb_fb_colourtype);
|
||||||
|
|
||||||
|
let mut temp_fb_fb_width = FACEBOOK.fb_width.lock();
|
||||||
|
*temp_fb_fb_width = framebuffer.info().horizontal_resolution;
|
||||||
|
drop(temp_fb_fb_width);
|
||||||
|
|
||||||
|
let mut temp_fb_fb_height = FACEBOOK.fb_height.lock();
|
||||||
|
*temp_fb_fb_height = framebuffer.info().vertical_resolution;
|
||||||
|
drop(temp_fb_fb_height);
|
||||||
|
|
||||||
|
let mut temp_fb_fb_pitch = FACEBOOK.fb_pitch.lock();
|
||||||
|
*temp_fb_fb_pitch = framebuffer.info().stride;
|
||||||
|
drop(temp_fb_fb_pitch);
|
||||||
|
}
|
||||||
// cover the screen in a nice blue
|
// cover the screen in a nice blue
|
||||||
draw_box(0, 0, framebuffer.info().horizontal_resolution, framebuffer.info().vertical_resolution, Colour{r:30,g:129,b:176}, framebuffer);
|
draw_box(0, 0, framebuffer.info().horizontal_resolution, framebuffer.info().vertical_resolution, Colour{r:30,g:129,b:176}, framebuffer);
|
||||||
|
|
||||||
let fb_width = framebuffer.info().horizontal_resolution;
|
let fb_width = framebuffer.info().horizontal_resolution;
|
||||||
let fb_height = framebuffer.info().vertical_resolution;
|
let fb_height = framebuffer.info().vertical_resolution;
|
||||||
|
|
||||||
|
IDT.load();
|
||||||
|
|
||||||
// draw a test string
|
// draw a test string
|
||||||
//draw_string(20, 20, "i love drinking cum\nnewline test", Colour { r: 255, g: 0, b: 255 }, framebuffer);
|
//draw_string(20, 20, "i love drinking cum\nnewline test", Colour { r: 255, g: 0, b: 255 }, framebuffer);
|
||||||
//draw_rainbow_string(20, 40, "gay sex", framebuffer);
|
//draw_rainbow_string(20, 40, "gay sex", framebuffer);
|
||||||
|
|
||||||
//draw_string(20,20, "),:\n\n\n\nuh oh! windows error! your computer is not compatible with windows 12\n\ncontact billgate@realmicrosoft.com to fix this issue!", Colour { r: 255, g: 255, b: 255}, framebuffer);
|
//draw_string(20,20, "),:\n\n\n\nuh oh! windows error! your computer is not compatible with windows 12\n\ncontact billgate@realmicrosoft.com to fix this issue!", Colour { r: 255, g: 255, b: 255}, framebuffer);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
asm!("int3", options(nomem, nostack));
|
||||||
|
}
|
||||||
|
|
||||||
draw_horizcentre_string(((fb_height/2)-4)-16, "welcome to windows 12! here is info:", CUM_WHITE, framebuffer);
|
draw_horizcentre_string(((fb_height/2)-4)-16, "welcome to windows 12! here is info:", CUM_WHITE, framebuffer);
|
||||||
|
|
||||||
// time for some funny com port stuff
|
// time for some funny com port stuff
|
||||||
|
|
Loading…
Reference in a new issue