1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-23 18:06:20 +04:00

Added syscalls and information to support syscalls.

This commit is contained in:
Stephen Marz 2020-06-03 21:33:04 -04:00
parent 9a26a90962
commit f6d842b02b
4 changed files with 62 additions and 29 deletions

View File

@ -208,6 +208,7 @@ impl File {
} }
// println!("DEBUG: Map 0x{:08x} to 0x{:08x} {:02x}", vaddr, paddr, bits); // println!("DEBUG: Map 0x{:08x} to 0x{:08x} {:02x}", vaddr, paddr, bits);
} }
my_proc.brk += 0x1000;
} }
// This will map all of the program pages. Notice that in linker.lds in // This will map all of the program pages. Notice that in linker.lds in
// userspace we set the entry point address to 0x2000_0000. This is the // userspace we set the entry point address to 0x2000_0000. This is the

View File

@ -402,6 +402,11 @@ impl Drop for Process {
} }
dealloc(self.mmu_table as *mut u8); dealloc(self.mmu_table as *mut u8);
dealloc(self.frame as *mut u8); dealloc(self.frame as *mut u8);
for i in self.data.pages.drain(..) {
dealloc(i as *mut u8);
}
// Kernel processes don't have a program, instead the program is linked
// directly in the kernel.
if !self.program.is_null() { if !self.program.is_null() {
dealloc(self.program); dealloc(self.program);
} }
@ -425,6 +430,7 @@ pub struct ProcessData {
pub environ: BTreeMap<String, String>, pub environ: BTreeMap<String, String>,
pub fdesc: BTreeMap<u16, FileDescriptor>, pub fdesc: BTreeMap<u16, FileDescriptor>,
pub cwd: String, pub cwd: String,
pub pages: VecDeque<usize>,
} }
// This is private data that we can query with system calls. // This is private data that we can query with system calls.
@ -436,6 +442,7 @@ impl ProcessData {
environ: BTreeMap::new(), environ: BTreeMap::new(),
fdesc: BTreeMap::new(), fdesc: BTreeMap::new(),
cwd: String::new(), cwd: String::new(),
pages: VecDeque::new(),
} }
} }
} }

View File

@ -10,7 +10,7 @@ use crate::{block::block_op,
fs, fs,
gpu, gpu,
input::{Event, ABS_EVENTS, KEY_EVENTS}, input::{Event, ABS_EVENTS, KEY_EVENTS},
page::{map, virt_to_phys, EntryBits, Table, PAGE_SIZE}, page::{map, virt_to_phys, EntryBits, Table, PAGE_SIZE, zalloc},
process::{add_kernel_process_args, delete_process, get_by_pid, set_sleeping, set_waiting, PROCESS_LIST, PROCESS_LIST_MUTEX}}; process::{add_kernel_process_args, delete_process, get_by_pid, set_sleeping, set_waiting, PROCESS_LIST, PROCESS_LIST_MUTEX}};
use alloc::{boxed::Box, string::String}; use alloc::{boxed::Box, string::String};
@ -125,6 +125,10 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
(*frame).regs[gp(Registers::A0)] = -1isize as usize; (*frame).regs[gp(Registers::A0)] = -1isize as usize;
0 0
} }
57 => {
// #define SYS_close 57
0
}
63 => { 63 => {
// Read system call // Read system call
// This is an asynchronous call. This will get the // This is an asynchronous call. This will get the
@ -174,19 +178,20 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
let mut buf = (*frame).regs[gp(Registers::A1)] as *const u8; let mut buf = (*frame).regs[gp(Registers::A1)] as *const u8;
let size = (*frame).regs[gp(Registers::A2)]; let size = (*frame).regs[gp(Registers::A2)];
let process = get_by_pid((*frame).pid as u16); let process = get_by_pid((*frame).pid as u16);
if (*frame).satp >> 60 != 0 { // if (*frame).satp >> 60 != 0 {
let table = ((*process).mmu_table).as_mut().unwrap(); // let table = ((*process).mmu_table).as_mut().unwrap();
let paddr = virt_to_phys(table, buf as usize); // let paddr = virt_to_phys(table, buf as usize);
if let Some(bufaddr) = paddr { // if let Some(bufaddr) = paddr {
buf = bufaddr as *const u8; // buf = bufaddr as *const u8;
} // }
else { // else {
(*frame).regs[gp(Registers::A0)] = -1isize as usize; // (*frame).regs[gp(Registers::A0)] = -1isize as usize;
return 0; // return 0;
} // }
} // }
if fd == 1 || fd == 2 { if fd == 1 || fd == 2 {
// stdout / stderr // stdout / stderr
// println!("WRITE {}, 0x{:08x}, {}", fd, bu/f as usize, size);
let mut iter = 0; let mut iter = 0;
for _ in 0..size { for _ in 0..size {
iter += 1; iter += 1;
@ -194,7 +199,8 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
let table = ((*process).mmu_table).as_mut().unwrap(); let table = ((*process).mmu_table).as_mut().unwrap();
let paddr = virt_to_phys(table, buf as usize); let paddr = virt_to_phys(table, buf as usize);
if let Some(bufaddr) = paddr { if let Some(bufaddr) = paddr {
buf = bufaddr as *const u8; let output = *(bufaddr as *const u8) as char;
print!("{}", output);
} }
else { else {
(*frame).regs[gp(Registers::A0)] = -1isize as usize; (*frame).regs[gp(Registers::A0)] = -1isize as usize;
@ -215,6 +221,12 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
(*frame).regs[gp(Registers::A0)] = -1isize as usize; (*frame).regs[gp(Registers::A0)] = -1isize as usize;
0 0
} }
// #define SYS_fstat 80
80 => {
// int fstat(int filedes, struct stat *buf)
(*frame).regs[gp(Registers::A0)] = 0;
0
}
172 => { 172 => {
// A0 = pid // A0 = pid
(*frame).regs[Registers::A0 as usize] = (*frame).pid; (*frame).regs[Registers::A0 as usize] = (*frame).pid;
@ -236,8 +248,21 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
// #define SYS_brk 214 // #define SYS_brk 214
// int brk(void *addr); // int brk(void *addr);
let addr = (*frame).regs[gp(Registers::A0)]; let addr = (*frame).regs[gp(Registers::A0)];
println!("BRK Addr = 0x{:08x}", addr); let process = get_by_pid((*frame).pid as u16).as_mut().unwrap();
(*frame).regs[gp(Registers::A0)] = -1isize as usize; // println!("Break move from 0x{:08x} to 0x{:08x}", process.brk, addr);
if addr > process.brk {
if (*frame).satp >> 60 != 0 {
let table = ((*process).mmu_table).as_mut().unwrap();
let diff = (addr + PAGE_SIZE - process.brk) / PAGE_SIZE;
for i in 0..diff {
let new_addr = zalloc(1) as usize;
process.data.pages.push_back(new_addr);
map(table, process.brk + (i << 12), new_addr, EntryBits::UserReadWrite.val(), 0);
}
}
process.brk = addr;
}
(*frame).regs[gp(Registers::A0)] = process.brk;
0 0
} }
// System calls 1000 and above are "special" system calls for our OS. I'll // System calls 1000 and above are "special" system calls for our OS. I'll
@ -393,11 +418,12 @@ fn exec_func(args: usize) {
println!("Failed to launch process."); println!("Failed to launch process.");
} }
else { else {
let process = proc.ok().unwrap();
// If we hold this lock, we can still be preempted, but the scheduler will // If we hold this lock, we can still be preempted, but the scheduler will
// return control to us. This required us to use try_lock in the scheduler. // return control to us. This required us to use try_lock in the scheduler.
PROCESS_LIST_MUTEX.sleep_lock(); PROCESS_LIST_MUTEX.sleep_lock();
if let Some(mut proc_list) = PROCESS_LIST.take() { if let Some(mut proc_list) = PROCESS_LIST.take() {
proc_list.push_back(proc.ok().unwrap()); proc_list.push_back(process);
PROCESS_LIST.replace(proc_list); PROCESS_LIST.replace(proc_list);
} }
PROCESS_LIST_MUTEX.unlock(); PROCESS_LIST_MUTEX.unlock();
@ -412,14 +438,13 @@ fn exec_func(args: usize) {
// #define SYS_faccessat 48 // #define SYS_faccessat 48
// #define SYS_chdir 49 // #define SYS_chdir 49
// #define SYS_openat 56 // #define SYS_openat 56
// #define SYS_close 57
// #define SYS_getdents 61 // #define SYS_getdents 61
// #define SYS_lseek 62 // #define SYS_lseek 62
// #define SYS_read 63 // #define SYS_read 63
// #define SYS_pread 67 // #define SYS_pread 67
// #define SYS_pwrite 68 // #define SYS_pwrite 68
// #define SYS_fstatat 79 // #define SYS_fstatat 79
// #define SYS_fstat 80
// #define SYS_kill 129 // #define SYS_kill 129
// #define SYS_rt_sigaction 134 // #define SYS_rt_sigaction 134
// #define SYS_times 153 // #define SYS_times 153

View File

@ -45,7 +45,7 @@ extern "C" fn m_trap(epc: usize,
// We will use this to awaken our other CPUs so they can process // We will use this to awaken our other CPUs so they can process
// processes. // processes.
println!("Machine software interrupt CPU #{}", hart); println!("Machine software interrupt CPU #{}", hart);
}, }
7 => { 7 => {
// This is the context-switch timer. // This is the context-switch timer.
// We would typically invoke the scheduler here to pick another // We would typically invoke the scheduler here to pick another
@ -56,7 +56,7 @@ extern "C" fn m_trap(epc: usize,
if new_frame != 0 { if new_frame != 0 {
rust_switch_to_user(new_frame); rust_switch_to_user(new_frame);
} }
}, }
11 => { 11 => {
// Machine external (interrupt from Platform Interrupt Controller (PLIC)) // Machine external (interrupt from Platform Interrupt Controller (PLIC))
// println!("Machine external interrupt CPU#{}", hart); // println!("Machine external interrupt CPU#{}", hart);
@ -65,10 +65,10 @@ extern "C" fn m_trap(epc: usize,
// get an interrupt from a non-PLIC source. This is the main reason that the PLIC // get an interrupt from a non-PLIC source. This is the main reason that the PLIC
// hardwires the id 0 to 0, so that we can use it as an error case. // hardwires the id 0 to 0, so that we can use it as an error case.
plic::handle_interrupt(); plic::handle_interrupt();
}, }
_ => { _ => {
panic!("Unhandled async trap CPU#{} -> {}\n", hart, cause_num); panic!("Unhandled async trap CPU#{} -> {}\n", hart, cause_num);
}, }
} }
} }
else { else {
@ -85,7 +85,7 @@ extern "C" fn m_trap(epc: usize,
let frame = schedule(); let frame = schedule();
schedule_next_context_switch(1); schedule_next_context_switch(1);
rust_switch_to_user(frame); rust_switch_to_user(frame);
}, }
3 => { 3 => {
// breakpoint // breakpoint
println!("BKPT\n\n"); println!("BKPT\n\n");
@ -97,7 +97,7 @@ extern "C" fn m_trap(epc: usize,
let frame = schedule(); let frame = schedule();
schedule_next_context_switch(1); schedule_next_context_switch(1);
rust_switch_to_user(frame); rust_switch_to_user(frame);
}, }
8 | 9 | 11 => unsafe { 8 | 9 | 11 => unsafe {
// Environment (system) call from User, Supervisor, and Machine modes // Environment (system) call from User, Supervisor, and Machine modes
// println!("E-call from User mode! CPU#{} -> 0x{:08x}", hart, epc); // println!("E-call from User mode! CPU#{} -> 0x{:08x}", hart, epc);
@ -110,7 +110,7 @@ extern "C" fn m_trap(epc: usize,
schedule_next_context_switch(1); schedule_next_context_switch(1);
rust_switch_to_user(frame); rust_switch_to_user(frame);
} }
}, }
// Page faults // Page faults
12 => unsafe { 12 => unsafe {
// Instruction page fault // Instruction page fault
@ -119,7 +119,7 @@ extern "C" fn m_trap(epc: usize,
let frame = schedule(); let frame = schedule();
schedule_next_context_switch(1); schedule_next_context_switch(1);
rust_switch_to_user(frame); rust_switch_to_user(frame);
}, }
13 => unsafe { 13 => unsafe {
// Load page fault // Load page fault
println!("Load page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval); println!("Load page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval);
@ -127,7 +127,7 @@ extern "C" fn m_trap(epc: usize,
let frame = schedule(); let frame = schedule();
schedule_next_context_switch(1); schedule_next_context_switch(1);
rust_switch_to_user(frame); rust_switch_to_user(frame);
}, }
15 => unsafe { 15 => unsafe {
// Store page fault // Store page fault
println!("Store page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval); println!("Store page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval);
@ -135,13 +135,13 @@ extern "C" fn m_trap(epc: usize,
let frame = schedule(); let frame = schedule();
schedule_next_context_switch(1); schedule_next_context_switch(1);
rust_switch_to_user(frame); rust_switch_to_user(frame);
}, }
_ => { _ => {
panic!( panic!(
"Unhandled sync trap {}. CPU#{} -> 0x{:08x}: 0x{:08x}\n", "Unhandled sync trap {}. CPU#{} -> 0x{:08x}: 0x{:08x}\n",
cause_num, hart, epc, tval cause_num, hart, epc, tval
); );
}, }
} }
}; };
// Finally, return the updated program counter // Finally, return the updated program counter