diff --git a/crate/memory/src/memory_set.rs b/crate/memory/src/memory_set.rs index 5a80f01..49e9896 100644 --- a/crate/memory/src/memory_set.rs +++ b/crate/memory/src/memory_set.rs @@ -15,7 +15,6 @@ pub trait InactivePageTable { fn alloc_frame() -> Option; fn dealloc_frame(target: PhysAddr); - fn alloc_stack() -> Stack; } /// 一片连续内存空间,有相同的访问权限 @@ -132,7 +131,6 @@ impl MemoryAttr { pub struct MemorySet { areas: Vec, page_table: T, - kstack: Stack, } impl MemorySet { @@ -140,17 +138,12 @@ impl MemorySet { MemorySet { areas: Vec::::new(), page_table: T::new(), - kstack: T::alloc_stack(), } } - /// Used for remap_kernel() where heap alloc is unavailable - pub unsafe fn new_from_raw_space(slice: &mut [u8], kstack: Stack) -> Self { - use core::mem::size_of; - let cap = slice.len() / size_of::(); + pub fn new_bare() -> Self { MemorySet { - areas: Vec::::from_raw_parts(slice.as_ptr() as *mut MemoryArea, 0, cap), + areas: Vec::::new(), page_table: T::new_bare(), - kstack, } } pub fn find_area(&self, addr: VirtAddr) -> Option<&MemoryArea> { @@ -175,9 +168,6 @@ impl MemorySet { pub fn token(&self) -> usize { self.page_table.token() } - pub fn kstack_top(&self) -> usize { - self.kstack.top - } pub fn clear(&mut self) { let Self { ref mut page_table, ref mut areas, .. } = self; page_table.edit(|pt| { @@ -200,7 +190,6 @@ impl Clone for MemorySet { MemorySet { areas: self.areas.clone(), page_table, - kstack: T::alloc_stack(), } } } @@ -218,9 +207,3 @@ impl Debug for MemorySet { .finish() } } - -#[derive(Debug)] -pub struct Stack { - pub top: usize, - pub bottom: usize, -} \ No newline at end of file diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index f9b5597..7e0c08c 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -1,10 +1,8 @@ use core::slice; -use memory::{active_table, FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet, Stack}; +use memory::{active_table, FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet}; use super::riscv::{addr::*, register::sstatus}; use ucore_memory::PAGE_SIZE; -// static mut KERNEL_MS: Option = None; - pub fn init() { #[repr(align(4096))] struct PageData([u8; PAGE_SIZE]); @@ -14,8 +12,8 @@ pub fn init() { let frame = Frame::of_addr(PhysAddr::new(&PAGE_TABLE_ROOT as *const _ as u32)); super::paging::setup_page_table(frame); init_frame_allocator(); - remap_the_kernel(); init_heap(); + remap_the_kernel(); } fn init_frame_allocator() { @@ -37,12 +35,7 @@ fn init_frame_allocator() { fn remap_the_kernel() { use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE}; - let kstack = Stack { - top: bootstacktop as usize, - bottom: bootstack as usize + PAGE_SIZE, - }; - static mut SPACE: [u8; 0x1000] = [0; 0x1000]; - let mut ms = unsafe { MemorySet::new_from_raw_space(&mut SPACE, kstack) }; + let mut ms = MemorySet::new_bare(); ms.push(MemoryArea::new_identity(0x10000000, 0x10000008, MemoryAttr::default(), "serial")); ms.push(MemoryArea::new_identity(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), "text")); ms.push(MemoryArea::new_identity(sdata as usize, edata as usize, MemoryAttr::default(), "data")); diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index ec1d03b..68efb45 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -1,6 +1,6 @@ use consts::{KERNEL_P2_INDEX, RECURSIVE_INDEX}; // Depends on kernel -use memory::{active_table, alloc_frame, alloc_stack, dealloc_frame}; +use memory::{active_table, alloc_frame, dealloc_frame}; use super::riscv::addr::*; use super::riscv::asm::{sfence_vma, sfence_vma_all}; use super::riscv::paging::{Mapper, PageTable as RvPageTable, PageTableEntry, PageTableFlags as EF, RecursivePageTable}; @@ -215,10 +215,6 @@ impl InactivePageTable for InactivePageTable0 { fn dealloc_frame(target: usize) { dealloc_frame(target) } - - fn alloc_stack() -> Stack { - alloc_stack() - } } impl InactivePageTable0 { diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index 0a3d812..8838dce 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -1,6 +1,6 @@ use bit_allocator::{BitAlloc, BitAlloc64K}; // Depends on kernel -use memory::{active_table, alloc_frame, alloc_stack, dealloc_frame}; +use memory::{active_table, alloc_frame, dealloc_frame}; use spin::{Mutex, MutexGuard}; use ucore_memory::cow::CowExt; use ucore_memory::memory_set::*; @@ -231,10 +231,6 @@ impl InactivePageTable for InactivePageTable0 { fn dealloc_frame(target: usize) { dealloc_frame(target) } - - fn alloc_stack() -> Stack { - alloc_stack() - } } impl InactivePageTable0 { diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 0f203f3..f69b5ba 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -5,7 +5,7 @@ use spin::{Mutex, MutexGuard}; use super::HEAP_ALLOCATOR; use ucore_memory::{*, paging::PageTable}; use ucore_memory::cow::CowExt; -pub use ucore_memory::memory_set::{MemoryArea, MemoryAttr, MemorySet as MemorySet_, Stack}; +pub use ucore_memory::memory_set::{MemoryArea, MemoryAttr, MemorySet as MemorySet_}; pub type MemorySet = MemorySet_; @@ -32,13 +32,25 @@ pub fn dealloc_frame(target: usize) { FRAME_ALLOCATOR.lock().dealloc((target - MEMORY_OFFSET) / PAGE_SIZE); } -// alloc from heap -pub fn alloc_stack() -> Stack { - use alloc::alloc::{alloc, Layout}; - const STACK_SIZE: usize = 0x8000; - let bottom = unsafe{ alloc(Layout::from_size_align(STACK_SIZE, 0x8000).unwrap()) } as usize; - let top = bottom + STACK_SIZE; - Stack { top, bottom } +pub struct KernelStack(usize); +const STACK_SIZE: usize = 0x8000; + +impl KernelStack { + pub fn new() -> Self { + use alloc::alloc::{alloc, Layout}; + let bottom = unsafe{ alloc(Layout::from_size_align(STACK_SIZE, STACK_SIZE).unwrap()) } as usize; + KernelStack(bottom) + } + pub fn top(&self) -> usize { + self.0 + STACK_SIZE + } +} + +impl Drop for KernelStack { + fn drop(&mut self) { + use alloc::alloc::{dealloc, Layout}; + unsafe{ dealloc(self.0 as _, Layout::from_size_align(STACK_SIZE, STACK_SIZE).unwrap()); } + } } lazy_static! { diff --git a/kernel/src/process/context.rs b/kernel/src/process/context.rs index dcc53f5..95da842 100644 --- a/kernel/src/process/context.rs +++ b/kernel/src/process/context.rs @@ -1,5 +1,5 @@ use arch::interrupt::{TrapFrame, Context as ArchContext}; -use memory::{MemoryArea, MemoryAttr, MemorySet}; +use memory::{MemoryArea, MemoryAttr, MemorySet, KernelStack}; use xmas_elf::{ElfFile, header, program::{Flags, ProgramHeader, Type}}; use core::fmt::{Debug, Error, Formatter}; use ucore_process::Context; @@ -8,6 +8,7 @@ use alloc::boxed::Box; pub struct ContextImpl { arch: ArchContext, memory_set: MemorySet, + kstack: KernelStack, } impl Context for ContextImpl { @@ -23,14 +24,17 @@ impl ContextImpl { Box::new(ContextImpl { arch: ArchContext::null(), memory_set: MemorySet::new(), + kstack: KernelStack::new(), }) } pub fn new_kernel(entry: extern fn(usize) -> !, arg: usize) -> Box { - let ms = MemorySet::new(); + let memory_set = MemorySet::new(); + let kstack = KernelStack::new(); Box::new(ContextImpl { - arch: unsafe { ArchContext::new_kernel_thread(entry, arg, ms.kstack_top(), ms.token()) }, - memory_set: ms, + arch: unsafe { ArchContext::new_kernel_thread(entry, arg, kstack.top(), memory_set.token()) }, + memory_set, + kstack, }) } @@ -82,12 +86,15 @@ impl ContextImpl { }); } + let kstack = KernelStack::new(); + Box::new(ContextImpl { arch: unsafe { ArchContext::new_user_thread( - entry_addr, user_stack_top - 8, memory_set.kstack_top(), is32, memory_set.token()) + entry_addr, user_stack_top - 8, kstack.top(), is32, memory_set.token()) }, memory_set, + kstack, }) } @@ -111,9 +118,12 @@ impl ContextImpl { }); } + let kstack = KernelStack::new(); + Box::new(ContextImpl { - arch: unsafe { ArchContext::new_fork(tf, memory_set.kstack_top(), memory_set.token()) }, + arch: unsafe { ArchContext::new_fork(tf, kstack.top(), memory_set.token()) }, memory_set, + kstack, }) } }