ch4 ok on qemu/k210 && Remove some comments.
This commit is contained in:
parent
8ee3671269
commit
949f2095bb
8 changed files with 0 additions and 48 deletions
|
@ -11,14 +11,11 @@ pub struct FrameTracker {
|
||||||
|
|
||||||
impl FrameTracker {
|
impl FrameTracker {
|
||||||
pub fn new(ppn: PhysPageNum) -> Self {
|
pub fn new(ppn: PhysPageNum) -> Self {
|
||||||
//println!("into FrameTracker::new, ppn = {:?}", ppn);
|
|
||||||
// page cleaning
|
// page cleaning
|
||||||
let bytes_array = ppn.get_bytes_array();
|
let bytes_array = ppn.get_bytes_array();
|
||||||
//println!("ptr = {:p}, len = {}", bytes_array.as_ptr(), bytes_array.len());
|
|
||||||
for i in bytes_array {
|
for i in bytes_array {
|
||||||
*i = 0;
|
*i = 0;
|
||||||
}
|
}
|
||||||
//println!("OK");
|
|
||||||
Self { ppn }
|
Self { ppn }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,12 +59,9 @@ impl FrameAllocator for StackFrameAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn alloc(&mut self) -> Option<PhysPageNum> {
|
fn alloc(&mut self) -> Option<PhysPageNum> {
|
||||||
//println!("into StackFrameAllocator::alloc()");
|
|
||||||
if let Some(ppn) = self.recycled.pop() {
|
if let Some(ppn) = self.recycled.pop() {
|
||||||
//println!("has recycled!");
|
|
||||||
Some(ppn.into())
|
Some(ppn.into())
|
||||||
} else {
|
} else {
|
||||||
//println!("run out recycled, current = {}, end = {}!", self.current, self.end);
|
|
||||||
if self.current == self.end {
|
if self.current == self.end {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,7 +101,6 @@ pub fn init_frame_allocator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame_alloc() -> Option<FrameTracker> {
|
pub fn frame_alloc() -> Option<FrameTracker> {
|
||||||
//println!("into frame_alloc()");
|
|
||||||
FRAME_ALLOCATOR
|
FRAME_ALLOCATOR
|
||||||
.lock()
|
.lock()
|
||||||
.alloc()
|
.alloc()
|
||||||
|
|
|
@ -124,24 +124,19 @@ impl MemorySet {
|
||||||
/// Include sections in elf and trampoline and TrapContext and user stack,
|
/// Include sections in elf and trampoline and TrapContext and user stack,
|
||||||
/// also returns user_sp and entry point.
|
/// also returns user_sp and entry point.
|
||||||
pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
|
pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
|
||||||
//println!("into from_elf!");
|
|
||||||
let mut memory_set = Self::new_bare();
|
let mut memory_set = Self::new_bare();
|
||||||
// map trampoline
|
// map trampoline
|
||||||
//println!("mapping trampoline!");
|
|
||||||
memory_set.map_trampoline();
|
memory_set.map_trampoline();
|
||||||
// map program headers of elf, with U flag
|
// map program headers of elf, with U flag
|
||||||
//println!("mapping elf!");
|
|
||||||
let elf = xmas_elf::ElfFile::new(elf_data).unwrap();
|
let elf = xmas_elf::ElfFile::new(elf_data).unwrap();
|
||||||
let elf_header = elf.header;
|
let elf_header = elf.header;
|
||||||
let magic = elf_header.pt1.magic;
|
let magic = elf_header.pt1.magic;
|
||||||
assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
|
assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
|
||||||
let ph_count = elf_header.pt2.ph_count();
|
let ph_count = elf_header.pt2.ph_count();
|
||||||
//println!("ph_count = {}", ph_count);
|
|
||||||
let mut max_end_vpn = VirtPageNum(0);
|
let mut max_end_vpn = VirtPageNum(0);
|
||||||
for i in 0..ph_count {
|
for i in 0..ph_count {
|
||||||
let ph = elf.program_header(i).unwrap();
|
let ph = elf.program_header(i).unwrap();
|
||||||
if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
|
if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
|
||||||
//println!("ph#{},va={},memsz={}", i, ph.virtual_addr(), ph.mem_size());
|
|
||||||
let start_va: VirtAddr = (ph.virtual_addr() as usize).into();
|
let start_va: VirtAddr = (ph.virtual_addr() as usize).into();
|
||||||
let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into();
|
let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into();
|
||||||
let mut map_perm = MapPermission::U;
|
let mut map_perm = MapPermission::U;
|
||||||
|
@ -149,16 +144,13 @@ impl MemorySet {
|
||||||
if ph_flags.is_read() { map_perm |= MapPermission::R; }
|
if ph_flags.is_read() { map_perm |= MapPermission::R; }
|
||||||
if ph_flags.is_write() { map_perm |= MapPermission::W; }
|
if ph_flags.is_write() { map_perm |= MapPermission::W; }
|
||||||
if ph_flags.is_execute() { map_perm |= MapPermission::X; }
|
if ph_flags.is_execute() { map_perm |= MapPermission::X; }
|
||||||
//println!("creating MapArea!");
|
|
||||||
let map_area = MapArea::new(
|
let map_area = MapArea::new(
|
||||||
start_va,
|
start_va,
|
||||||
end_va,
|
end_va,
|
||||||
MapType::Framed,
|
MapType::Framed,
|
||||||
map_perm,
|
map_perm,
|
||||||
);
|
);
|
||||||
//println!("end_vpn = {:?}", map_area.vpn_range.get_end());
|
|
||||||
max_end_vpn = map_area.vpn_range.get_end();
|
max_end_vpn = map_area.vpn_range.get_end();
|
||||||
//println!("pushing MapArea!");
|
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
map_area,
|
map_area,
|
||||||
Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize])
|
Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize])
|
||||||
|
@ -166,13 +158,11 @@ impl MemorySet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// map user stack with U flags
|
// map user stack with U flags
|
||||||
//println!("mapping user stack!");
|
|
||||||
let max_end_va: VirtAddr = max_end_vpn.into();
|
let max_end_va: VirtAddr = max_end_vpn.into();
|
||||||
let mut user_stack_bottom: usize = max_end_va.into();
|
let mut user_stack_bottom: usize = max_end_va.into();
|
||||||
// guard page
|
// guard page
|
||||||
user_stack_bottom += PAGE_SIZE;
|
user_stack_bottom += PAGE_SIZE;
|
||||||
let user_stack_top = user_stack_bottom + USER_STACK_SIZE;
|
let user_stack_top = user_stack_bottom + USER_STACK_SIZE;
|
||||||
//println!("user stack={:#x},{:#x}", user_stack_bottom, user_stack_top);
|
|
||||||
memory_set.push(MapArea::new(
|
memory_set.push(MapArea::new(
|
||||||
user_stack_bottom.into(),
|
user_stack_bottom.into(),
|
||||||
user_stack_top.into(),
|
user_stack_top.into(),
|
||||||
|
@ -180,7 +170,6 @@ impl MemorySet {
|
||||||
MapPermission::R | MapPermission::W | MapPermission::U,
|
MapPermission::R | MapPermission::W | MapPermission::U,
|
||||||
), None);
|
), None);
|
||||||
// map TrapContext
|
// map TrapContext
|
||||||
//println!("mapping TrapContext {:#x},{:#x}", TRAP_CONTEXT, TRAMPOLINE);
|
|
||||||
memory_set.push(MapArea::new(
|
memory_set.push(MapArea::new(
|
||||||
TRAP_CONTEXT.into(),
|
TRAP_CONTEXT.into(),
|
||||||
TRAMPOLINE.into(),
|
TRAMPOLINE.into(),
|
||||||
|
|
|
@ -61,7 +61,6 @@ pub struct PageTable {
|
||||||
/// Assume that it won't oom when creating/mapping.
|
/// Assume that it won't oom when creating/mapping.
|
||||||
impl PageTable {
|
impl PageTable {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
//println!("into PageTable::new()");
|
|
||||||
let frame = frame_alloc().unwrap();
|
let frame = frame_alloc().unwrap();
|
||||||
PageTable {
|
PageTable {
|
||||||
root_ppn: frame.ppn,
|
root_ppn: frame.ppn,
|
||||||
|
@ -95,8 +94,6 @@ 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;
|
||||||
|
@ -115,7 +112,6 @@ impl PageTable {
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
|
pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
|
||||||
//println!("mapping {:?} {:?}", vpn, ppn);
|
|
||||||
let pte = self.find_pte_create(vpn).unwrap();
|
let pte = self.find_pte_create(vpn).unwrap();
|
||||||
assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
|
assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
|
||||||
*pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
|
*pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
|
||||||
|
@ -127,7 +123,6 @@ 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()})
|
||||||
}
|
}
|
||||||
|
@ -137,22 +132,17 @@ impl PageTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static [u8]> {
|
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 page_table = PageTable::from_token(token);
|
||||||
let mut start = ptr as usize;
|
let mut start = ptr as usize;
|
||||||
let end = start + len;
|
let end = start + len;
|
||||||
//println!("start={:#x},end={:#x}", start, end);
|
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
while start < end {
|
while start < end {
|
||||||
//println!("start={:#x}", start);
|
|
||||||
let start_va = VirtAddr::from(start);
|
let start_va = VirtAddr::from(start);
|
||||||
let mut vpn = start_va.floor();
|
let mut vpn = start_va.floor();
|
||||||
//println!("vpn={:?}", vpn);
|
|
||||||
let ppn = page_table
|
let ppn = page_table
|
||||||
.translate(vpn)
|
.translate(vpn)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.ppn();
|
.ppn();
|
||||||
//println!("ppn={:?}", ppn);
|
|
||||||
vpn.step();
|
vpn.step();
|
||||||
let mut end_va: VirtAddr = vpn.into();
|
let mut end_va: VirtAddr = vpn.into();
|
||||||
end_va = end_va.min(VirtAddr::from(end));
|
end_va = end_va.min(VirtAddr::from(end));
|
||||||
|
|
|
@ -4,7 +4,6 @@ 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 buffers = translated_byte_buffer(current_user_token(), buf, len);
|
let buffers = translated_byte_buffer(current_user_token(), buf, len);
|
||||||
|
|
|
@ -10,7 +10,6 @@ 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!");
|
|
||||||
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),
|
||||||
|
|
|
@ -31,7 +31,6 @@ lazy_static! {
|
||||||
println!("num_app = {}", num_app);
|
println!("num_app = {}", num_app);
|
||||||
let mut tasks: Vec<TaskControlBlock> = Vec::new();
|
let mut tasks: Vec<TaskControlBlock> = Vec::new();
|
||||||
for i in 0..num_app {
|
for i in 0..num_app {
|
||||||
println!("creating TCB #{}", i);
|
|
||||||
tasks.push(TaskControlBlock::new(
|
tasks.push(TaskControlBlock::new(
|
||||||
get_app_data(i),
|
get_app_data(i),
|
||||||
i,
|
i,
|
||||||
|
@ -49,10 +48,8 @@ lazy_static! {
|
||||||
|
|
||||||
impl TaskManager {
|
impl TaskManager {
|
||||||
fn run_first_task(&self) {
|
fn run_first_task(&self) {
|
||||||
println!("into TaskManager::run_first_task");
|
|
||||||
self.inner.borrow_mut().tasks[0].task_status = TaskStatus::Running;
|
self.inner.borrow_mut().tasks[0].task_status = TaskStatus::Running;
|
||||||
let next_task_cx = self.inner.borrow().tasks[0].get_task_cx_ptr2();
|
let next_task_cx = self.inner.borrow().tasks[0].get_task_cx_ptr2();
|
||||||
println!("next_task_cx={:p} {:#x}", next_task_cx, unsafe { next_task_cx.read_volatile() });
|
|
||||||
let _unused: usize = 0;
|
let _unused: usize = 0;
|
||||||
unsafe {
|
unsafe {
|
||||||
__switch(
|
__switch(
|
||||||
|
|
|
@ -22,20 +22,15 @@ impl TaskControlBlock {
|
||||||
self.memory_set.token()
|
self.memory_set.token()
|
||||||
}
|
}
|
||||||
pub fn new(elf_data: &[u8], app_id: usize) -> Self {
|
pub fn new(elf_data: &[u8], app_id: usize) -> Self {
|
||||||
//println!("into TCB::new");
|
|
||||||
// memory_set with elf program headers/trampoline/trap context/user stack
|
// memory_set with elf program headers/trampoline/trap context/user stack
|
||||||
let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
|
let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
|
||||||
//println!("user_sp={:#x},entry_point={:#}", user_sp, entry_point);
|
|
||||||
let trap_cx_ppn = memory_set
|
let trap_cx_ppn = memory_set
|
||||||
.translate(VirtAddr::from(TRAP_CONTEXT).into())
|
.translate(VirtAddr::from(TRAP_CONTEXT).into())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.ppn();
|
.ppn();
|
||||||
//println!("trap_cx_ppn={:?}", trap_cx_ppn);
|
|
||||||
let task_status = TaskStatus::Ready;
|
let task_status = TaskStatus::Ready;
|
||||||
// map a kernel-stack in kernel space
|
// map a kernel-stack in kernel space
|
||||||
//println!("mapping kernel-stack!");
|
|
||||||
let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(app_id);
|
let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(app_id);
|
||||||
//println!("kernel_stack={:#x},{:#x}", kernel_stack_bottom, kernel_stack_top);
|
|
||||||
KERNEL_SPACE
|
KERNEL_SPACE
|
||||||
.lock()
|
.lock()
|
||||||
.insert_framed_area(
|
.insert_framed_area(
|
||||||
|
@ -44,10 +39,7 @@ impl TaskControlBlock {
|
||||||
MapPermission::R | MapPermission::W,
|
MapPermission::R | MapPermission::W,
|
||||||
);
|
);
|
||||||
let task_cx_ptr = (kernel_stack_top - core::mem::size_of::<TaskContext>()) as *mut TaskContext;
|
let task_cx_ptr = (kernel_stack_top - core::mem::size_of::<TaskContext>()) as *mut TaskContext;
|
||||||
//println!("task_cx size={}", core::mem::size_of::<TaskContext>());
|
|
||||||
//println!("init task_cx, ptr={:p}", task_cx_ptr);
|
|
||||||
unsafe { *task_cx_ptr = TaskContext::goto_trap_return(); }
|
unsafe { *task_cx_ptr = TaskContext::goto_trap_return(); }
|
||||||
//println!("after init task_cx");
|
|
||||||
let task_control_block = Self {
|
let task_control_block = Self {
|
||||||
task_cx_ptr: task_cx_ptr as usize,
|
task_cx_ptr: task_cx_ptr as usize,
|
||||||
task_status,
|
task_status,
|
||||||
|
@ -56,7 +48,6 @@ impl TaskControlBlock {
|
||||||
base_size: user_sp,
|
base_size: user_sp,
|
||||||
};
|
};
|
||||||
// prepare TrapContext in user space
|
// prepare TrapContext in user space
|
||||||
//println!("preparing trap_cx");
|
|
||||||
let trap_cx = task_control_block.get_trap_cx();
|
let trap_cx = task_control_block.get_trap_cx();
|
||||||
*trap_cx = TrapContext::app_init_context(
|
*trap_cx = TrapContext::app_init_context(
|
||||||
entry_point,
|
entry_point,
|
||||||
|
|
|
@ -52,14 +52,12 @@ pub fn enable_timer_interrupt() {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_handler() -> ! {
|
pub fn trap_handler() -> ! {
|
||||||
//println!("into trap_handler!");
|
|
||||||
set_kernel_trap_entry();
|
set_kernel_trap_entry();
|
||||||
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!");
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -86,17 +84,13 @@ pub fn trap_handler() -> ! {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_return() -> ! {
|
pub fn trap_return() -> ! {
|
||||||
set_user_trap_entry();
|
set_user_trap_entry();
|
||||||
//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);
|
|
||||||
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!("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…
Add table
Add a link
Reference in a new issue