Skip to content

Commit

Permalink
Checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
8176135 committed Jun 7, 2020
1 parent 71c335b commit c9efda3
Show file tree
Hide file tree
Showing 15 changed files with 503 additions and 77 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ edition = "2018"
#[profile.release]
#panic = "abort"

[profile.release]
debug = true

[package.metadata.bootimage]
run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}", "-S", "-gdb", "tcp::9009"]
test-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "stdio",
"-display", "none"]
test-success-exit-code = 33 # (0x10 << 1) | 1
Expand Down
13 changes: 13 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::env;

fn main() {
let mut input = std::fs::read_to_string("src/setup_process_stack.s").unwrap();
let replacement= match env::var("OPT_LEVEL").unwrap().as_ref() {
"0" => "0x40", // Debug build
"3" => "0x90", // Release build
opt_lvl => panic!("Wtf is this opt level: {}", opt_lvl),
};

std::fs::write("src/setup_process_stack.s.out",
input.replace("<RSP_SUB_VAL>", replacement)).unwrap();
}
46 changes: 46 additions & 0 deletions src/context_switch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use crate::kernel::Pid;
use crate::println;
use crate::registers::Registers;
use crate::kernel::Process;

// pub fn save_state(old_process: &mut Process) {
//
// }
//
// pub fn context_switch(new_process: &mut Process, old_pid: Option<&mut Process>, old_registers: Option<Registers>) {
// if let Some(old_pid) = old_pid {
// let rax: u64 = 0;
// let rcx: u64 = 0;
// let rdx: u64 = 0;
// let rbx: u64 = 0;
// let rsp: u64 = 0;
// let rbp: u64 = 0;
// let rsi: u64 = 0;
// let rdi: u64 = 0;
//
// unsafe {
// llvm_asm!("mov %rdi, $0" : "=r" (rdi));
// llvm_asm!("mov %rax, $0" : "=r" (rax));
// llvm_asm!("mov %rdx, $0" : "=r" (rdx));
// llvm_asm!("mov %rcx, $0" : "=r" (rcx));
// llvm_asm!("mov %rsi, $0" : "=r" (rsi));
// llvm_asm!("mov %rsp, $0" : "=r" (rsp));
// llvm_asm!("mov %rbx, $0" : "=r" (rbx));
// llvm_asm!("mov %rbp, $0" : "=r" (rbp));
// }
//
// let regs = Registers {
// rax,
// rcx,
// rdx,
// rbx,
// rsp,
// rbp,
// rsi,
// rdi
// };
//
// println!("DOES THIS WORK: {:?}", regs);
// old_pid.set_regs(regs);
// }
// }
13 changes: 13 additions & 0 deletions src/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use crate::println;

#[inline(always)]
pub fn print_stack_pointer() {
let other: usize;
unsafe {
llvm_asm!( "
mov %rsp, $0
": "={rsp}"(other): :
: "volatile");
}
println!("{:x}", other);
}
45 changes: 43 additions & 2 deletions src/interrupts/hardware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,68 @@ use pic8259_simple::ChainedPics;
use x86_64::structures::idt::InterruptStackFrame;
use lazy_static::lazy_static;
use crate::{print, println};
use core::intrinsics::breakpoint;

pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
pub const SYSCALL_IDX: u8 = 0x80;

pub static PICS: spin::Mutex<ChainedPics> = // Remap PIC ports via offset
spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });

#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum InterruptIndex {
Syscall = SYSCALL_IDX,
Timer = PIC_1_OFFSET,
Keyboard, // +1
}

pub extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: &mut InterruptStackFrame) {
print!(".");
#[inline(never)]
pub extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: &mut InterruptStackFrame) { // NOTE: Please don't touch, everything relies on the fact that the compiler only uses 0x40 of the stack when executing this function
let stack_pointer: usize;
let return_pointer;
unsafe {
llvm_asm!( "
mov %rsp, $0
": "=r"(stack_pointer): : : "volatile");

return_pointer = crate::scheduling::check_schedule(stack_pointer);
// x86_64::registers::control::Cr3::read()
llvm_asm!( "
mov $0, %rsp
": : "r" (return_pointer): "rsp" : "volatile");
}
unsafe {
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer as u8);
}
unsafe {
llvm_asm!( "
nop
": : : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rbp" : "volatile");
}
}

// #[inline(never)]
// pub extern "C" fn random_thing(_stack_frame: usize) {
// let stack_pointer: usize;
// unsafe {
// llvm_asm!( "
// mov %rsp, $0
// ": "={rsp}"(stack_pointer): :
// "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" :
// "volatile");
//
// let return_pointer = crate::scheduling::check_schedule(stack_pointer);
//
// llvm_asm!( "
// mov $0, %rsp
// ": : "{rsp}" (return_pointer):
// "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" :
// "volatile");
// }
// }

pub extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: &mut InterruptStackFrame) {
use x86_64::instructions::port::Port;
use spin::{Mutex, MutexGuard};
Expand Down
9 changes: 7 additions & 2 deletions src/interrupts/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use x86_64::structures::idt::InterruptDescriptorTable;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
use hardware::InterruptIndex;
use lazy_static::lazy_static;

mod cpu;
mod hardware;
pub mod hardware;

lazy_static! {
static ref IDT: InterruptDescriptorTable = create_idt();
Expand All @@ -15,6 +15,10 @@ pub fn interrupt_init() {
x86_64::instructions::interrupts::enable();
}

pub extern "x86-interrupt" fn syscall(_stack_frame: &mut InterruptStackFrame) {
println!("yay a syscall happened!");
}

fn create_idt() -> InterruptDescriptorTable {
let mut idt = InterruptDescriptorTable::new();
idt.breakpoint.set_handler_fn(cpu::breakpoint_handler);
Expand All @@ -25,5 +29,6 @@ fn create_idt() -> InterruptDescriptorTable {
}
idt[InterruptIndex::Timer as u8 as usize].set_handler_fn(hardware::timer_interrupt_handler);
idt[InterruptIndex::Keyboard as u8 as usize].set_handler_fn(hardware::keyboard_interrupt_handler);
idt[InterruptIndex::Syscall as u8 as usize].set_handler_fn(syscall);
idt
}
100 changes: 48 additions & 52 deletions src/kernel.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,27 @@
use crate::interrupts::interrupt_init;
use crate::gdt::gdt_init;
use crate::{println, print};
use crate::{println, print, helper};
use crate::special_collections::{IncrementingPool, DynamicBitmap};
use x86_64::instructions::interrupts;
use lazy_static::lazy_static;
use spin::Mutex;

use alloc::vec::Vec;
use alloc::vec;
use x86_64::{PhysAddr, VirtAddr};
use x86_64::structures::idt::InterruptStackFrame;
use crate::memory::{StackBounds, alloc_stack};
use volatile::Volatile;
use crate::kernel::SchedulingLevel::Periodic;
use x86_64::instructions::interrupts::without_interrupts;
use core::sync::atomic::AtomicUsize;
use crate::processes::process::SchedulingLevel::Periodic;

type Name = u64;
type Pid = u64;

#[derive(Clone, Copy, Debug)]
struct Registers {}

#[derive(Clone, Copy, Debug)]
struct Process {
pid: u64,
regs: Option<Registers>,
level: SchedulingLevel,
name: Name,
arg: i32,
}

impl Process {
// TODO: Implement error type
fn new(level: SchedulingLevel, name: Name, arg: i32) -> Result<Process, ()> {
match level {
SchedulingLevel::Device => {},
SchedulingLevel::Periodic => {
if !NAME_REGISTRY.lock().set_bit(name as usize) {
// Name already taken
return Err(())
}
},
SchedulingLevel::Sporadic => {},
}
let pid = PID_POOL.lock().get_free_elem();

Ok(Process {
pid,
regs: None,
level,
name,
arg,
})
}
}
pub static CURRENT_PROCESS: AtomicUsize = AtomicUsize::new(0);

lazy_static! {
static ref PROCESSES: Mutex<Vec<Process>> = Mutex::new(Vec::new());
static ref PID_POOL: Mutex<IncrementingPool> = Mutex::new(IncrementingPool::new(2));
pub static ref PROCESSES: Mutex<Vec<Option<Process>>> = Mutex::new(vec![None; 2]);
static ref PID_POOL: Mutex<IncrementingPool> = Mutex::new(IncrementingPool::new(1));
static ref NAME_REGISTRY: Mutex<DynamicBitmap> = Mutex::new(DynamicBitmap::new());
}

Expand All @@ -59,20 +30,45 @@ pub fn os_init() {
gdt_init();
}

pub fn os_start() {}
#[inline(never)]
pub fn os_start() {
// crate::interrupts::hardware::random_thing(123);
// crate::context_switch::context_switch(123, Some(123));
os_create(123, Periodic, 333, *&test_app);
tester(1);
}

extern "C" fn os_terminate() -> ! {
println!("We out of there!");
loop {}
}

#[derive(Copy, Clone, Debug)]
enum SchedulingLevel {
Device = 0,
Periodic = 1,
Sporadic = 2,
#[inline(never)]
fn tester(item: usize) {
let other: usize;
helper::print_stack_pointer();
loop {}
}

fn os_create<F: FnOnce() -> ()>(f: F, arg: i32, level: SchedulingLevel, name: i32) -> Result<u64, ()>{
// Process::new(level, name, arg);
fn os_create(arg: i32, level: SchedulingLevel, name: Name, f: extern "C" fn()) -> Result<u64, ()> {
let process = Process::new(level, name, arg, f)?;

Ok(without_interrupts(|| {
let mut lock = PROCESSES.lock();

if process.get_idx() >= lock.len() {
lock.resize(process.get_idx() + 1, None);
}
let out_pid = process.pid;

assert!(lock[process.get_idx()].is_none(), "PID of new process is not empty");
lock[process.get_idx()] = Some(process);
out_pid
}))
}

// Process::new()
unimplemented!()
extern "C" fn test_app() {
println!("YOLO!!");
}

pub fn os_abort() {
Expand Down
37 changes: 25 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![no_main]
#![no_std]

#![feature(core_intrinsics)]
#![feature(global_asm)]
#![feature(llvm_asm)]
#![feature(const_in_array_repeat_expressions)]
#![feature(const_fn)]
#![feature(abi_x86_interrupt)]
Expand All @@ -18,22 +21,35 @@ mod tests;
mod serial;
mod interrupts;
mod gdt;
mod context_switch;
mod helper;

// Logic
mod kernel;
// mod static_collections;
mod processes;

// Collections
mod special_collections;

use x86_64::VirtAddr;
use lazy_static::lazy_static;
use spin::Mutex;
use crate::memory::paging::BootInfoFrameAllocator;

static FRAME_ALLOCATOR: Mutex<BootInfoFrameAllocator> = Mutex::new(BootInfoFrameAllocator::new());
static TEMP_MAPPER: Mutex<Option<OffsetPageTable>> = Mutex::new(None);

#[no_mangle]
pub extern "C" fn _start(boot_info: &'static bootloader::BootInfo) -> ! {

let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
let mut mapper = unsafe { memory::paging::init(phys_mem_offset) };
let mut frame_allocator = unsafe {
BootInfoFrameAllocator::init(&boot_info.memory_map)
};

memory::allocator::init_heap(&mut mapper, &mut frame_allocator)
unsafe { FRAME_ALLOCATOR.lock().init(&boot_info.memory_map) };

memory::allocator::init_heap(&mut mapper, &mut *FRAME_ALLOCATOR.lock())
.expect("Failed to init heap");

*TEMP_MAPPER.lock() = Some(mapper);

kernel::os_init();

#[cfg(test)]
Expand All @@ -42,14 +58,11 @@ pub extern "C" fn _start(boot_info: &'static bootloader::BootInfo) -> ! {
kernel::os_start();

println!("Didn't quite crash");
loop {
x86_64::instructions::hlt();
}
loop {}
}

use core::panic::PanicInfo;
use x86_64::VirtAddr;
use crate::memory::paging::BootInfoFrameAllocator;
use x86_64::structures::paging::OffsetPageTable;

/// This function is called on panic.
Expand Down
Loading

0 comments on commit c9efda3

Please sign in to comment.