Fix user stack. Make MemoryArea fields private.

master
WangRunji 7 years ago
parent b885b7ce6a
commit 09147732bc

@ -6,15 +6,48 @@ use core::fmt::{Debug, Formatter, Error};
/// 对应ucore中 `vma_struct`
#[derive(Debug, Eq, PartialEq)]
pub struct MemoryArea {
pub start_addr: VirtAddr,
pub end_addr: VirtAddr,
pub phys_start_addr: Option<PhysAddr>,
pub flags: u32,
pub name: &'static str,
pub mapped: bool,
start_addr: VirtAddr,
end_addr: VirtAddr,
phys_start_addr: Option<PhysAddr>,
flags: u64,
name: &'static str,
mapped: bool,
}
impl MemoryArea {
pub fn new(start_addr: VirtAddr, end_addr: VirtAddr, flags: EntryFlags, name: &'static str) -> Self {
assert!(start_addr <= end_addr, "invalid memory area");
MemoryArea {
start_addr,
end_addr,
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 {
assert!(start_addr <= end_addr, "invalid memory area");
MemoryArea {
start_addr,
end_addr,
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 {
assert!(start_addr <= end_addr, "invalid memory area");
MemoryArea {
start_addr,
end_addr,
phys_start_addr: Some(PhysAddr::from_kernel_virtual(start_addr)),
flags: flags.bits(),
name,
mapped: false,
}
}
pub fn contains(&self, addr: VirtAddr) -> bool {
addr >= self.start_addr && addr < self.end_addr
}
@ -54,11 +87,6 @@ impl MemorySet {
self.areas.iter().find(|area| area.contains(addr))
}
pub fn push(&mut self, area: MemoryArea) {
assert!(area.start_addr <= area.end_addr, "invalid memory area");
if let Some(phys_addr) = area.phys_start_addr {
assert_eq!(area.start_addr % PAGE_SIZE, phys_addr.get() % PAGE_SIZE,
"virtual & physical start address must have same page offset");
}
assert!(self.areas.iter()
.find(|other| area.is_overlap_with(other))
.is_none(), "memory area overlap");

@ -71,30 +71,9 @@ pub fn remap_the_kernel(boot_info: BootInformation) -> (ActivePageTable, Stack)
let mut memory_set = MemorySet::from(boot_info.elf_sections_tag().unwrap());
use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE};
memory_set.push(MemoryArea {
start_addr: 0xb8000,
end_addr: 0xb9000,
phys_start_addr: Some(PhysAddr(0xb8000)),
flags: EntryFlags::WRITABLE.bits() as u32,
name: "VGA",
mapped: false,
});
memory_set.push(MemoryArea {
start_addr: boot_info.start_address(),
end_addr: boot_info.end_address(),
phys_start_addr: Some(PhysAddr(boot_info.start_address() as u64)),
flags: EntryFlags::PRESENT.bits() as u32,
name: "multiboot",
mapped: false,
});
memory_set.push(MemoryArea {
start_addr: KERNEL_HEAP_OFFSET,
end_addr: KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE,
phys_start_addr: None,
flags: EntryFlags::WRITABLE.bits() as u32,
name: "kernel_heap",
mapped: false,
});
memory_set.push(MemoryArea::new_identity(0xb8000, 0xb9000, EntryFlags::WRITABLE, "VGA"));
memory_set.push(MemoryArea::new_identity(boot_info.start_address(), boot_info.end_address(), EntryFlags::PRESENT, "multiboot"));
memory_set.push(MemoryArea::new(KERNEL_HEAP_OFFSET, KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE, EntryFlags::WRITABLE, "kernel_heap"));
let mut page_table = InactivePageTable::new(alloc_frame(), &mut active_table);
active_table.with(&mut page_table, |pt| memory_set.map(pt));
@ -136,29 +115,15 @@ impl From<ElfSectionsTag> for MemorySet {
impl From<ElfSection> for MemoryArea {
fn from(section: ElfSection) -> Self {
use self::address::FromToVirtualAddress;
let start_addr = section.start_address() as usize;
let end_addr = section.end_address() as usize;
let mut start_addr = section.start_address() as usize;
let mut end_addr = section.end_address() as usize;
assert_eq!(start_addr % PAGE_SIZE, 0, "sections need to be page aligned");
let name = unsafe { &*(section.name() as *const str) };
if start_addr < KERNEL_OFFSET {
MemoryArea {
start_addr: start_addr + KERNEL_OFFSET,
end_addr: end_addr + KERNEL_OFFSET,
phys_start_addr: Some(PhysAddr(section.start_address() as u64)),
flags: EntryFlags::from(section.flags()).bits() as u32,
name,
mapped: false,
}
} else {
MemoryArea {
start_addr,
end_addr,
phys_start_addr: Some(PhysAddr::from_kernel_virtual(start_addr)),
flags: EntryFlags::from(section.flags()).bits() as u32,
name,
mapped: false,
}
start_addr += KERNEL_OFFSET;
end_addr += KERNEL_OFFSET;
}
MemoryArea::new_kernel(start_addr, end_addr, EntryFlags::from(section.flags()), name)
}
}

@ -64,7 +64,10 @@ impl Process {
let elf = ElfFile::new(slice).expect("failed to read elf");
// Make page table
use consts::{USER_STACK_OFFSET, USER_STACK_SIZE};
let mut memory_set = MemorySet::from(&elf);
memory_set.push(MemoryArea::new(USER_STACK_OFFSET, USER_STACK_OFFSET + USER_STACK_SIZE,
EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE, "user_stack"));
let page_table = mc.make_page_table(&mut memory_set);
debug!("{:#x?}", memory_set);
@ -86,7 +89,7 @@ impl Process {
// Allocate kernel stack and push trap frame
let kstack = mc.alloc_stack(7).unwrap();
let tf = TrapFrame::new_user_thread(entry_addr, kstack.top());
let tf = TrapFrame::new_user_thread(entry_addr, USER_STACK_OFFSET + USER_STACK_SIZE);
let rsp = kstack.push_at_top(tf);
Process {
@ -112,14 +115,11 @@ impl<'a> From<&'a ElfFile<'a>> for MemorySet {
ProgramHeader::Ph64(ph) => ph,
_ => unimplemented!(),
};
set.push(MemoryArea {
start_addr: ph.virtual_addr as usize,
end_addr: (ph.virtual_addr + ph.mem_size) as usize,
phys_start_addr: None,
flags: EntryFlags::from(ph.flags).bits() as u32,
name: "",
mapped: false,
});
set.push(MemoryArea::new(
ph.virtual_addr as usize,
(ph.virtual_addr + ph.mem_size) as usize,
EntryFlags::from(ph.flags),
""));
}
set
}

Loading…
Cancel
Save