《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.2 KiB

10 years ago
  1. #include <unistd.h>
  2. #include <proc.h>
  3. #include <syscall.h>
  4. #include <trap.h>
  5. #include <stdio.h>
  6. #include <pmm.h>
  7. #include <assert.h>
  8. static int
  9. sys_exit(uint32_t arg[]) {
  10. int error_code = (int)arg[0];
  11. return do_exit(error_code);
  12. }
  13. static int
  14. sys_fork(uint32_t arg[]) {
  15. struct trapframe *tf = current->tf;
  16. uintptr_t stack = tf->tf_esp;
  17. return do_fork(0, stack, tf);
  18. }
  19. static int
  20. sys_wait(uint32_t arg[]) {
  21. int pid = (int)arg[0];
  22. int *store = (int *)arg[1];
  23. return do_wait(pid, store);
  24. }
  25. static int
  26. sys_exec(uint32_t arg[]) {
  27. const char *name = (const char *)arg[0];
  28. size_t len = (size_t)arg[1];
  29. unsigned char *binary = (unsigned char *)arg[2];
  30. size_t size = (size_t)arg[3];
  31. return do_execve(name, len, binary, size);
  32. }
  33. static int
  34. sys_yield(uint32_t arg[]) {
  35. return do_yield();
  36. }
  37. static int
  38. sys_kill(uint32_t arg[]) {
  39. int pid = (int)arg[0];
  40. return do_kill(pid);
  41. }
  42. static int
  43. sys_getpid(uint32_t arg[]) {
  44. return current->pid;
  45. }
  46. static int
  47. sys_putc(uint32_t arg[]) {
  48. int c = (int)arg[0];
  49. cputchar(c);
  50. return 0;
  51. }
  52. static int
  53. sys_pgdir(uint32_t arg[]) {
  54. print_pgdir();
  55. return 0;
  56. }
  57. static int (*syscalls[])(uint32_t arg[]) = {
  58. [SYS_exit] sys_exit,
  59. [SYS_fork] sys_fork,
  60. [SYS_wait] sys_wait,
  61. [SYS_exec] sys_exec,
  62. [SYS_yield] sys_yield,
  63. [SYS_kill] sys_kill,
  64. [SYS_getpid] sys_getpid,
  65. [SYS_putc] sys_putc,
  66. [SYS_pgdir] sys_pgdir,
  67. };
  68. #define NUM_SYSCALLS ((sizeof(syscalls)) / (sizeof(syscalls[0])))
  69. void
  70. syscall(void) {
  71. struct trapframe *tf = current->tf;
  72. uint32_t arg[5];
  73. int num = tf->tf_regs.reg_eax;
  74. if (num >= 0 && num < NUM_SYSCALLS) {
  75. if (syscalls[num] != NULL) {
  76. arg[0] = tf->tf_regs.reg_edx;
  77. arg[1] = tf->tf_regs.reg_ecx;
  78. arg[2] = tf->tf_regs.reg_ebx;
  79. arg[3] = tf->tf_regs.reg_edi;
  80. arg[4] = tf->tf_regs.reg_esi;
  81. tf->tf_regs.reg_eax = syscalls[num](arg);
  82. return ;
  83. }
  84. }
  85. print_trapframe(tf);
  86. panic("undefined syscall %d, pid = %d, name = %s.\n",
  87. num, current->pid, current->name);
  88. }