diff --git a/src/arch/x86_64/driver/mod.rs b/src/arch/x86_64/driver/mod.rs index c1f66d3..1531952 100644 --- a/src/arch/x86_64/driver/mod.rs +++ b/src/arch/x86_64/driver/mod.rs @@ -18,12 +18,13 @@ pub fn init(mut page_map: impl FnMut(usize)) -> acpi::AcpiResult { page_map(0x7fe1000); // RSDT let acpi = acpi::init().expect("Failed to init ACPI"); + assert_eq!(acpi.lapic_addr as usize, 0xfee00000); debug!("{:?}", acpi); if cfg!(feature = "use_apic") { pic::disable(); - page_map(acpi.lapic_addr as usize); // LAPIC + page_map(0xfee00000); // LAPIC page_map(0xFEC00000); // IOAPIC apic::init(acpi.lapic_addr, acpi.ioapic_id); diff --git a/src/arch/x86_64/paging/entry.rs b/src/arch/x86_64/paging/entry.rs index 3a4645f..afa86eb 100644 --- a/src/arch/x86_64/paging/entry.rs +++ b/src/arch/x86_64/paging/entry.rs @@ -1,5 +1,6 @@ use memory::Frame; +#[derive(Copy, Clone)] pub struct Entry(u64); impl Entry { diff --git a/src/arch/x86_64/paging/mapper.rs b/src/arch/x86_64/paging/mapper.rs index a176184..69bdae4 100644 --- a/src/arch/x86_64/paging/mapper.rs +++ b/src/arch/x86_64/paging/mapper.rs @@ -76,8 +76,7 @@ impl Mapper { let mut p1 = p2.next_table_create(page.p2_index()); assert!(p1[page.p1_index()].is_unused()); - // TODO: Remove USER_ACCESSIBLE - p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT | EntryFlags::USER_ACCESSIBLE); + p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT); } pub fn map(&mut self, page: Page, flags: EntryFlags) diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs index 4c7b395..8dfe2d7 100644 --- a/src/arch/x86_64/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -155,6 +155,7 @@ impl ActivePageTable { } } +#[derive(Debug)] pub struct InactivePageTable { p4_frame: Frame, } diff --git a/src/lib.rs b/src/lib.rs index d7a881a..a96ae77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,17 +83,18 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { unsafe{ arch::interrupt::enable(); } - unsafe{ - use arch::syscall; - // 在用户模式下触发时钟中断,会导致GPF - // (可能是由于没有合理分离栈) - no_interrupt!({ - syscall::switch_to_user(); - println!("Now in user mode"); - syscall::switch_to_kernel(); - println!("Now in kernel mode"); - }); - } + // 直接进入用户态暂不可用:内核代码用户不可访问 +// unsafe{ +// use arch::syscall; +// // 在用户模式下触发时钟中断,会导致GPF +// // (可能是由于没有合理分离栈) +// no_interrupt!({ +// syscall::switch_to_user(); +// println!("Now in user mode"); +// syscall::switch_to_kernel(); +// println!("Now in kernel mode"); +// }); +// } loop{ println!("init ..."); diff --git a/src/memory/mod.rs b/src/memory/mod.rs index edff14b..ee58b8c 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -211,7 +211,18 @@ impl MemoryController { } pub fn make_page_table(&mut self, set: &mut MemorySet) -> InactivePageTable { let mut page_table = InactivePageTable::new(alloc_frame(), &mut self.active_table); - self.active_table.with(&mut page_table, |pt| set.map(pt)); + + use consts::{KERNEL_HEAP_PML4, KERNEL_PML4}; + let e510 = self.active_table.p4()[KERNEL_PML4].clone(); + let e509 = self.active_table.p4()[KERNEL_HEAP_PML4].clone(); + + self.active_table.with(&mut page_table, |pt: &mut Mapper| { + set.map(pt); + + pt.p4_mut()[KERNEL_PML4] = e510; + pt.p4_mut()[KERNEL_HEAP_PML4] = e509; + pt.identity_map(Frame::of_addr(0xfee00000), EntryFlags::WRITABLE); // LAPIC + }); page_table } } diff --git a/src/process/process.rs b/src/process/process.rs index b074b8a..12e1dea 100644 --- a/src/process/process.rs +++ b/src/process/process.rs @@ -1,5 +1,5 @@ use super::*; -use memory::Stack; +use memory::{Stack, InactivePageTable}; use xmas_elf::{ElfFile, program::{Flags, ProgramHeader}}; use core::slice; use alloc::rc::Rc; @@ -9,7 +9,8 @@ pub struct Process { pub(in process) pid: Pid, name: &'static str, kstack: Stack, - // memory_set: Rc, + pub(in process) memory_set: Option, + pub(in process) page_table: Option, pub(in process) status: Status, pub(in process) rsp: usize, pub(in process) is_user: bool, @@ -33,6 +34,8 @@ impl Process { pid: 0, name, kstack, + memory_set: None, + page_table: None, status: Status::Ready, rsp, is_user: false, @@ -46,6 +49,8 @@ impl Process { pid: 0, name: "init", kstack: mc.kernel_stack.take().unwrap(), + memory_set: None, + page_table: None, status: Status::Running, rsp: 0, // will be set at first schedule is_user: false, @@ -56,9 +61,9 @@ impl Process { let slice = unsafe{ slice::from_raw_parts(begin as *const u8, end - begin) }; let elf = ElfFile::new(slice).expect("failed to read elf"); let phys_start = PhysAddr::from_kernel_virtual(begin); - let mut set = MemorySet::from((&elf, phys_start)); - let page_table = mc.make_page_table(&mut set); - debug!("{:#x?}", set); + let mut memory_set = MemorySet::from((&elf, phys_start)); + let page_table = mc.make_page_table(&mut memory_set); + debug!("{:#x?}", memory_set); use xmas_elf::header::HeaderPt2; let entry_addr = match elf.header.pt2 { @@ -74,6 +79,8 @@ impl Process { pid: 0, name: "user", kstack, + memory_set: Some(memory_set), + page_table: Some(page_table), status: Status::Ready, rsp, is_user: true, @@ -107,7 +114,7 @@ impl<'a> From<(&'a ElfFile<'a>, PhysAddr)> for MemorySet { impl From for EntryFlags { fn from(elf_flags: Flags) -> Self { - let mut flags = EntryFlags::PRESENT; + let mut flags = EntryFlags::PRESENT | EntryFlags::USER_ACCESSIBLE; if elf_flags.is_write() { flags = flags | EntryFlags::WRITABLE; } diff --git a/src/process/processor.rs b/src/process/processor.rs index b09e067..df300dc 100644 --- a/src/process/processor.rs +++ b/src/process/processor.rs @@ -1,4 +1,5 @@ use alloc::BTreeMap; +use memory::{ActivePageTable, InactivePageTable}; use super::*; #[derive(Debug)] @@ -61,7 +62,13 @@ impl Processor { let process = self.procs.get_mut(&pid).unwrap(); process.status = Status::Running; *rsp = process.rsp; - // TODO switch page table + + // switch page table + if let Some(page_table) = process.page_table.take() { + let mut active_table = unsafe { ActivePageTable::new() }; + let old_table = active_table.switch(page_table); + process.page_table = Some(old_table); + } } self.current_pid = pid; debug!("Processor: switch from {} to {}\n rsp: {:#x} -> {:#x}", pid0, pid, rsp0, rsp);