Can run into another kernel thread

master
WangRunji 7 years ago
parent 5d857c38eb
commit 7d28231f1b

@ -2,6 +2,7 @@
#[path = "./template.rs"] #[path = "./template.rs"]
mod template; mod template;
use self::template::*; use self::template::*;
pub type TrapFrame = InterruptStackP;
interrupt_stack!(breakpoint, stack, { interrupt_stack!(breakpoint, stack, {
println!("\nEXCEPTION: Breakpoint"); println!("\nEXCEPTION: Breakpoint");
@ -60,12 +61,14 @@ interrupt!(com2, {
use spin::Mutex; use spin::Mutex;
static TICK: Mutex<usize> = Mutex::new(0); static TICK: Mutex<usize> = Mutex::new(0);
interrupt!(timer, { interrupt_stack_p!(timer, stack, {
let mut tick = TICK.lock(); let mut tick = TICK.lock();
*tick += 1; *tick += 1;
let tick = *tick; let tick = *tick;
if tick % 100 == 0 { if tick % 100 == 0 {
println!("\nInterupt: Timer\ntick = {}", tick); println!("\nInterupt: Timer\ntick = {}", tick);
use process;
process::schedule(stack);
} }
ack(IRQ_TIMER); ack(IRQ_TIMER);
}); });

@ -4,6 +4,8 @@ use arch::driver::{apic::IOAPIC, pic};
pub mod handler; pub mod handler;
pub mod consts; pub mod consts;
pub use self::handler::TrapFrame;
#[inline(always)] #[inline(always)]
pub unsafe fn enable() { pub unsafe fn enable() {
x86_64::instructions::interrupts::enable(); x86_64::instructions::interrupts::enable();

@ -2,6 +2,7 @@
#[allow(dead_code)] #[allow(dead_code)]
#[repr(packed)] #[repr(packed)]
#[derive(Clone, Default)]
pub struct ScratchRegisters { pub struct ScratchRegisters {
pub r11: usize, pub r11: usize,
pub r10: usize, pub r10: usize,
@ -60,6 +61,7 @@ macro_rules! scratch_pop {
#[allow(dead_code)] #[allow(dead_code)]
#[repr(packed)] #[repr(packed)]
#[derive(Clone, Default)]
pub struct PreservedRegisters { pub struct PreservedRegisters {
pub r15: usize, pub r15: usize,
pub r14: usize, pub r14: usize,
@ -122,6 +124,7 @@ macro_rules! fs_pop {
#[allow(dead_code)] #[allow(dead_code)]
#[repr(packed)] #[repr(packed)]
#[derive(Clone, Default)]
pub struct IretRegisters { pub struct IretRegisters {
pub rip: usize, pub rip: usize,
pub cs: usize, pub cs: usize,
@ -282,6 +285,7 @@ macro_rules! interrupt_error {
#[allow(dead_code)] #[allow(dead_code)]
#[repr(packed)] #[repr(packed)]
#[derive(Clone, Default)]
pub struct InterruptStackP { pub struct InterruptStackP {
pub fs: usize, pub fs: usize,
pub preserved: PreservedRegisters, pub preserved: PreservedRegisters,
@ -298,6 +302,17 @@ impl InterruptStackP {
} }
} }
use core::fmt::Debug;
use core::fmt::Formatter;
use core::fmt::Error;
impl Debug for InterruptStackP {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
self.dump();
Ok(())
}
}
#[macro_export] #[macro_export]
macro_rules! interrupt_stack_p { macro_rules! interrupt_stack_p {
($name:ident, $stack: ident, $func:block) => { ($name:ident, $stack: ident, $func:block) => {

@ -38,8 +38,8 @@ mod io;
mod memory; mod memory;
mod lang; mod lang;
mod util; mod util;
#[macro_use] // test! #[macro_use]
mod test_util; mod macros;
mod consts; mod consts;
mod process; mod process;
@ -77,7 +77,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! {
// memory_controller.print_page_table(); // memory_controller.print_page_table();
arch::smp::start_other_cores(&acpi, &mut memory_controller); arch::smp::start_other_cores(&acpi, &mut memory_controller);
process::init(memory_controller.kernel_stack.take().unwrap()); process::init(&mut memory_controller);
unsafe{ arch::interrupt::enable(); } unsafe{ arch::interrupt::enable(); }

@ -22,4 +22,13 @@ macro_rules! test {
println!("Success: {}", stringify!($func)); println!("Success: {}", stringify!($func));
} }
) )
}
macro_rules! no_interrupt {
{$func:block} => {
use arch::interrupt;
unsafe{ interrupt::disable(); }
$func;
unsafe{ interrupt::enable(); }
};
} }

@ -1,9 +1,17 @@
use alloc::{boxed::Box, string::String, btree_map::BTreeMap}; use alloc::{boxed::Box, string::String, btree_map::BTreeMap};
use memory::Stack; use memory::{MemoryController, Stack};
use arch::interrupt::TrapFrame;
use spin::{Once, Mutex};
pub fn init(kstack: Stack) { pub fn init(mc: &mut MemoryController) {
let processor = Box::new(Processor::new(kstack)); PROCESSOR.call_once(|| {Mutex::new(Processor::new(mc))});
Box::into_raw(processor); }
static PROCESSOR: Once<Mutex<Processor>> = Once::new();
/// Called by timer handler in arch
pub fn schedule(trap_frame: &mut TrapFrame) {
PROCESSOR.try().unwrap().lock().schedule(trap_frame);
} }
#[derive(Debug)] #[derive(Debug)]
@ -13,12 +21,7 @@ pub struct Process {
kstack: Stack, kstack: Stack,
// page_table: Box<PageTable>, // page_table: Box<PageTable>,
status: Status, status: Status,
context: Context, trap_frame: TrapFrame,
}
#[derive(Debug)]
struct Context {
} }
#[derive(Debug)] #[derive(Debug)]
@ -28,23 +31,39 @@ enum Status {
struct Processor { struct Processor {
procs: BTreeMap<Pid, Box<Process>>, procs: BTreeMap<Pid, Box<Process>>,
current_pid: Pid,
} }
type Pid = usize; type Pid = usize;
impl Processor { impl Processor {
fn new(kernel_stack: Stack) -> Self { fn new(mc: &mut MemoryController) -> Self {
let mut processor = Processor { let mut processor = Processor {
procs: BTreeMap::<Pid, Box<Process>>::new(), procs: BTreeMap::<Pid, Box<Process>>::new(),
current_pid: 0,
}; };
let initproc = Box::new(Process{ let initproc = Box::new(Process{
pid: 0, pid: 0,
name: String::from("initproc"), name: String::from("initproc"),
kstack: kernel_stack, kstack: mc.kernel_stack.take().unwrap(),
status: Status::Running, status: Status::Running,
context: Context{}, trap_frame: TrapFrame::default(),
});
let idleproc = Box::new(Process{
pid: 1,
name: String::from("idleproc"),
kstack: mc.alloc_stack(7).unwrap(),
status: Status::Ready,
trap_frame: {
let mut tf = TrapFrame::default();
tf.iret.cs = 8;
tf.iret.rip = idle_thread as usize;
tf.iret.rflags = 0x282;
tf
},
}); });
processor.procs.insert(0, initproc); processor.procs.insert(0, initproc);
processor.procs.insert(1, idleproc);
processor processor
} }
fn alloc_pid(&self) -> Pid { fn alloc_pid(&self) -> Pid {
@ -58,7 +77,21 @@ impl Processor {
} }
return next; return next;
} }
fn schedule(&self) { fn schedule(&mut self, trap_frame: &mut TrapFrame) {
self.run(1, trap_frame);
}
fn run(&mut self, pid: Pid, trap_frame: &mut TrapFrame) {
if pid == self.current_pid {
return;
}
let process = self.procs.get_mut(&pid).unwrap();
self.current_pid = pid;
*trap_frame = process.trap_frame.clone();
// TODO switch page table
} }
}
extern fn idle_thread() {
println!("idle ...");
loop {}
} }
Loading…
Cancel
Save