void do_syscall(TrapFrame *tf) { int id = tf->eax; switch(id) { case SYS_fork: syscall_fork(tf); break; case SYS_exec: syscall_exec(tf); break; case SYS_exit: syscall_exit(tf); break; case SYS_getpid: syscall_getpid(tf); break; case SYS_waitpid: syscall_waitpid(tf); break; case SYS_puts1: printk((char*)(tf->ebx)); printk(" %d\n", current->pid); break; case SYS_puts: syscall_puts(tf); break; case SYS_read_line: syscall_read_line(tf); break; case SYS_sleep: syscall_sleep(tf); break; case SYS_open: syscall_open(tf); break; case SYS_read: syscall_read(tf); break; case SYS_write: syscall_write(tf); break; case SYS_create: syscall_create(tf); break; case SYS_close: syscall_close(tf); break; case SYS_delete: syscall_delete(tf); break; case SYS_lseek: syscall_lseek(tf); break; case SYS_dup: syscall_dup(tf); break; case SYS_dup2: syscall_dup2(tf); break; case SYS_mkdir: syscall_mkdir(tf); break; case SYS_rmdir: syscall_rmdir(tf); break; case SYS_lsdir: syscall_lsdir(tf); break; case SYS_chdir: syscall_chdir(tf); break; //default: panic("Unknown system call type"); } }
int main(void) { char file[] = "[arkimedes]hej"; int handle = syscall_open((char const*) &file); char buffer[128]; char buffer2[128]; syscall_read(handle, &buffer, 4); syscall_write(handle, &buffer, 4); syscall_seek(handle, 0); syscall_read(handle, &buffer2, 11); syscall_write(FILEHANDLE_STDOUT, &buffer2, 11); syscall_close(handle); syscall_delete((char const*) &file); char file2[] = "[arkimedes]rasputin"; syscall_create((char const*) &file2, 11); char buffer3[] = "\ngorbatjov\n"; handle = syscall_open((char const*) &file2); syscall_write(handle, &buffer3, 11); int ret_code = syscall_seek(handle, 12); printf("\n%d\n", ret_code); syscall_seek(handle, 0); syscall_read(handle, &buffer3, 11); syscall_write(FILEHANDLE_STDOUT, &buffer3, 11); syscall_close(handle); char file3[] = "[arkimedes]putin"; syscall_create((char const*) &file3, 11); handle = syscall_open((char const*) &file3); char buffer4[] = "\ngorbad\n"; syscall_write(handle, &buffer4, 11); return 0; }
int cmd_touch(int argc, char** argv) { if (argc < 2) { printf("Usage: touch <file> [size]\n"); return 1; } int ret; int size = atoi(argv[2]); if ((ret=syscall_create(argv[1], size)) < 0) { printf("Could not create %s with initial size %d. Reason: %d\n", argv[1], size, ret); return 1; } return 0; }
int rpc_init() { rpc_functions = llist_create(); rpc_lastid = 0; if (syscall_create(SYSCALL_RPC_CREATE,rpc_function_create,4)==-1) return -1; if (syscall_create(SYSCALL_RPC_DESTROY,rpc_function_destroy,1)==-1) return -1; if (syscall_create(SYSCALL_RPC_GETINFO,rpc_function_getinfo,8)==-1) return -1; if (syscall_create(SYSCALL_RPC_CALL,rpc_function_call,5)==-1) return -1; if (syscall_create(SYSCALL_RPC_POLL,rpc_call_poll,4)==-1) return -1; if (syscall_create(SYSCALL_RPC_RETURN,rpc_call_return,3)==-1) return -1; if (syscall_create(SYSCALL_RPC_LIST,rpc_list,3)==-1) return -1; return 0; }
int cmd_cp(int argc, char** argv) { if (argc != 3 && argc != 4) { printf("Usage: cp <from> <to> [size]\n"); return 1; } int fd1, fd2; int size = argc == 4 ? atoi(argv[3]) : 0; if ((fd1=syscall_open(argv[1])) < 0) { printf("Could not open %s. Reason: %d\n", argv[1], fd1); return 1; } if ((fd2=syscall_create(argv[2], size)) < 0) { printf("Could not create %s with initial size %d. Reason: %d\n", argv[2], size, fd2); syscall_close(fd1); return 1; } if ((fd2=syscall_open(argv[2])) < 0) { printf("Could not open newly created file %s. Reason: %d\n", argv[2], fd2); syscall_close(fd1); return 1; } int ret, i, rd, wr; int totalread = 0, totalwritten = 0; char buffer[BUFFER_SIZE]; while ((rd = syscall_read(fd1, buffer, BUFFER_SIZE))) { i = 0; totalread += rd; clearline(); printf("Read %d bytes, wrote %d bytes.", totalread, totalwritten); while (i < rd) { if ((wr=syscall_write(fd2, buffer+i, rd-i)) <= 0) { printf("\nCall to syscall_write() failed. Reason: %d.\n", wr); if (wr == 0) { printf("Did you remember to make the destination file big enough?\n"); } ret=1; goto exit; } totalwritten += wr; i += wr; clearline(); printf("Read %d bytes, wrote %d bytes.", totalread, totalwritten); } } exit: printf("\n"); syscall_close(fd1); syscall_close(fd2); return ret; }
/* * get system call */ static void syscall_handler (struct intr_frame *f) { int *esp = (int *)syscall_user_to_kernel_vaddr(f->esp); switch(*esp) { case SYS_WRITE: syscall_write(f); break; case SYS_EXIT: syscall_exit(f); break; case SYS_HALT: syscall_halt(f); break; case SYS_EXEC: syscall_exec(f); break; case SYS_CREATE: syscall_create(f); break; case SYS_REMOVE: syscall_remove(f); break; case SYS_OPEN: syscall_open(f); break; case SYS_FILESIZE: syscall_filesize(f); break; case SYS_READ: syscall_read(f); break; case SYS_SEEK: syscall_seek(f); break; case SYS_TELL: syscall_tell(f); break; case SYS_CLOSE: syscall_close(f); break; case SYS_WAIT: syscall_wait(f); break; } }
int main() { char buff[20]; syscall_delete(file1); if (syscall_create(file1, 100) < 0) fail("Couldn't create file :(\n"); int fd = syscall_open(file1); if (fd < 0) fail("Couldn't open file :(\n"); printf("Wrote %d bytes\n", syscall_write(fd, "Teststring!\n", 11)); if (syscall_seek(fd, 0) < 0) fail("Couldn't seek :(\n"); printf("Read %d bytes\n", syscall_read(fd, buff, 20)); printf(buff); syscall_halt(); return 0; }
int signal_init() { if (syscall_create(SYSCALL_SIG_SETUP,signal_setup,1)==-1) return -1; if (syscall_create(SYSCALL_SIG_SEND,signal_send_syscall,2)==-1) return -1; return 0; }
/** * Initializes process management * @return -1=Success; 0=Failure */ int proc_init() { proc_all = llist_create(); proc_running = llist_create(); proc_sleeping = llist_create(); proc_nextpid = 1; proc_current = NULL; if (syscall_create(SYSCALL_PROC_GETPID,proc_getpid,0)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETUID,proc_getuid,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETGID,proc_getgid,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_SETUID,proc_setuid,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_SETGID,proc_setgid,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETPARENT,proc_getparent,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETCHILD,proc_getchild,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETNAME,proc_getname,3)==-1) return -1; if (syscall_create(SYSCALL_PROC_SETNAME,proc_setname,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETPIDBYNAME,proc_getpidbyname,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETVAR,proc_getvar,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_SETVAR,proc_setvar,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_EXIT,proc_exit,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_ABORT,proc_abort,0)==-1) return -1; if (syscall_create(SYSCALL_PROC_STOP,proc_stop,0)==-1) return -1; if (syscall_create(SYSCALL_PROC_CREATE,proc_create_syscall,4)==-1) return -1; if (syscall_create(SYSCALL_PROC_DESTROY,proc_destroy_syscall,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_MEMMAP,proc_memmap,6)==-1) return -1; if (syscall_create(SYSCALL_PROC_MEMALLOC,proc_memalloc,4)==-1) return -1; if (syscall_create(SYSCALL_PROC_MEMUNMAP,proc_memunmap,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_MEMFREE,proc_memfree,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_MEMGET,proc_memget,6)==-1) return -1; if (syscall_create(SYSCALL_PROC_MEMPAGELIST,proc_mempagelist,6)==-1) return -1; if (syscall_create(SYSCALL_PROC_SYSTEM,proc_system,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_JUMP,proc_jump,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_CREATESTACK,proc_createstack,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_GETSTACK,proc_getstack,1)==-1) return -1; if (syscall_create(SYSCALL_PROC_SETSTACK,proc_setstack,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_WAITPID,proc_waitpid,3)==-1) return -1; return 0; }
int ioport_init() { iopb_general = malloc(IOPORT_MAXNUM/sizeof(*iopb_general)); if (syscall_create(SYSCALL_IO_REG,ioport_reg,1)==-1) return -1; if (syscall_create(SYSCALL_IO_UNREG,ioport_unreg,1)==-1) return -1; return 0; }
static void syscall_handler (struct intr_frame *f) { int syscall_num; VALIDATE_AND_GET_ARG (f->esp, syscall_num, f); void *cur_sp = f->esp + sizeof (void *); /* store user program stack pointer to the thread's user_esp before changing to kernel mode */ struct thread *t = thread_current (); t->user_esp = f->esp; switch (syscall_num) { case SYS_HALT: syscall_halt (f, cur_sp); break; case SYS_EXIT: syscall_exit (f, cur_sp); break; case SYS_EXEC: syscall_exec (f, cur_sp); break; case SYS_WAIT: syscall_wait (f, cur_sp); break; case SYS_CREATE: syscall_create (f, cur_sp); break; case SYS_REMOVE: syscall_remove (f, cur_sp); break; case SYS_OPEN: syscall_open (f, cur_sp); break; case SYS_FILESIZE: syscall_filesize (f, cur_sp); break; case SYS_READ: syscall_read (f, cur_sp); break; case SYS_WRITE: syscall_write (f, cur_sp); break; case SYS_SEEK: syscall_seek (f, cur_sp); break; case SYS_TELL: syscall_tell (f, cur_sp); break; case SYS_CLOSE: syscall_close (f, cur_sp); break; case SYS_MMAP: syscall_mmap (f, cur_sp); break; case SYS_MUNMAP: syscall_unmmap (f, cur_sp); break; default : printf ("Invalid system call! #%d\n", syscall_num); syscall_thread_exit (f, -1); break; } }
static void syscall_handler (struct intr_frame *f) { /* Validate the first addr of the stack frame */ void *esp = utok_addr (f->esp, NULL); if (esp == NULL) { syscall_exit (-1); return; } enum SYSCALL_NUMBER call_number = *(enum SYSCALL_NUMBER *) esp; if (call_number < syscall_first_call || call_number > syscall_last_call) { syscall_exit (-1); return; } /* Buffer the arguments for validation */ int argc = syscall_argc[call_number]; uint32_t argbuf[3]; int i = 0; for (; i < argc; i++) { /* Validate each argument */ void *vaddr = uptr_valid((uint32_t *) f->esp + 1 + i, f->esp); if (vaddr == NULL) { syscall_exit (-1); return; } /* Translate the argument to kernel virtual (== physical) memory */ argbuf[i] = *(uint32_t *) vaddr; } int retval = 0; /* Switch based on call_number to delegate to corresponding syscall. Have not implemented several syscalls as of this project. Use validation methods to check user-provided arguments. */ switch (call_number) { case SYS_HALT: syscall_halt (); break; case SYS_EXIT: syscall_exit ((int) argbuf[0]); break; case SYS_EXEC: if (str_valid ((void *) argbuf[0], f->esp) == NULL) { syscall_exit (-1); return; } retval = syscall_exec ((char *) argbuf[0]); break; case SYS_WAIT: retval = syscall_wait ((int) argbuf[0]); break; case SYS_CREATE: if (str_valid ((char *) argbuf[0], f->esp) == NULL) { syscall_exit (-1); return; } retval = (int) syscall_create ((char *) argbuf[0], (unsigned) argbuf[1]); break; case SYS_REMOVE: if (!uptr_valid ((char *) argbuf[0], f->esp)) { syscall_exit (-1); return; } retval = (int) syscall_remove ((char *) argbuf[0]); break; case SYS_OPEN: if (str_valid ((char *) argbuf[0], f->esp) == NULL) { syscall_exit (-1); return; } retval = (int) syscall_open ((char *) argbuf[0]); break; case SYS_FILESIZE: retval = syscall_filesize ((int) argbuf[0]); break; case SYS_READ: if (buffer_valid ((void *) argbuf[1], f->esp, (unsigned) argbuf[2]) == NULL) { syscall_exit (-1); return; } retval = syscall_read ((int) argbuf[0], (void *) argbuf[1], (unsigned) argbuf[2]); break; case SYS_WRITE: if (buffer_valid ((void *) argbuf[1], f->esp, (unsigned) argbuf[2]) == NULL) { syscall_exit (-1); return; } retval = syscall_write ((int) argbuf[0], (void *) argbuf[1], (unsigned) argbuf[2]); break; case SYS_SEEK: syscall_seek ((int) argbuf[0], (unsigned) argbuf[1]); break; case SYS_TELL: retval = (int) syscall_tell ((int) argbuf[0]); break; case SYS_CLOSE: syscall_close ((int) argbuf[0]); break; #ifdef VM case SYS_MMAP: // addr will be checked internally inside mmap retval = (int) syscall_mmap ((int) argbuf[0], (void *) argbuf[1]); break; case SYS_MUNMAP: syscall_munmap ((int) argbuf[0]); break; #endif default: printf("unhandled system call!\n"); thread_exit(); } f->eax = retval; }
static void syscall_handler (struct intr_frame *f) { int nsyscall, argc, i; int *esp = (int *)f->esp; /* get argument pointer */ int *arg_int[3]; void **arg_ptr[3]; /* verify the argument pointer */ if (!IS_VALID(esp)) goto error_end; /* system call number */ nsyscall = *(esp++); /* number of arguments */ switch (nsyscall) { case SYS_HALT: argc = 0; break; case SYS_EXIT: case SYS_EXEC: case SYS_WAIT: case SYS_TELL: case SYS_CLOSE: case SYS_REMOVE: case SYS_OPEN: case SYS_FILESIZE: argc = 1; break; case SYS_CREATE: case SYS_SEEK: argc = 2; break; case SYS_READ: case SYS_WRITE: argc = 3; break; default: goto error_end; } /* verify the argument pointer */ for (i = 0; i < argc; i++) if (IS_VALID(esp + i)) { arg_int[i] = esp + i; arg_ptr[i] = (void**)(esp + i); } else { break; } if (i < argc) goto error_end; /* system call */ switch (nsyscall) { case SYS_HALT: shutdown_power_off(); break; case SYS_EXIT: syscall_exit(*arg_int[0]); break; case SYS_EXEC: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = process_execute(*arg_ptr[0]); lock_release (&lock_filesys); break; case SYS_WAIT: f->eax = process_wait(*arg_int[0]); break; case SYS_TELL: lock_acquire (&lock_filesys); f->eax = syscall_tell(*arg_int[0]); lock_release (&lock_filesys); break; case SYS_CLOSE: lock_acquire (&lock_filesys); process_file_close(*arg_int[0]); lock_release (&lock_filesys); break; case SYS_REMOVE: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_remove(*arg_ptr[0]); lock_release (&lock_filesys); break; case SYS_OPEN: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = process_file_open(*arg_ptr[0]); lock_release (&lock_filesys); break; case SYS_FILESIZE: lock_acquire (&lock_filesys); f->eax = syscall_filesize(*arg_int[0]); lock_release (&lock_filesys); break; case SYS_CREATE: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_create(*arg_ptr[0], *arg_int[1]); lock_release (&lock_filesys); break; case SYS_SEEK: lock_acquire (&lock_filesys); syscall_seek(*arg_int[0], *arg_int[1]); lock_release (&lock_filesys); break; case SYS_READ: if (!IS_VALID(*arg_ptr[1])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_read(*arg_int[0], *arg_ptr[1], *arg_int[2]); lock_release (&lock_filesys); break; case SYS_WRITE: if (!IS_VALID(*arg_ptr[1])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_write(*arg_int[0], *arg_ptr[1], *arg_int[2]); lock_release (&lock_filesys); break; default: printf ("Unknown syscall : %d\n", nsyscall); goto error_end; } return; error_end: thread_exit (); }
static void syscall_handler (struct intr_frame *f) { // XXX : EDIT WITH 'syscall.h' 'lib/user/syscall.c' 'lib/syscall-nr.h //printf ("system call!\n"); void *now = f->esp; // XXX : Check PTR Range, and bash to syscall_exit(-1); if(!is_valid_ptr(now)) syscall_exit(-1); int syscall_number = *(int *)(f->esp); int argc_size_table[22] = { // CHECK syscall-nr.h 0, // SYS_HALT (*) :0 1, // SYS_EXIT (*) :1 1, // SYS_EXEC (*) :2 1, // SYS_WAIT (*) :3 2, // SYS_CREATE :4 1, // SYS_REMOVE :5 1, // SYS_OPEN :6 1, // SYS_FILESIZE :7 3, // SYS_READ (*) :8 3, // SYS_WRITE (*):9 2, // SYS_SEEK :10 1, // SYS_TELL :11 1, // SYS_CLOSE :12 (proj 2-2) 2, // SYS_MMAP 1, // SYS_MUNMAP 1, // SYS_CHDIR 1, // SYS_MKDIR 2, // SYS_READDIR 1, // SYS_ISDIR 1, // SYS_INUMBER 1, // SYS_PIBONACCI 4 // SYS_SUM_OF_FOUR_INTEGERS }; int argc_size = argc_size_table[syscall_number]; //printf("SYSCALL %d SIZE %d\n", syscall_number, argc_size); void *argc[4] = {NULL,}; { int i; for(i = 0; i < argc_size; i++){ now += 4; // sizeof(void *); // IT WILL USE 4 Bytes. (ref:man38). argc[i] = now; // XXX : Check argument's ptr; if(!is_valid_ptr(argc[i])) syscall_exit(-1); // printf("%x\n", now); } } switch(syscall_number){ default: case -1: break; case 0: // SYS_HALT syscall_halt(); break; case 1: // SYS_EXIT syscall_exit(*(int *)argc[0]); break; case 2: // SYS_EXEC f->eax = syscall_exec(*(const char **)argc[0]); break; case 3: // SYS_WAIT //printf("CALLED SYS_WAIT!\n"); f->eax = syscall_wait(*(pid_t *)argc[0]); break; case 4: // SYS_CREATE f->eax = syscall_create(*(const char **)argc[0], *(unsigned *)argc[1]); break; case 5: // SYS_REMOVE f->eax = syscall_remove(*(const char **)argc[0]); break; case 6: // SYS_OPEN f->eax = syscall_open(*(const char **)argc[0]); break; case 7: // SYS_FILESIZE f->eax = syscall_filesize(*(int *)argc[0]); break; case 8: // SYS_READ f->eax = syscall_read( *(int *)argc[0], *(void **)argc[1], *(unsigned *)argc[2] ); break; case 9: // SYS_WRITE //printf("CALLED WRITE! %d %x %u\n", *(int *)argc[0], argc[1], *(unsigned *)argc[2]); f->eax = syscall_write( *(int *)argc[0], *(const void **)argc[1], *(unsigned *)argc[2] ); break; case 10: // SYS_SEEK syscall_seek(*(int *)argc[0], *(unsigned *)argc[1] ); break; case 11: // SYS_TELL f->eax = syscall_tell(*(int *)argc[0]); break; case 12: // SYS_CLOSE syscall_close(*(int *)argc[0]); break; case 20: // SYS_PIBONACCI f->eax = syscall_pibonacci(*(int *)argc[0]); break; case 21: // SYS_SUM_OF_FOUR_INTEGERS f->eax = syscall_sum_of_four_integers( *(int *)argc[0], *(int *)argc[1], *(int *)argc[2], *(int *)argc[3] ); break; // case *: } // printf("SYSCALL_RETURN: %d\n", f->eax); // thread_exit (); // XXX }
/** * Handle system calls. Interrupts are enabled when this function is * called. * * @param user_context The userland context (CPU registers as they * where when system call instruction was called in userland) */ void syscall_handle(context_t *user_context) { /* When a syscall is executed in userland, register a0 contains * the number of the syscall. Registers a1, a2 and a3 contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register v0. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ switch (A0) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_READ: { int filehandle = (int)A1; if (filehandle == FILEHANDLE_STDIN || filehandle == FILEHANDLE_STDOUT || filehandle == FILEHANDLE_STDERR) { V0 = io_read((int) A1, (void*) A2, (int) A3); } else { V0 = syscall_read((openfile_t)A1, (void *)A2, (int)A3); } } break; case SYSCALL_WRITE: { int filehandle = (int)A1; if (filehandle == FILEHANDLE_STDIN || filehandle == FILEHANDLE_STDOUT || filehandle == FILEHANDLE_STDERR) { V0 = io_write((int) A1, (void*) A2, (int) A3); } else { V0 = syscall_write((openfile_t)A1, (void *)A2, (int)A3); } } break; case SYSCALL_EXEC: V0 = syscall_exec((char*) A1); break; case SYSCALL_EXIT: syscall_exit((int) A1); break; case SYSCALL_JOIN: V0 = syscall_join((process_id_t) A1); break; case SYSCALL_OPEN: V0 = syscall_open((char *) A1); break; case SYSCALL_CLOSE: V0 = syscall_close((openfile_t) A1); break; case SYSCALL_SEEK: V0 = syscall_seek((openfile_t)A1, (int)A2); break; case SYSCALL_CREATE: V0 = syscall_create((const char *)A1, (int)A2); break; case SYSCALL_REMOVE: V0 = syscall_remove((const char *)A1); break; case SYSCALL_TELL: V0 = syscall_tell((openfile_t)A1); break; case SYSCALL_SEM_OPEN: V0 = (uint32_t) usr_sem_open((char*) A1, A2); break; case SYSCALL_SEM_PROCURE: V0 = usr_sem_p((usr_sem_t*) A1); break; case SYSCALL_SEM_VACATE: V0 = usr_sem_v((usr_sem_t*) A1); break; case SYSCALL_SEM_DESTROY: V0 = usr_sem_destroy((usr_sem_t*) A1); break; default: KERNEL_PANIC("Unhandled system call\n"); } /* Move to next instruction after system call */ user_context->pc += 4; }