diff --git a/src/threads/thread.c b/src/threads/thread.c index 052302f8d417bbcce955ae4216fc297d956316a6..1551f6147328aa26f4859e4efb5a10b3d6d31324 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -188,7 +188,9 @@ thread_create (const char *name, int priority, return TID_ERROR; /* Initialize thread. */ + //printf("Starting init_thread\n"); init_thread (t, name, priority); + //printf("Finished init_thread\n"); tid = t->tid = allocate_tid (); /* Stack frame for kernel_thread(). */ diff --git a/src/userprog/process.c b/src/userprog/process.c index d51339a4aff8ec7aae340ae87035ef64358853fd..a4fbbee042cbc7b47e314c1cecc1a586676f08f5 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -29,6 +29,8 @@ tid_t process_execute (const char *file_name) { char *fn_copy; + char *process_name; + char *save_ptr; tid_t tid; /* Make a copy of FILE_NAME. @@ -38,9 +40,13 @@ process_execute (const char *file_name) return TID_ERROR; strlcpy (fn_copy, file_name, PGSIZE); - /* Create a new thread to execute FILE_NAME. */ - tid = thread_create (file_name, PRI_DEFAULT, start_process, fn_copy); + // Extract process name from file + process_name = fn_copy + strlen(fn_copy)+1; + strlcpy(process_name, file_name, strlen(file_name)+1); + process_name = strtok_r(process_name, " ", &save_ptr); + /* Create a new thread to execute FILE_NAME. */ + tid = thread_create (process_name, PRI_DEFAULT, start_process, fn_copy); if (tid == TID_ERROR) palloc_free_page (fn_copy); return tid; @@ -61,6 +67,7 @@ start_process (void *file_name_) if_.cs = SEL_UCSEG; if_.eflags = FLAG_IF | FLAG_MBS; + printf("Starting Load\n"); success = load (file_name, &if_.eip, &if_.esp); /* If load failed, quit. */ @@ -103,6 +110,8 @@ process_exit (void) struct thread *cur = thread_current (); uint32_t *pd; + printf("%s:exit_code(%d)\n",cur->name); + /* Destroy the current process's page directory and switch back to the kernel-only page directory. */ pd = cur->pagedir; @@ -200,7 +209,7 @@ struct Elf32_Phdr #define PF_W 2 /* Writable. */ #define PF_R 4 /* Readable. */ -static bool setup_stack (void **esp); +static bool setup_stack (void **esp, char *file_name); static bool validate_segment (const struct Elf32_Phdr *, struct file *); static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, @@ -227,7 +236,14 @@ load (const char *file_name, void (**eip) (void), void **esp) process_activate (); /* Open executable file. */ - file = filesys_open (file_name); + char * fn_cp = malloc(strlen(file_name)+1); + strlcpy(fn_cp, file_name, strlen(file_name)+1); + char * save_ptr; + fn_cp = strtok_r(fn_cp," ", &save_ptr); + + printf("Looking for file: %s\n",fn_cp); + file = filesys_open (fn_cp); + free(fn_cp); if (file == NULL) { @@ -308,7 +324,7 @@ load (const char *file_name, void (**eip) (void), void **esp) } /* Set up stack. */ - if (!setup_stack (esp)) + if (!setup_stack (esp, file_name)) goto done; /* Start address. */ @@ -430,14 +446,51 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage, return true; } +// Used in setupstack to reverse tokens +void reverse(char* begin, char* end) +{ + char temp; + while (begin < end) { + temp = *begin; + *begin++ = *end; + *end-- = temp; + } +} + +// Function to reverse words*/ +void reverseWords(char* s) +{ + char* word_begin = s; + + // Word boundary + char* temp = s; + + // Reversing individual words as + // explained in the first step + while (*temp) { + temp++; + if (*temp == '\0') { + reverse(word_begin, temp - 1); + } + else if (*temp == ' ') { + reverse(word_begin, temp - 1); + word_begin = temp + 1; + } + } + + // Reverse the entire string + reverse(s, temp - 1); +} + /* Create a minimal stack by mapping a zeroed page at the top of user virtual memory. */ static bool -setup_stack (void **esp) +setup_stack (void **esp, char *file_name) { uint8_t *kpage; bool success = false; + printf("Setting up stack\n"); kpage = palloc_get_page (PAL_USER | PAL_ZERO); if (kpage != NULL) { @@ -447,6 +500,75 @@ setup_stack (void **esp) } else palloc_free_page (kpage); } + + char *token; + char *save_ptr; + + // Initial size of 2, will be incremented as needed + int argv_size = 2; + int argc = 0; + char ** argv = malloc(argv_size * sizeof(char *)); + + // Convert char* to char array + char str[100]; + for (int j=0; j<strlen(file_name)+1; j++) + { + str[j] = file_name[j]; + } + + // Reverse the filename such that arguments are first + reverseWords(str); + char *rev; + rev=str; + + for (token = strtok_r(rev, " ", &save_ptr); token!=NULL; + token = strtok_r(NULL, " ", &save_ptr)) + { + *esp -= strlen(token) + 1; + argv[argc] = *esp; + argc++; + + if (argc >= 64) + { + free(argv); + return false; + } + + if (argc >= argv_size) + { + argv_size *= 2; + argv = realloc(argv, argv_size* sizeof(char*)); + } + memcpy(*esp,token,strlen(token)+1); + + //hex_dump(PHYS_BASE, *esp, PHYS_BASE-(*esp),true); + } + + argv[argc] = 0; + + // Load + int i = 0; + for (i=argc; i>=0; i--) + { + *esp -= sizeof(char*); + memcpy(*esp, &argv[i], sizeof(char*)); + } + + //Push argv address to stack + token = *esp; + *esp-=sizeof(char**); + memcpy(*esp,&token,sizeof(char**)); + + // Push argc to stack + *esp -= sizeof(int); + memcpy(*esp, &argc, sizeof(int)); + + // Push NULL Pointer + *esp -= sizeof(void*); + memcpy(*esp, &argv[argc], sizeof(void*)); + free(argv); + + hex_dump(PHYS_BASE, *esp, PHYS_BASE-(*esp),true); return success; } diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 04635159d30520fa11296dc922e622f2ad2553d5..08e82c9e8b11053771fc565e7464ba1239bacf89 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -3,8 +3,11 @@ #include <syscall-nr.h> #include "threads/interrupt.h" #include "threads/thread.h" +#include "devices/shutdown.h" static void syscall_handler (struct intr_frame *); +void syscall_exit(int status); +void syscall_halt(void); void syscall_init (void) @@ -14,8 +17,39 @@ syscall_init (void) static void -syscall_handler (struct intr_frame *f UNUSED) +syscall_handler (struct intr_frame *f) { printf ("system call!\n"); + int sys_code = *(int*)f->esp; + + printf("System call number: %d\n", sys_code); + + switch(sys_code) { + + case SYS_EXIT: + printf("Running SYS_EXIT\n"); + //syscall_exit(); + break; + + case SYS_HALT: + printf("Running SYS_HALT\n"); + syscall_halt(); + break; + + default: + printf("Unknown Syscall number\n"); + break; + } + thread_exit (); } + + +/* System Call Implementations*/ + +void syscall_exit(int status); + +void syscall_halt() +{ + shutdown_power_off(); +}