add some
This commit is contained in:
parent
e1f8c3f9ca
commit
b3a1c5194a
10 changed files with 80 additions and 42 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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) => {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
@ -47,7 +49,7 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
boot_info.start_address(),
|
boot_info.start_address(),
|
||||||
boot_info.end_address(),
|
boot_info.end_address(),
|
||||||
memory_map_tag.memory_areas(),
|
memory_map_tag.memory_areas(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let frame_allocator = RecycleAllocator::new(bump_allocator);
|
let frame_allocator = RecycleAllocator::new(bump_allocator);
|
||||||
|
|
||||||
|
|
@ -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 {
|
||||||
frame_allocator,
|
MEMORY_CONTROLER = Some(MemoryControler {
|
||||||
stack_allocator,
|
frame_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 {
|
||||||
controler.frame_allocator.allocate_frames(count)
|
if let Some(ref mut controler) = MEMORY_CONTROLER {
|
||||||
} else {
|
controler.frame_allocator.allocate_frames(count)
|
||||||
panic!("frame allocator not initialized!");
|
} else {
|
||||||
|
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 {
|
||||||
controler.frame_allocator.deallocate_frames(frame, count)
|
if let Some(ref mut controler) = MEMORY_CONTROLER {
|
||||||
} else {
|
controler.frame_allocator.deallocate_frames(frame, count)
|
||||||
panic!("frame allocator not initialized!");
|
} else {
|
||||||
|
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 {
|
||||||
} else {
|
controler.stack_allocator.allocate_stack(&mut active_table, &mut controler.frame_allocator, 5)
|
||||||
panic!("frame allocator not initialized!");
|
} else {
|
||||||
|
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 {
|
||||||
controler.frame_allocator.set_core(true);
|
if let Some(ref mut controler) = MEMORY_CONTROLER {
|
||||||
} else {
|
controler.frame_allocator.set_core(true);
|
||||||
panic!("frame allocator not initialized");
|
} else {
|
||||||
|
panic!("frame allocator not initialized");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in a new issue