syscall.rs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. use core::ffi::c_void;
  2. use alloc::string::String;
  3. use crate::{
  4. arch::ipc::signal::X86_64SignalArch,
  5. include::bindings::bindings::set_system_trap_gate,
  6. ipc::signal_types::SignalArch,
  7. syscall::{Syscall, SystemError, SYS_RT_SIGRETURN},
  8. };
  9. use super::{interrupt::TrapFrame, mm::barrier::mfence};
  10. extern "C" {
  11. fn syscall_int();
  12. }
  13. macro_rules! syscall_return {
  14. ($val:expr, $regs:expr) => {{
  15. let ret = $val;
  16. $regs.rax = ret as u64;
  17. return;
  18. }};
  19. }
  20. #[no_mangle]
  21. pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () {
  22. let syscall_num = frame.rax as usize;
  23. let args = [
  24. frame.r8 as usize,
  25. frame.r9 as usize,
  26. frame.r10 as usize,
  27. frame.r11 as usize,
  28. frame.r12 as usize,
  29. frame.r13 as usize,
  30. frame.r14 as usize,
  31. frame.r15 as usize,
  32. ];
  33. mfence();
  34. // 由于进程管理未完成重构,有些系统调用需要在这里临时处理,以后这里的特殊处理要删掉。
  35. match syscall_num {
  36. SYS_RT_SIGRETURN => {
  37. syscall_return!(X86_64SignalArch::sys_rt_sigreturn(frame) as usize, frame);
  38. }
  39. _ => {}
  40. }
  41. syscall_return!(
  42. Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize)
  43. as u64,
  44. frame
  45. );
  46. }
  47. /// 系统调用初始化
  48. pub fn arch_syscall_init() -> Result<(), SystemError> {
  49. // kinfo!("arch_syscall_init\n");
  50. unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
  51. return Ok(());
  52. }
  53. /// 执行第一个用户进程的函数(只应该被调用一次)
  54. ///
  55. /// 当进程管理重构完成后,这个函数应该被删除。调整为别的函数。
  56. #[no_mangle]
  57. pub extern "C" fn rs_exec_init_process(frame: &mut TrapFrame) -> usize {
  58. let path = String::from("/bin/shell.elf");
  59. let argv = vec![String::from("/bin/shell.elf")];
  60. let envp = vec![String::from("PATH=/bin")];
  61. let r = Syscall::do_execve(path, argv, envp, frame);
  62. // kdebug!("rs_exec_init_process: r: {:?}\n", r);
  63. return r.map(|_| 0).unwrap_or_else(|e| e.to_posix_errno() as usize);
  64. }