syscall.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <asm/port_io.h>
  2. #include <kernel/interrupt.h>
  3. #include <kernel/process.hpp>
  4. #include <kernel/syscall.hpp>
  5. #include <kernel/tty.h>
  6. #include <types/elf.hpp>
  7. syscall_handler syscall_handlers[8];
  8. void _syscall_not_impl(interrupt_stack* data)
  9. {
  10. data->s_regs.eax = 0xffffffff;
  11. data->s_regs.edx = 0xffffffff;
  12. }
  13. void _syscall_fork(interrupt_stack* data)
  14. {
  15. thread_context_save(data, current_thread);
  16. process_context_save(data, current_process);
  17. process new_proc(*current_process, *current_thread);
  18. thread* new_thd = new_proc.thds.begin().ptr();
  19. // return value
  20. new_thd->regs.eax = 0;
  21. data->s_regs.eax = new_proc.pid;
  22. new_thd->regs.edx = 0;
  23. data->s_regs.edx = 0;
  24. add_to_process_list(types::move(new_proc));
  25. add_to_ready_list(new_thd);
  26. }
  27. void _syscall_write(interrupt_stack* data)
  28. {
  29. tty_print(console, reinterpret_cast<const char*>(data->s_regs.edi));
  30. data->s_regs.eax = 0;
  31. data->s_regs.edx = 0;
  32. }
  33. void _syscall_sleep(interrupt_stack* data)
  34. {
  35. current_thread->attr.ready = 0;
  36. current_thread->attr.wait = 1;
  37. data->s_regs.eax = 0;
  38. data->s_regs.edx = 0;
  39. do_scheduling(data);
  40. }
  41. void _syscall_crash(interrupt_stack*)
  42. {
  43. tty_print(console, "\nan error occurred while executing command\n");
  44. asm_cli();
  45. asm_hlt();
  46. }
  47. // syscall_exec(const char* exec, const char** argv)
  48. // @param exec: the path of program to execute
  49. // @param argv: arguments end with nullptr
  50. void _syscall_exec(interrupt_stack* data)
  51. {
  52. const char* exec = reinterpret_cast<const char*>(data->s_regs.edi);
  53. // TODO: load argv
  54. const char** argv = reinterpret_cast<const char**>(data->s_regs.esi);
  55. (void)argv;
  56. types::elf::elf32_load(exec, data, current_process->attr.system);
  57. }
  58. void _syscall_exit(interrupt_stack* data)
  59. {
  60. _syscall_crash(data);
  61. }
  62. void init_syscall(void)
  63. {
  64. syscall_handlers[0] = _syscall_fork;
  65. syscall_handlers[1] = _syscall_write;
  66. syscall_handlers[2] = _syscall_sleep;
  67. syscall_handlers[3] = _syscall_crash;
  68. syscall_handlers[4] = _syscall_exec;
  69. syscall_handlers[5] = _syscall_exit;
  70. syscall_handlers[6] = _syscall_not_impl;
  71. syscall_handlers[7] = _syscall_not_impl;
  72. }