mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 17:36:25 +04:00
Fetch buffer in user space as a Vec.
This commit is contained in:
parent
064f1cb5cb
commit
f54573ae15
@ -260,7 +260,7 @@ impl MapArea {
|
|||||||
self.unmap_one(page_table, vpn);
|
self.unmap_one(page_table, vpn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// data: start-aligned but maybe with shorted length
|
/// data: start-aligned but maybe with shorter length
|
||||||
/// assume that all frames were cleared before
|
/// assume that all frames were cleared before
|
||||||
pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) {
|
pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) {
|
||||||
assert_eq!(self.map_type, MapType::Framed);
|
assert_eq!(self.map_type, MapType::Framed);
|
||||||
|
@ -8,7 +8,7 @@ use page_table::{PageTable, PTEFlags};
|
|||||||
use address::{VPNRange, StepByOne};
|
use address::{VPNRange, StepByOne};
|
||||||
pub use address::{PhysAddr, VirtAddr, PhysPageNum, VirtPageNum};
|
pub use address::{PhysAddr, VirtAddr, PhysPageNum, VirtPageNum};
|
||||||
pub use frame_allocator::{FrameTracker, frame_alloc};
|
pub use frame_allocator::{FrameTracker, frame_alloc};
|
||||||
pub use page_table::{PageTableEntry};
|
pub use page_table::{PageTableEntry, translated_byte_buffer};
|
||||||
pub use memory_set::{MemorySet, KERNEL_SPACE, MapPermission};
|
pub use memory_set::{MemorySet, KERNEL_SPACE, MapPermission};
|
||||||
pub use memory_set::remap_test;
|
pub use memory_set::remap_test;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::{frame_alloc, PhysPageNum, FrameTracker, VirtPageNum};
|
use super::{frame_alloc, PhysPageNum, FrameTracker, VirtPageNum, VirtAddr, StepByOne};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use bitflags::*;
|
use bitflags::*;
|
||||||
@ -69,9 +69,9 @@ impl PageTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Temporarily used to get arguments from user space.
|
/// Temporarily used to get arguments from user space.
|
||||||
pub fn from_root_ppn(root_ppn: PhysPageNum) -> Self {
|
pub fn from_token(satp: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
root_ppn,
|
root_ppn: PhysPageNum::from(satp & ((1usize << 44) - 1)),
|
||||||
frames: Vec::new(),
|
frames: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,6 +95,8 @@ impl PageTable {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
fn find_pte(&self, vpn: VirtPageNum) -> Option<&PageTableEntry> {
|
fn find_pte(&self, vpn: VirtPageNum) -> Option<&PageTableEntry> {
|
||||||
|
//println!("into find_pte");
|
||||||
|
//println!("root_ppn = {:?}", self.root_ppn);
|
||||||
let idxs = vpn.indexes();
|
let idxs = vpn.indexes();
|
||||||
let mut ppn = self.root_ppn;
|
let mut ppn = self.root_ppn;
|
||||||
let mut result: Option<&PageTableEntry> = None;
|
let mut result: Option<&PageTableEntry> = None;
|
||||||
@ -123,6 +125,7 @@ impl PageTable {
|
|||||||
*pte = PageTableEntry::empty();
|
*pte = PageTableEntry::empty();
|
||||||
}
|
}
|
||||||
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
|
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
|
||||||
|
//println!("into PageTable::translate");
|
||||||
self.find_pte(vpn)
|
self.find_pte(vpn)
|
||||||
.map(|pte| {pte.clone()})
|
.map(|pte| {pte.clone()})
|
||||||
}
|
}
|
||||||
@ -130,3 +133,29 @@ impl PageTable {
|
|||||||
8usize << 60 | self.root_ppn.0
|
8usize << 60 | self.root_ppn.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static [u8]> {
|
||||||
|
//println!("into translated_byte_buffer!");
|
||||||
|
let page_table = PageTable::from_token(token);
|
||||||
|
let mut start = ptr as usize;
|
||||||
|
let end = start + len;
|
||||||
|
//println!("start={:#x},end={:#x}", start, end);
|
||||||
|
let mut v = Vec::new();
|
||||||
|
while start < end {
|
||||||
|
//println!("start={:#x}", start);
|
||||||
|
let start_va = VirtAddr::from(start);
|
||||||
|
let mut vpn = start_va.floor();
|
||||||
|
//println!("vpn={:?}", vpn);
|
||||||
|
let ppn = page_table
|
||||||
|
.translate(vpn)
|
||||||
|
.unwrap()
|
||||||
|
.ppn();
|
||||||
|
//println!("ppn={:?}", ppn);
|
||||||
|
vpn.step();
|
||||||
|
let mut end_va: VirtAddr = vpn.into();
|
||||||
|
end_va = end_va.min(VirtAddr::from(end));
|
||||||
|
v.push(&ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
|
||||||
|
start = end_va.into();
|
||||||
|
}
|
||||||
|
v
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
|
use crate::mm::translated_byte_buffer;
|
||||||
|
use crate::task::current_user_token;
|
||||||
|
|
||||||
const FD_STDOUT: usize = 1;
|
const FD_STDOUT: usize = 1;
|
||||||
|
|
||||||
pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
||||||
|
//println!("into sys_write!");
|
||||||
match fd {
|
match fd {
|
||||||
FD_STDOUT => {
|
FD_STDOUT => {
|
||||||
let slice = unsafe { core::slice::from_raw_parts(buf, len) };
|
let buffers = translated_byte_buffer(current_user_token(), buf, len);
|
||||||
let str = core::str::from_utf8(slice).unwrap();
|
for buffer in buffers {
|
||||||
print!("{}", str);
|
print!("{}", core::str::from_utf8(buffer).unwrap());
|
||||||
|
}
|
||||||
len as isize
|
len as isize
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -10,7 +10,7 @@ use fs::*;
|
|||||||
use process::*;
|
use process::*;
|
||||||
|
|
||||||
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
||||||
println!("into syscall!");
|
//println!("into syscall!");
|
||||||
match syscall_id {
|
match syscall_id {
|
||||||
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
|
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
|
||||||
SYSCALL_EXIT => sys_exit(args[0] as i32),
|
SYSCALL_EXIT => sys_exit(args[0] as i32),
|
||||||
|
@ -41,13 +41,13 @@ pub fn enable_timer_interrupt() {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_handler() -> ! {
|
pub fn trap_handler() -> ! {
|
||||||
println!("into trap_handler!");
|
//println!("into trap_handler!");
|
||||||
let cx = current_trap_cx();
|
let cx = current_trap_cx();
|
||||||
let scause = scause::read();
|
let scause = scause::read();
|
||||||
let stval = stval::read();
|
let stval = stval::read();
|
||||||
match scause.cause() {
|
match scause.cause() {
|
||||||
Trap::Exception(Exception::UserEnvCall) => {
|
Trap::Exception(Exception::UserEnvCall) => {
|
||||||
println!("found UserEnvCall!");
|
//println!("found UserEnvCall!");
|
||||||
cx.sepc += 4;
|
cx.sepc += 4;
|
||||||
cx.x[10] = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]) as usize;
|
cx.x[10] = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]) as usize;
|
||||||
}
|
}
|
||||||
@ -73,17 +73,17 @@ pub fn trap_handler() -> ! {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_return() -> ! {
|
pub fn trap_return() -> ! {
|
||||||
println!("into trap_return");
|
//println!("into trap_return");
|
||||||
let trap_cx_ptr = TRAP_CONTEXT;
|
let trap_cx_ptr = TRAP_CONTEXT;
|
||||||
let user_satp = current_user_token();
|
let user_satp = current_user_token();
|
||||||
println!("trap_cx_ptr={:#x}, user_satp={:#x}", trap_cx_ptr, user_satp);
|
//println!("trap_cx_ptr={:#x}, user_satp={:#x}", trap_cx_ptr, user_satp);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn __alltraps();
|
fn __alltraps();
|
||||||
fn __restore();
|
fn __restore();
|
||||||
}
|
}
|
||||||
let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE;
|
let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE;
|
||||||
println!("__alltraps={:#x},__restore={:#x}", __alltraps as usize, __restore as usize);
|
//println!("__alltraps={:#x},__restore={:#x}", __alltraps as usize, __restore as usize);
|
||||||
println!("restore_va={:#x}", restore_va);
|
//println!("restore_va={:#x}", restore_va);
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm_asm!("jr $0" :: "r"(restore_va), "{a0}"(trap_cx_ptr), "{a1}"(user_satp) :: "volatile");
|
llvm_asm!("jr $0" :: "r"(restore_va), "{a0}"(trap_cx_ptr), "{a1}"(user_satp) :: "volatile");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user