This commit is contained in:
wescande 2018-04-15 21:00:53 +02:00
parent e1f8c3f9ca
commit b3a1c5194a
10 changed files with 80 additions and 42 deletions

View file

@ -15,7 +15,7 @@ build/arch/$(ARCH)/%.o: src/arch/$(ARCH)/%.asm Makefile
## COMPILE RUST (xargo) ## COMPILE RUST (xargo)
rust_os := target/$(TARGET)/debug/lib$(OS).a rust_os := target/$(TARGET)/debug/lib$(OS).a
$(rust_os): $(TARGET).json Makefile $(rust_os): $(TARGET).json Makefile
@RUST_TARGET_PATH="$(shell pwd)" xargo build --target $(TARGET) @TERM=xterm RUST_TARGET_PATH="$(shell pwd)" xargo build --target $(TARGET)
## LINKAGE ## LINKAGE
kernel := build/$(OS) kernel := build/$(OS)

View file

@ -2,14 +2,25 @@ use x86::structures::gdt;
use x86::structures::tss; use x86::structures::tss;
use x86::instructions::segmentation::set_cs; use x86::instructions::segmentation::set_cs;
use x86::instructions::tables::load_tss; use x86::instructions::tables::load_tss;
use arch::x86::paging::ActivePageTable;
use spin::Once; use spin::Once;
// use io;
static GDT: Once<gdt::Gdt> = Once::new(); static GDT: Once<gdt::Gdt> = Once::new();
static TSS: Once<tss::TaskStateSegment> = Once::new(); static TSS: Once<tss::TaskStateSegment> = Once::new();
pub fn init() { pub fn init(mut active_table: &mut ActivePageTable) {
// let tss = tss::TaskStateSegment::new();
let tss = TSS.call_once(|| { let tss = TSS.call_once(|| {
let tss = tss::TaskStateSegment::new(); let mut tss = tss::TaskStateSegment::new();
match ::memory::allocate_stack(&mut active_table) {
Some(stack) => {tss.esp0 = stack.top; tss.ss = 0x18},
// Some(stack) => {tss.esp = stack.top; tss.ebp = stack.bottom },
_ => panic!("There is no stack available for tss"),
};
// tss.esp = tss.esp0;
// tss.ebp = tss.esp;
// println!("tss on {:#x}", tss.esp0);flush!();
tss tss
}); });
@ -33,6 +44,7 @@ pub fn init() {
println!("gdt 3 lower: {:#x}", gdt.table[3] >> 32 as u32); println!("gdt 3 lower: {:#x}", gdt.table[3] >> 32 as u32);
flush!(); flush!();
// io::halt();
gdt.load(); gdt.load();
unsafe { unsafe {
// reload code segment register // reload code segment register

View file

@ -15,10 +15,12 @@ lazy_static! {
idt.invalid_opcode.set_handler_fn(exception::invalid_opcode); idt.invalid_opcode.set_handler_fn(exception::invalid_opcode);
idt.device_not_available.set_handler_fn(exception::device_not_available); idt.device_not_available.set_handler_fn(exception::device_not_available);
idt.double_fault.set_handler_fn(exception::double_fault); idt.double_fault.set_handler_fn(exception::double_fault);
idt.double_fault.set_gate_type(GateType::TaskGate32);
idt.segment_not_present.set_handler_fn(exception::segment_not_present); idt.segment_not_present.set_handler_fn(exception::segment_not_present);
idt.stack_segment_fault.set_handler_fn(exception::stack_segment); idt.stack_segment_fault.set_handler_fn(exception::stack_segment);
idt.general_protection_fault.set_handler_fn(exception::general_protection); idt.general_protection_fault.set_handler_fn(exception::general_protection);
idt.page_fault.set_handler_fn(exception::page_fault); idt.page_fault.set_handler_fn(exception::page_fault);
idt.page_fault.set_gate_type(GateType::TaskGate32);
idt.x87_floating_point.set_handler_fn(exception::x87_fpu); idt.x87_floating_point.set_handler_fn(exception::x87_fpu);
idt.alignment_check.set_handler_fn(exception::alignment_check); idt.alignment_check.set_handler_fn(exception::alignment_check);
idt.machine_check.set_handler_fn(exception::machine_check); idt.machine_check.set_handler_fn(exception::machine_check);

View file

@ -1,6 +1,7 @@
// https://wiki.osdev.org/Exceptions // https://wiki.osdev.org/Exceptions
use arch::x86::pti; use arch::x86::pti;
use io;
macro_rules! exception { macro_rules! exception {
($name:ident, $func:block) => { ($name:ident, $func:block) => {

View file

@ -40,7 +40,7 @@ pub unsafe extern "C" fn x86_rust_start(multiboot_info_addr: usize) {
idt::init(); idt::init();
// fill and load gdt // fill and load gdt
gdt::init(); gdt::init(&mut active_table);
// set up heap // set up heap
::allocator::init(&mut active_table); ::allocator::init(&mut active_table);

View file

@ -29,10 +29,12 @@ pub trait Io {
} }
} }
#[inline(always)]
pub fn cli() { pub fn cli() {
unsafe { asm!("cli" : : : : "volatile") }; unsafe { asm!("cli" : : : : "volatile") };
} }
#[inline(always)]
pub fn halt() -> ! { pub fn halt() -> ! {
cli(); cli();
loop { loop {

View file

@ -44,6 +44,8 @@ pub mod memory;
/// arch specific entry points /// arch specific entry points
pub mod arch; pub mod arch;
// use core::mem;
// use x86::structures::idt::*;
/// kernel entry point. arch module is responsible for /// kernel entry point. arch module is responsible for
/// calling this once the core has loaded /// calling this once the core has loaded
pub fn kmain() -> ! { pub fn kmain() -> ! {
@ -51,15 +53,22 @@ pub fn kmain() -> ! {
memory::init_noncore(); memory::init_noncore();
// x86::instructions::interrupts::int3(); // x86::instructions::interrupts::int3();
// println!("size of idt entry: {}", mem::size_of::<IdtEntry<HandlerFunc>>());
// println!("size of i32 {}", mem::size_of::<i32>());
// flush!();
// unsafe {asm!("hlt");}
// let x = 0;
// let y = 5 /x;
// println!("x {} y {}", x, y);
// fn stack_overflow() { // fn stack_overflow() {
// stack_overflow(); // stack_overflow();
// } // }
// stack_overflow(); // stack_overflow();
// unsafe { unsafe {
// *(0xdead as *mut u32) = 42; *(0xdead as *mut u32) = 42;
// }; };
// vga is *not* cpu specific // vga is *not* cpu specific
vga::init(); vga::init();

View file

@ -4,12 +4,14 @@ mod stack_allocator;
use multiboot2; use multiboot2;
use x86::structures::paging::*; use x86::structures::paging::*;
use arch::x86::paging::ActivePageTable;
use x86::*; use x86::*;
use spin::Mutex; // use spin::Mutex;
use self::bump::BumpFrameAllocator; use self::bump::BumpFrameAllocator;
use self::recycle::RecycleAllocator; use self::recycle::RecycleAllocator;
use self::stack_allocator::StackAllocator; use self::stack_allocator::{Stack,StackAllocator};
pub trait FrameAllocator { pub trait FrameAllocator {
fn allocate_frames(&mut self, size: usize) -> Option<PhysFrame>; fn allocate_frames(&mut self, size: usize) -> Option<PhysFrame>;
@ -21,7 +23,7 @@ pub struct MemoryControler {
stack_allocator: StackAllocator, stack_allocator: StackAllocator,
} }
static MEMORY_CONTROLER: Mutex<Option<MemoryControler>> = Mutex::new(None); static mut MEMORY_CONTROLER: Option<MemoryControler> = None;
pub fn init(boot_info: &multiboot2::BootInformation) { pub fn init(boot_info: &multiboot2::BootInformation) {
let elf_sections_tag = boot_info.elf_sections_tag().unwrap(); let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
@ -61,42 +63,52 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
StackAllocator::new(stack_alloc_range) StackAllocator::new(stack_alloc_range)
}; };
*MEMORY_CONTROLER.lock() = Some(MemoryControler { unsafe {
MEMORY_CONTROLER = Some(MemoryControler {
frame_allocator, frame_allocator,
stack_allocator, stack_allocator,
}); });
}
} }
pub fn allocate_frames(count: usize) -> Option<PhysFrame> { pub fn allocate_frames(count: usize) -> Option<PhysFrame> {
if let Some(ref mut controler) = *MEMORY_CONTROLER.lock() { unsafe {
if let Some(ref mut controler) = MEMORY_CONTROLER {
controler.frame_allocator.allocate_frames(count) controler.frame_allocator.allocate_frames(count)
} else { } else {
panic!("frame allocator not initialized!"); panic!("frame allocator not initialized!");
} }
}
} }
pub fn deallocate_frames(frame: PhysFrame, count: usize) { pub fn deallocate_frames(frame: PhysFrame, count: usize) {
if let Some(ref mut controler) = *MEMORY_CONTROLER.lock() { unsafe {
if let Some(ref mut controler) = MEMORY_CONTROLER {
controler.frame_allocator.deallocate_frames(frame, count) controler.frame_allocator.deallocate_frames(frame, count)
} else { } else {
panic!("frame allocator not initialized!"); panic!("frame allocator not initialized!");
} }
}
} }
pub fn allocate_stack() { pub fn allocate_stack(mut active_table: &mut ActivePageTable) -> Option<Stack> {
if let Some(ref mut controler) = *MEMORY_CONTROLER.lock() { unsafe {
controler.stack_allocator.allocate_stack() if let Some(ref mut controler) = MEMORY_CONTROLER {
controler.stack_allocator.allocate_stack(&mut active_table, &mut controler.frame_allocator, 5)
} else { } else {
panic!("frame allocator not initialized!"); panic!("frame allocator not initialized!");
} }
}
} }
/// Init memory module after core /// Init memory module after core
/// Must be called once, and only once, /// Must be called once, and only once,
pub fn init_noncore() { pub fn init_noncore() {
if let Some(ref mut controler) = *MEMORY_CONTROLER.lock() { unsafe {
if let Some(ref mut controler) = MEMORY_CONTROLER {
controler.frame_allocator.set_core(true); controler.frame_allocator.set_core(true);
} else { } else {
panic!("frame allocator not initialized"); panic!("frame allocator not initialized");
} }
}
} }

View file

@ -1,25 +1,25 @@
use x86::structures::paging::*; use x86::structures::paging::*;
use memory::paging::ActivePageTable; use arch::x86::paging::ActivePageTable;
use memory::*; use memory::*;
use core::ops::Range; use core::ops::Range;
#[derive(Debug)] #[derive(Debug)]
pub struct Stack { pub struct Stack {
top: usize, pub top: u32,
bottom: usize, pub bottom: u32,
} }
impl Stack { impl Stack {
fn new(top: usize, bottom: usize) -> Stack { fn new(top: u32, bottom: u32) -> Stack {
assert!(top > bottom); assert!(top > bottom);
Stack { top, bottom } Stack { top, bottom }
} }
pub fn top(&self) -> usize { pub fn top(&self) -> u32 {
self.top self.top
} }
pub fn bottom(&self) -> usize { pub fn bottom(&self) -> u32 {
self.bottom self.bottom
} }
} }
@ -65,14 +65,14 @@ impl StackAllocator {
// map stack pages to physical frames // map stack pages to physical frames
for page in range { for page in range {
active_table.map(page, PageTableFlags::WRITABLE, frame_allocator); active_table.map(page, PageTableFlags::WRITABLE);
} }
// create a new stack // create a new stack
let top_of_stack = end.start_address().as_u32() + PAGE_SIZE as u32; let top_of_stack = end.start_address().as_u32() + PAGE_SIZE as u32;
Some(Stack::new( Some(Stack::new(
top_of_stack as usize, top_of_stack,
start.start_address().as_u32() as usize, start.start_address().as_u32(),
)) ))
} }
_ => None, /* not enough pages */ _ => None, /* not enough pages */

@ -1 +1 @@
Subproject commit 2a8416d0af403786d082695d13a0f74cd2b7f216 Subproject commit c6636434cb64916c303c17c243c0e93830882248