stack allocator, keyboard doesnt work with interrupts yet, i think i need to tell 0x20 and 0x21 to shift interrupt by 32 because of intel bug. tomorrow
This commit is contained in:
parent
30a8daf1a3
commit
9d69b7a82a
5 changed files with 145 additions and 13 deletions
|
|
@ -4,16 +4,30 @@ lazy_static! {
|
||||||
static ref IDT: Idt = {
|
static ref IDT: Idt = {
|
||||||
let mut idt = Idt::new();
|
let mut idt = Idt::new();
|
||||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||||
|
idt.double_fault.set_handler_fn(double_fault_handler);
|
||||||
|
idt[0x21].set_handler_fn(::keyboard::kbd_callback);
|
||||||
idt
|
idt
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init(memory_controller: &mut ::memory::MemoryController) {
|
||||||
|
let double_fault_stack = memory_controller.alloc_stack(1)
|
||||||
|
.expect("could not allocate double fault stack");
|
||||||
|
// println!("DF stack: {:#?}", double_fault_stack);
|
||||||
|
// flush!();
|
||||||
IDT.load();
|
IDT.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "x86-interrupt" fn double_fault_handler(
|
||||||
|
stack_frame: &mut ExceptionStackFrame, _error_code: u32)
|
||||||
|
{
|
||||||
|
println!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
||||||
|
flush!();
|
||||||
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn breakpoint_handler(
|
extern "x86-interrupt" fn breakpoint_handler(
|
||||||
stack_frame: &mut ExceptionStackFrame)
|
stack_frame: &mut ExceptionStackFrame)
|
||||||
{
|
{
|
||||||
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
||||||
|
flush!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
use x86::structures::idt::*;
|
||||||
|
|
||||||
use cpuio;
|
use cpuio;
|
||||||
use vga;
|
use vga;
|
||||||
|
|
@ -76,7 +77,10 @@ fn check_key_state(key: u8) -> (bool, usize) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kbd_callback() {
|
pub extern "x86-interrupt" fn kbd_callback(
|
||||||
|
stack_frame: &mut ExceptionStackFrame) {
|
||||||
|
println!("kbd callback called");
|
||||||
|
flush!();
|
||||||
static mut SHIFT: bool = false;
|
static mut SHIFT: bool = false;
|
||||||
static mut CTRL: bool = false;
|
static mut CTRL: bool = false;
|
||||||
static mut ALT: bool = false;
|
static mut ALT: bool = false;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ fn init_kernel(multiboot_info_addr: usize) -> Result <(), &'static str> {
|
||||||
|
|
||||||
let boot_info = unsafe { multiboot2::load(multiboot_info_addr)};
|
let boot_info = unsafe { multiboot2::load(multiboot_info_addr)};
|
||||||
|
|
||||||
|
// ACPI must be intialized BEFORE paging (memory::init()) is active
|
||||||
if let Some(rsdp) = boot_info.rsdp_v2_tag() {
|
if let Some(rsdp) = boot_info.rsdp_v2_tag() {
|
||||||
acpi::load(rsdp)?;
|
acpi::load(rsdp)?;
|
||||||
} else if let Some(rsdp) = boot_info.rsdp_tag() {
|
} else if let Some(rsdp) = boot_info.rsdp_tag() {
|
||||||
|
|
@ -45,11 +46,8 @@ fn init_kernel(multiboot_info_addr: usize) -> Result <(), &'static str> {
|
||||||
acpi::init()?;
|
acpi::init()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_paging();
|
let mut memory_controller = memory::init(&boot_info);
|
||||||
enable_write_protect_bit();
|
interrupts::init(&mut memory_controller);
|
||||||
|
|
||||||
memory::init(&boot_info);
|
|
||||||
interrupts::init();
|
|
||||||
vga::init();
|
vga::init();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -62,11 +60,16 @@ pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
||||||
cpuio::halt();
|
cpuio::halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
x86::instructions::interrupts::int3();
|
// x86::instructions::interrupts::int3();
|
||||||
|
|
||||||
flush!();
|
// fn stack_overflow() { stack_overflow(); }
|
||||||
|
// stack_overflow();
|
||||||
|
|
||||||
loop { keyboard::kbd_callback(); }
|
// unsafe {
|
||||||
|
// *(0xdead as *mut u32) = 42;
|
||||||
|
// };
|
||||||
|
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality"] #[no_mangle]
|
#[lang = "eh_personality"] #[no_mangle]
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
pub const PAGE_SIZE: usize = 4096;
|
|
||||||
|
|
||||||
mod area_allocator;
|
mod area_allocator;
|
||||||
mod heap_allocator;
|
mod heap_allocator;
|
||||||
|
mod stack_allocator;
|
||||||
mod paging;
|
mod paging;
|
||||||
|
|
||||||
pub use self::area_allocator::*;
|
pub use self::area_allocator::*;
|
||||||
pub use self::heap_allocator::*;
|
pub use self::heap_allocator::*;
|
||||||
|
pub use self::stack_allocator::*;
|
||||||
pub use self::paging::remap_the_kernel;
|
pub use self::paging::remap_the_kernel;
|
||||||
use multiboot2;
|
use multiboot2;
|
||||||
use x86::*;
|
use x86::*;
|
||||||
|
|
@ -16,8 +16,25 @@ pub trait FrameAllocator {
|
||||||
fn deallocate_frame(&mut self, frame: PhysFrame);
|
fn deallocate_frame(&mut self, frame: PhysFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct MemoryController {
|
||||||
|
active_table: paging::ActivePageTable,
|
||||||
|
frame_allocator: AreaFrameAllocator,
|
||||||
|
stack_allocator: StackAllocator,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryController {
|
||||||
|
pub fn alloc_stack(&mut self, size_in_pages: usize) -> Option<Stack> {
|
||||||
|
let &mut MemoryController { ref mut active_table,
|
||||||
|
ref mut frame_allocator,
|
||||||
|
ref mut stack_allocator } = self;
|
||||||
|
|
||||||
|
stack_allocator.alloc_stack(active_table, frame_allocator,
|
||||||
|
size_in_pages)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// memory initialisation should only be called once
|
/// memory initialisation should only be called once
|
||||||
pub fn init(boot_info: &multiboot2::BootInformation) {
|
pub fn init(boot_info: &multiboot2::BootInformation) -> MemoryController {
|
||||||
use x86::registers::control::{Cr0, Cr4, Cr0Flags, Cr4Flags};
|
use x86::registers::control::{Cr0, Cr4, Cr0Flags, Cr4Flags};
|
||||||
Cr4::add(Cr4Flags::PSE);
|
Cr4::add(Cr4Flags::PSE);
|
||||||
Cr0::add(Cr0Flags::PAGING | Cr0Flags::WRITE_PROTECT);
|
Cr0::add(Cr0Flags::PAGING | Cr0Flags::WRITE_PROTECT);
|
||||||
|
|
@ -52,4 +69,17 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
for page in heap_start_page..heap_end_page {
|
for page in heap_start_page..heap_end_page {
|
||||||
active_table.map(page, PageTableFlags::WRITABLE, &mut frame_allocator);
|
active_table.map(page, PageTableFlags::WRITABLE, &mut frame_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let stack_allocator = {
|
||||||
|
let stack_alloc_start = heap_end_page + 1;
|
||||||
|
let stack_alloc_end = stack_alloc_start + 100;
|
||||||
|
let stack_alloc_range = stack_alloc_start..stack_alloc_end + 1;
|
||||||
|
StackAllocator::new(stack_alloc_range)
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryController {
|
||||||
|
active_table,
|
||||||
|
frame_allocator,
|
||||||
|
stack_allocator,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
81
kernel-rs/src/memory/stack_allocator.rs
Normal file
81
kernel-rs/src/memory/stack_allocator.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
use x86::*;
|
||||||
|
use x86::structures::paging::*;
|
||||||
|
use memory::paging::{self, ActivePageTable};
|
||||||
|
use memory::*;
|
||||||
|
use core::ops::Range;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Stack {
|
||||||
|
top: usize,
|
||||||
|
bottom: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stack {
|
||||||
|
fn new (top: usize, bottom: usize) -> Stack {
|
||||||
|
assert!(top > bottom);
|
||||||
|
Stack {
|
||||||
|
top,
|
||||||
|
bottom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn top(&self) -> usize {
|
||||||
|
self.top
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bottom(&self) -> usize {
|
||||||
|
self.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StackAllocator {
|
||||||
|
range: Range<Page>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StackAllocator {
|
||||||
|
pub fn new(range: Range<Page>) -> StackAllocator {
|
||||||
|
StackAllocator { range }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc_stack<FA: FrameAllocator>(&mut self,
|
||||||
|
active_table: &mut ActivePageTable,
|
||||||
|
frame_allocator: &mut FA,
|
||||||
|
size_in_pages: usize) -> Option<Stack> {
|
||||||
|
if size_in_pages == 0 {
|
||||||
|
return None; /* a zero sized stack makes no sense */
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone the range, since we only want to change it on success
|
||||||
|
let mut range = self.range.clone();
|
||||||
|
|
||||||
|
// try to allocate the stack pages and a guard page
|
||||||
|
let guard_page = range.next();
|
||||||
|
let stack_start = range.next();
|
||||||
|
let stack_end = if size_in_pages == 1 {
|
||||||
|
stack_start
|
||||||
|
} else {
|
||||||
|
// choose the (size_in_pages-2)th element, since index
|
||||||
|
// starts at 0 and we already allocated the start page
|
||||||
|
range.nth(size_in_pages - 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
match (guard_page, stack_start, stack_end) {
|
||||||
|
(Some(_), Some(start), Some(end)) => {
|
||||||
|
// success! write back updated range
|
||||||
|
self.range = range.clone();
|
||||||
|
|
||||||
|
// map stack pages to physical frames
|
||||||
|
for page in range {
|
||||||
|
active_table.map(page, PageTableFlags::WRITABLE, frame_allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new stack
|
||||||
|
let top_of_stack = end.start_address().as_u32() + PAGE_SIZE as u32;
|
||||||
|
Some(Stack::new(top_of_stack as usize,
|
||||||
|
start.start_address().as_u32() as usize))
|
||||||
|
}
|
||||||
|
_ => None, /* not enough pages */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue