diff --git a/src/arch/x86_64/interrupt/template.rs b/src/arch/x86_64/interrupt/template.rs index 80675273..fcafe6ea 100644 --- a/src/arch/x86_64/interrupt/template.rs +++ b/src/arch/x86_64/interrupt/template.rs @@ -151,7 +151,6 @@ macro_rules! iret { } /// Create an interrupt function that can safely run rust code -#[macro_export] macro_rules! interrupt { ($name:ident, $func:block) => { #[naked] @@ -198,7 +197,6 @@ impl InterruptStack { } } -#[macro_export] macro_rules! interrupt_stack { ($name:ident, $stack: ident, $func:block) => { #[naked] @@ -251,7 +249,6 @@ impl InterruptErrorStack { } } -#[macro_export] macro_rules! interrupt_error { ($name:ident, $stack:ident, $func:block) => { #[naked] @@ -317,7 +314,6 @@ impl Debug for InterruptStackP { } } -#[macro_export] macro_rules! interrupt_switch { ($name:ident, $rsp: ident, $func:block) => { #[naked] @@ -358,7 +354,6 @@ macro_rules! interrupt_switch { }; } -#[macro_export] macro_rules! interrupt_stack_p { ($name:ident, $stack: ident, $func:block) => { #[naked] @@ -415,7 +410,6 @@ impl InterruptErrorStackP { } } -#[macro_export] macro_rules! interrupt_error_p { ($name:ident, $stack:ident, $func:block) => { #[naked] diff --git a/src/arch/x86_64/paging/mapper.rs b/src/arch/x86_64/paging/mapper.rs index 69bdae4b..a8a9cf53 100644 --- a/src/arch/x86_64/paging/mapper.rs +++ b/src/arch/x86_64/paging/mapper.rs @@ -8,7 +8,7 @@ pub struct Mapper { } impl Mapper { - pub unsafe fn new() -> Mapper { + pub const unsafe fn new() -> Mapper { Mapper { p4: Unique::new_unchecked(table::P4), } diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs index 8dfe2d7e..841ad7d3 100644 --- a/src/arch/x86_64/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -105,7 +105,7 @@ impl DerefMut for ActivePageTable { } impl ActivePageTable { - pub unsafe fn new() -> ActivePageTable { + pub const unsafe fn new() -> ActivePageTable { ActivePageTable { mapper: Mapper::new(), } diff --git a/src/lib.rs b/src/lib.rs index 85c60cab..0a40bb74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,7 @@ mod syscall; #[path = "arch/x86_64/mod.rs"] mod arch; -// The entry point of Rust kernel +/// The entry point of Rust kernel #[no_mangle] pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { arch::cpu::init(); @@ -61,11 +61,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { let boot_info = unsafe { multiboot2::load(multiboot_information_address) }; // set up guard page and map the heap pages - let mut memory_controller = memory::init(boot_info); - unsafe { - use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; - HEAP_ALLOCATOR.lock().init(KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE); - } + let mut memory_controller = memory::init(boot_info); arch::gdt::init(); arch::idt::init(); @@ -109,6 +105,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { unreachable!(); } +/// The entry point for another processors #[no_mangle] pub extern "C" fn other_main() -> ! { arch::cpu::init(); @@ -124,6 +121,11 @@ pub extern "C" fn other_main() -> ! { use linked_list_allocator::LockedHeap; +/// Global heap allocator +/// +/// Available after `memory::init()`. +/// +/// It should be defined in memory mod, but in Rust `global_allocator` must be in root mod. #[global_allocator] static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); diff --git a/src/memory/memory_set.rs b/src/memory/memory_set.rs index a6e510b4..65ef6fed 100644 --- a/src/memory/memory_set.rs +++ b/src/memory/memory_set.rs @@ -4,14 +4,13 @@ use core::fmt::{Debug, Formatter, Error}; /// 一片连续内存空间,有相同的访问权限 /// 对应ucore中 `vma_struct` -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Eq, PartialEq, Copy, Clone)] pub struct MemoryArea { start_addr: VirtAddr, end_addr: VirtAddr, phys_start_addr: Option, flags: u64, name: &'static str, - mapped: bool, } impl MemoryArea { @@ -23,7 +22,6 @@ impl MemoryArea { phys_start_addr: None, flags: flags.bits(), name, - mapped: false, } } pub fn new_identity(start_addr: VirtAddr, end_addr: VirtAddr, flags: EntryFlags, name: &'static str) -> Self { @@ -34,7 +32,6 @@ impl MemoryArea { phys_start_addr: Some(PhysAddr(start_addr as u64)), flags: flags.bits(), name, - mapped: false, } } pub fn new_kernel(start_addr: VirtAddr, end_addr: VirtAddr, flags: EntryFlags, name: &'static str) -> Self { @@ -45,7 +42,6 @@ impl MemoryArea { phys_start_addr: Some(PhysAddr::from_kernel_virtual(start_addr)), flags: flags.bits(), name, - mapped: false, } } pub fn contains(&self, addr: VirtAddr) -> bool { @@ -94,9 +90,6 @@ impl MemorySet { } pub fn map(&mut self, pt: &mut Mapper) { for area in self.areas.iter_mut() { - if area.mapped { - continue - } match area.phys_start_addr { Some(phys_start) => { for page in Page::range_of(area.start_addr, area.end_addr) { @@ -110,18 +103,13 @@ impl MemorySet { } }, } - area.mapped = true; } } pub fn unmap(&mut self, pt: &mut Mapper) { for area in self.areas.iter_mut() { - if !area.mapped { - continue - } for page in Page::range_of(area.start_addr, area.end_addr) { pt.unmap(page); } - area.mapped = false; } } } diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 3770e7df..32da9d49 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -9,6 +9,7 @@ use multiboot2::BootInformation; use consts::KERNEL_OFFSET; use arch::paging; use spin::Mutex; +use super::HEAP_ALLOCATOR; mod memory_set; mod area_frame_allocator; @@ -17,6 +18,8 @@ mod stack_allocator; mod address; mod frame; +pub static ACITVE_PAGETABLE: Mutex = Mutex::new(unsafe { ActivePageTable::new() }); + pub static FRAME_ALLOCATOR: Mutex> = Mutex::new(None); pub fn alloc_frame() -> Frame { @@ -47,11 +50,13 @@ pub fn init(boot_info: BootInformation) -> MemoryController { memory_map_tag.memory_areas() )); - let (mut active_table, kernel_stack) = remap_the_kernel(boot_info); + let kernel_stack = remap_the_kernel(boot_info); use self::paging::Page; use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; + unsafe { HEAP_ALLOCATOR.lock().init(KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE); } + let stack_allocator = { let stack_alloc_range = Page::range_of(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE + 0x100000); @@ -60,14 +65,14 @@ pub fn init(boot_info: BootInformation) -> MemoryController { MemoryController { kernel_stack: Some(kernel_stack), - active_table, + active_table: unsafe { ActivePageTable::new() }, stack_allocator, } } -pub fn remap_the_kernel(boot_info: BootInformation) -> (ActivePageTable, Stack) +pub fn remap_the_kernel(boot_info: BootInformation) -> Stack { - let mut active_table = unsafe { ActivePageTable::new() }; + let mut active_table = ACITVE_PAGETABLE.lock(); let mut memory_set = MemorySet::from(boot_info.elf_sections_tag().unwrap()); use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; @@ -90,7 +95,7 @@ pub fn remap_the_kernel(boot_info: BootInformation) -> (ActivePageTable, Stack) let kernel_stack = Stack::new(stack_bottom + 8 * PAGE_SIZE, stack_bottom + 1 * PAGE_SIZE); println!("guard page at {:#x}", stack_bottom_page.start_address()); - (active_table, kernel_stack) + kernel_stack } use multiboot2::{ElfSectionsTag, ElfSection, ElfSectionFlags}; diff --git a/src/process/mod.rs b/src/process/mod.rs index 75e88675..96a2ef0c 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -1,5 +1,6 @@ use memory::MemoryController; use spin::{Once, Mutex}; +use core::slice; use self::process::*; use self::processor::*; @@ -38,7 +39,7 @@ extern { pub fn init(mc: &mut MemoryController) { PROCESSOR.call_once(|| {Mutex::new({ - let mut processor = Processor::new(mc); + let mut processor = Processor::new(); let initproc = Process::new_init(mc); let idleproc = Process::new("idle", idle_thread, mc); #[cfg(feature = "link_user_program")] diff --git a/src/process/process.rs b/src/process/process.rs index 23342c14..e409289c 100644 --- a/src/process/process.rs +++ b/src/process/process.rs @@ -42,6 +42,7 @@ impl Process { is_user: false, } } + /// Make the first kernel thread `initproc` /// Should be called only once pub fn new_init(mc: &mut MemoryController) -> Self { @@ -58,6 +59,8 @@ impl Process { } } + /// Make a new user thread + /// The program elf data is placed at [begin, end) pub fn new_user(begin: usize, end: usize, mc: &mut MemoryController) -> Self { // Parse elf let slice = unsafe{ slice::from_raw_parts(begin as *const u8, end - begin) }; @@ -103,6 +106,12 @@ impl Process { is_user: true, } } + + /// Fork + pub fn fork(&mut self) -> Self { + assert!(self.is_user); + unimplemented!() + } } use memory::{MemorySet, MemoryArea, PhysAddr, FromToVirtualAddress, EntryFlags}; diff --git a/src/process/processor.rs b/src/process/processor.rs index df300dcb..79bed747 100644 --- a/src/process/processor.rs +++ b/src/process/processor.rs @@ -9,7 +9,7 @@ pub struct Processor { } impl Processor { - pub fn new(mc: &mut MemoryController) -> Self { + pub fn new() -> Self { Processor { procs: BTreeMap::::new(), current_pid: 0,