Implement many process syscalls.
This commit is contained in:
parent
e56ea17566
commit
8fbadfc951
20 changed files with 383 additions and 88 deletions
|
@ -110,6 +110,13 @@ impl VirtPageNum {
|
|||
}
|
||||
}
|
||||
|
||||
impl PhysAddr {
|
||||
pub fn get_mut<T>(&self) -> &'static mut T {
|
||||
unsafe {
|
||||
(self.0 as *mut T).as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PhysPageNum {
|
||||
pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
|
||||
let pa: PhysAddr = self.clone().into();
|
||||
|
@ -125,9 +132,7 @@ impl PhysPageNum {
|
|||
}
|
||||
pub fn get_mut<T>(&self) -> &'static mut T {
|
||||
let pa: PhysAddr = self.clone().into();
|
||||
unsafe {
|
||||
(pa.0 as *mut T).as_mut().unwrap()
|
||||
}
|
||||
pa.get_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ impl MemorySet {
|
|||
areas: Vec::new(),
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub fn dealloc_all_frames(&mut self) {
|
||||
*self = Self::new_bare();
|
||||
}
|
||||
|
@ -68,7 +69,6 @@ impl MemorySet {
|
|||
area.unmap(&mut self.page_table);
|
||||
self.areas.remove(idx);
|
||||
}
|
||||
panic!("Area not found!");
|
||||
}
|
||||
fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
|
||||
map_area.map(&mut self.page_table);
|
||||
|
@ -189,6 +189,23 @@ impl MemorySet {
|
|||
), None);
|
||||
(memory_set, user_stack_top, elf.header.pt2.entry_point() as usize)
|
||||
}
|
||||
pub fn from_existed_user(user_space: &MemorySet) -> MemorySet {
|
||||
let mut memory_set = Self::new_bare();
|
||||
// map trampoline
|
||||
memory_set.map_trampoline();
|
||||
// copy data sections/trap_context/user_stack
|
||||
for area in user_space.areas.iter() {
|
||||
let new_area = MapArea::from_another(area);
|
||||
memory_set.push(new_area, None);
|
||||
// copy data from another space
|
||||
for vpn in area.vpn_range {
|
||||
let src_ppn = user_space.translate(vpn).unwrap().ppn();
|
||||
let dst_ppn = memory_set.translate(vpn).unwrap().ppn();
|
||||
dst_ppn.get_bytes_array().copy_from_slice(src_ppn.get_bytes_array());
|
||||
}
|
||||
}
|
||||
memory_set
|
||||
}
|
||||
pub fn activate(&self) {
|
||||
let satp = self.page_table.token();
|
||||
unsafe {
|
||||
|
@ -199,6 +216,9 @@ impl MemorySet {
|
|||
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
|
||||
self.page_table.translate(vpn)
|
||||
}
|
||||
pub fn clear(&mut self) {
|
||||
*self = Self::new_bare();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapArea {
|
||||
|
@ -224,6 +244,14 @@ impl MapArea {
|
|||
map_perm,
|
||||
}
|
||||
}
|
||||
pub fn from_another(another: &MapArea) -> Self {
|
||||
Self {
|
||||
vpn_range: VPNRange::new(another.vpn_range.get_start(), another.vpn_range.get_end()),
|
||||
data_frames: BTreeMap::new(),
|
||||
map_type: another.map_type,
|
||||
map_perm: another.map_perm,
|
||||
}
|
||||
}
|
||||
pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
|
||||
let ppn: PhysPageNum;
|
||||
match self.map_type {
|
||||
|
|
|
@ -8,7 +8,12 @@ use page_table::{PageTable, PTEFlags};
|
|||
use address::{VPNRange, StepByOne};
|
||||
pub use address::{PhysAddr, VirtAddr, PhysPageNum, VirtPageNum};
|
||||
pub use frame_allocator::{FrameTracker, frame_alloc};
|
||||
pub use page_table::{PageTableEntry, translated_byte_buffer};
|
||||
pub use page_table::{
|
||||
PageTableEntry,
|
||||
translated_byte_buffer,
|
||||
translated_str,
|
||||
translated_refmut,
|
||||
};
|
||||
pub use memory_set::{MemorySet, KERNEL_SPACE, MapPermission};
|
||||
pub use memory_set::remap_test;
|
||||
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
use super::{frame_alloc, PhysPageNum, FrameTracker, VirtPageNum, VirtAddr, StepByOne};
|
||||
use super::{
|
||||
frame_alloc,
|
||||
PhysPageNum,
|
||||
FrameTracker,
|
||||
VirtPageNum,
|
||||
VirtAddr,
|
||||
PhysAddr,
|
||||
StepByOne
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use alloc::vec;
|
||||
use alloc::string::String;
|
||||
use bitflags::*;
|
||||
|
||||
bitflags! {
|
||||
|
@ -126,6 +135,17 @@ impl PageTable {
|
|||
self.find_pte(vpn)
|
||||
.map(|pte| {pte.clone()})
|
||||
}
|
||||
pub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr> {
|
||||
self.find_pte(va.clone().floor())
|
||||
.map(|pte| {
|
||||
//println!("translate_va:va = {:?}", va);
|
||||
let aligned_pa: PhysAddr = pte.ppn().into();
|
||||
//println!("translate_va:pa_align = {:?}", aligned_pa);
|
||||
let offset = va.page_offset();
|
||||
let aligned_pa_usize: usize = aligned_pa.into();
|
||||
(aligned_pa_usize + offset).into()
|
||||
})
|
||||
}
|
||||
pub fn token(&self) -> usize {
|
||||
8usize << 60 | self.root_ppn.0
|
||||
}
|
||||
|
@ -150,4 +170,28 @@ pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&
|
|||
start = end_va.into();
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
pub fn translated_str(token: usize, ptr: *const u8) -> String {
|
||||
let page_table = PageTable::from_token(token);
|
||||
let mut string = String::new();
|
||||
let mut va = ptr as usize;
|
||||
loop {
|
||||
let ch: u8 = *(page_table.translate_va(VirtAddr::from(va)).unwrap().get_mut());
|
||||
if ch == 0 {
|
||||
break;
|
||||
} else {
|
||||
string.push(ch as char);
|
||||
va += 1;
|
||||
}
|
||||
}
|
||||
string
|
||||
}
|
||||
|
||||
pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T {
|
||||
//println!("into translated_refmut!");
|
||||
let page_table = PageTable::from_token(token);
|
||||
let va = ptr as usize;
|
||||
//println!("translated_refmut: before translate_va");
|
||||
page_table.translate_va(VirtAddr::from(va)).unwrap().get_mut()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue