Compare commits

...

2 Commits

Author SHA1 Message Date
husky b81c5a76d8
fuck it we're using the x86_64 crate 2022-04-19 23:49:19 -07:00
husky 2c740c9d8a
FUCK we have to convert this all to 64 bit (,: 2022-04-19 23:12:21 -07:00
9 changed files with 304 additions and 36 deletions

12
.idea/customTargets.xml Normal file
View 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
View 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>

View 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>

View File

@ -4,6 +4,9 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/simple_boot/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" />
</content>
<orderEntry type="inheritedJdk" />

View File

@ -9,4 +9,9 @@ members = [
]
[dependencies]
bootloader = "0.10.12"
bootloader = "0.10.12"
spin = "0.9.1"
x86_64 = "0.14.9"
[dependencies.lazy_static]
version = "1.4.0"
features = ["spin_no_std"]

55
src/allocator/mod.rs Normal file
View 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) {}
}

121
src/internals/errors.rs Normal file
View File

@ -0,0 +1,121 @@
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(width: usize, y: usize, s: &str, color: Colour, fb: &mut [u8]) {
let mut x_tmp = (width - s.len() * 8) / 2;
let mut y_tmp = y;
for c in s.chars() {
if c == '\n' {
x_tmp = (width - s.len() * 8) / 2;
y_tmp += 8;
} else {
draw_char(x_tmp, y_tmp, c, color, fb.borrow_mut());
x_tmp += 8;
}
}
}
pub extern "x86-interrupt" fn breakpoint_exception(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_width,(*fb_height / 2) - (14 * (8/2)), "OOPSY WOOPSY, THE KERNEL HAD A FUCKY WUCKY UWU", CUM_WHITE, fb.borrow_mut());
draw_horizcentre_string(*fb_width,(*fb_height / 2) - (10 * (8/2)), "WHOEVER WAS PROGRAMMING THE KERNEL DECIDED TO LEAVE A BREAKPOINT IN IT, OOPS (:", CUM_WHITE, fb.borrow_mut());
draw_horizcentre_string(*fb_width,(*fb_height / 2) - (4 * (8/2)), "THE KERNEL IS NOW HALTED, YOU CAN'T DO ANYTHING UNTIL YOU RESTART THE KERNEL", CUM_WHITE, fb.borrow_mut());
drop(fb_width);
drop(fb_height);
drop(fb);
}

View File

@ -1,4 +1,7 @@
pub mod errors;
pub mod WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood {
use core::arch::asm;
use core::marker::PhantomData;
#[derive(Clone, Copy)]
@ -19,36 +22,6 @@ pub mod WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood {
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 struct IDTEntry<F> {
based_offset: u16,
code_selector: u16,
ist_offset_wastes_6_bits: u8,
attributes: u8,
mid_offset: u16,
offset_popping_off: u32,
what: PhantomData<F>
}
pub struct InterruptDescriptorTable {
pub divide_error: IDTEntry<ErrorHandler>,
pub debug: IDTEntry<ErrorHandler>,
pub dream_mask_sus_version: IDTEntry<ErrorHandler>, // non-maskable interrupt
pub breakpoint: IDTEntry<ErrorHandler>,
pub into_detected_overflow: IDTEntry<ErrorHandler>,
pub in_the_fortnite_storm: IDTEntry<ErrorHandler>, // bound range exceeded
pub owo_whats_this: IDTEntry<ErrorHandler>, // invalid opcode
pub device_not_available: IDTEntry<ErrorHandler>,
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(());
pub enum ErrorKind {
HardwareFuckUp,
}

View File

@ -1,16 +1,58 @@
#![feature(abi_x86_interrupt)]
#![feature(default_alloc_error_handler)]
#![no_std]
#![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 core::panic::PanicInfo;
use bootloader::boot_info::{FrameBuffer, FrameBufferInfo, PixelFormat};
use crate::internals::WhyDoTheyCallItOvenWhenYouOfInTheColdFoodOfOutHotEatTheFood::*;
use crate::serial::potential_serial_ports;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
mod font;
mod serial;
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.breakpoint.set_handler_fn(internals::errors::breakpoint_exception);
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}];
@ -28,7 +70,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 pitch = fb.info().stride * pixelwidth;
@ -49,7 +91,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 pitch = fb.info().stride * pixelwidth;
@ -92,7 +134,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 y_tmp = y;
@ -107,7 +149,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 y_tmp = y;
@ -122,7 +164,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 y_tmp = y;
@ -141,23 +183,61 @@ fn draw_rainbow_string(x: usize, y: usize, s: &str, fb: &mut FrameBuffer) {
}
}
entry_point!(main);
fn main(boot_info: &'static mut BootInfo) -> ! {
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 * framebuffer.info().bytes_per_pixel;
drop(temp_fb_fb_pitch);
}
// 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);
let fb_width = framebuffer.info().horizontal_resolution;
let fb_height = framebuffer.info().vertical_resolution;
IDT.load();
// draw a test string
//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_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);
x86_64::instructions::interrupts::int3();
/*
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
@ -175,7 +255,9 @@ fn main(boot_info: &'static mut BootInfo) -> ! {
//draw_rainbow_string((fb_width/2) - ((7*8)/2), (fb_height/2) - 4, "gay sex", framebuffer);
*/
}
loop{}
}