Fix kernel thread

master
WangRunji 7 years ago
parent e3a80a1223
commit 89bcd5f660

@ -1 +1 @@
Subproject commit b979c91db3bcfd9c9e9edabf45ef04e41dc4f659 Subproject commit a8bbb3eb031fc377098e1493b14f22ba8448b2ad

@ -12,11 +12,16 @@ pub struct TrapFrame {
/// 用于在内核栈中构造新线程的中断帧 /// 用于在内核栈中构造新线程的中断帧
impl TrapFrame { impl TrapFrame {
fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, rsp: usize) -> Self { fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self {
use core::mem::zeroed; use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() }; let mut tf: Self = unsafe { zeroed() };
tf.x[10] = arg; // a0 tf.x[10] = arg; // a0
tf.x[2] = sp;
tf.sepc = entry as usize; tf.sepc = entry as usize;
tf.sstatus = sstatus::read();
tf.sstatus.set_spie(true);
tf.sstatus.set_sie(false);
tf.sstatus.set_spp(sstatus::SPP::Supervisor);
tf tf
} }
fn new_user_thread(entry_addr: usize, rsp: usize) -> Self { fn new_user_thread(entry_addr: usize, rsp: usize) -> Self {

@ -19,7 +19,9 @@ pub unsafe fn enable() {
#[inline(always)] #[inline(always)]
pub unsafe fn disable_and_store() -> usize { pub unsafe fn disable_and_store() -> usize {
sstatus::read().sie() as usize let e = sstatus::read().sie() as usize;
sstatus::clear_sie();
e
} }
#[inline(always)] #[inline(always)]
@ -35,9 +37,10 @@ pub extern fn rust_trap(tf: &mut TrapFrame) {
trace!("Interrupt: {:?}", tf.scause.cause()); trace!("Interrupt: {:?}", tf.scause.cause());
match tf.scause.cause() { match tf.scause.cause() {
Trap::Interrupt(SupervisorTimer) => timer(), Trap::Interrupt(SupervisorTimer) => timer(),
_ => panic!("Unhandled interrupt: {:?}\n{:#x?}", tf.scause.cause(), tf), _ => panic!("Unhandled interrupt: {:?}\n{:#010x?}", tf.scause.cause(), tf),
} }
::trap::before_return(); ::trap::before_return();
trace!("Interrupt end");
} }
fn timer() { fn timer() {

@ -11,10 +11,8 @@ pub fn init() {
let frame = Frame::of_addr(PhysAddr::new(&PAGE_TABLE_ROOT as *const _ as u32)); let frame = Frame::of_addr(PhysAddr::new(&PAGE_TABLE_ROOT as *const _ as u32));
super::paging::setup_page_table(frame); super::paging::setup_page_table(frame);
init_frame_allocator(); init_frame_allocator();
let ms = remap_the_kernel(); remap_the_kernel();
init_heap(); init_heap();
use core::mem::forget;
forget(ms);
} }
fn init_frame_allocator() { fn init_frame_allocator() {
@ -34,7 +32,7 @@ fn init_frame_allocator() {
} }
} }
fn remap_the_kernel() -> MemorySet { fn remap_the_kernel() {
use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE};
let kstack = Stack { let kstack = Stack {
top: bootstacktop as usize, top: bootstacktop as usize,
@ -48,8 +46,9 @@ fn remap_the_kernel() -> MemorySet {
ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss")); ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss"));
ms.push(MemoryArea::new(KERNEL_HEAP_OFFSET, KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, MemoryAttr::default(), "kernel_heap")); ms.push(MemoryArea::new(KERNEL_HEAP_OFFSET, KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, MemoryAttr::default(), "kernel_heap"));
unsafe { ms.activate(); } unsafe { ms.activate(); }
use core::mem::forget;
forget(ms);
info!("kernel remap end"); info!("kernel remap end");
ms
} }
// Symbols provided by linker script // Symbols provided by linker script

@ -218,11 +218,11 @@ impl InactivePageTable for InactivePageTable0 {
impl InactivePageTable0 { impl InactivePageTable0 {
fn map_kernel(&mut self) { fn map_kernel(&mut self) {
let table = unsafe { &mut *ROOT_PAGE_TABLE }; let table = unsafe { &mut *ROOT_PAGE_TABLE };
let e1 = table[KERNEL_PML4].clone(); let e1 = table[KERNEL_PML4];
let e2 = table[KERNEL_PML4 + 1].clone(); assert!(!e1.is_unused());
self.edit(|_| { self.edit(|_| {
table[KERNEL_PML4] = e1; table[KERNEL_PML4].set(e1.frame(), EF::VALID | EF::GLOBAL);
table[KERNEL_PML4 + 1] = e2;
}); });
} }
} }

Loading…
Cancel
Save