X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fuserprog%2Faddrspace.c;h=1170f16ab92a7f61f1a93ad381ea49ff38208e63;hb=a051c001c942a1f9cce57b1beec79794f9c7089f;hp=454eef1fa286e8612e7a7bd2da9bab5839098c97;hpb=4105c31b051ba59ce5487fa1ae0ba2f9eef58a39;p=pintos-anon diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index 454eef1..1170f16 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -6,9 +6,10 @@ #include "init.h" #include "lib.h" #include "mmu.h" -#include "malloc.h" #include "paging.h" #include "palloc.h" +#include "thread.h" +#include "tss.h" /* We load ELF binaries. The following definitions are taken from the ELF specification more-or-less verbatim. */ @@ -80,12 +81,12 @@ struct Elf32_Phdr } while (0) static bool -install_page (struct addrspace *as, void *upage, void *kpage) +install_page (struct thread *t, void *upage, void *kpage) { /* Verify that there's not already a page at that virtual address, then map our page there. */ - if (pagedir_get_page (as->pagedir, upage) == NULL - && pagedir_set_page (as->pagedir, upage, kpage, true)) + if (pagedir_get_page (t->pagedir, upage) == NULL + && pagedir_set_page (t->pagedir, upage, kpage, true)) return true; else { @@ -95,14 +96,14 @@ install_page (struct addrspace *as, void *upage, void *kpage) } static bool -load_segment (struct addrspace *as, struct file *file, +load_segment (struct thread *t, struct file *file, const struct Elf32_Phdr *phdr) { void *start, *end; uint8_t *upage; off_t filesz_left; - ASSERT (as != NULL); + ASSERT (t != NULL); ASSERT (file != NULL); ASSERT (phdr != NULL); ASSERT (phdr->p_type == PT_LOAD); @@ -148,7 +149,7 @@ load_segment (struct addrspace *as, struct file *file, memset (kpage + read_bytes, 0, zero_bytes); filesz_left -= read_bytes; - if (!install_page (as, upage, kpage)) + if (!install_page (t, upage, kpage)) return false; } @@ -156,7 +157,7 @@ load_segment (struct addrspace *as, struct file *file, } static bool -setup_stack (struct addrspace *as) +setup_stack (struct thread *t) { uint8_t *kpage = palloc_get (PAL_ZERO); if (kpage == NULL) @@ -165,11 +166,11 @@ setup_stack (struct addrspace *as) return false; } - return install_page (as, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage); + return install_page (t, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage); } bool -addrspace_load (struct addrspace *as, const char *filename, +addrspace_load (struct thread *t, const char *filename, void (**start) (void)) { struct Elf32_Ehdr ehdr; @@ -179,8 +180,12 @@ addrspace_load (struct addrspace *as, const char *filename, bool success = false; int i; - as->pagedir = pagedir_create (); + /* Allocate page directory. */ + t->pagedir = pagedir_create (); + if (t->pagedir == NULL) + LOAD_ERROR (("page directory allocation failed")); + /* Open executable file. */ file_open = filesys_open (filename, &file); if (!file_open) LOAD_ERROR (("open failed")); @@ -230,14 +235,14 @@ addrspace_load (struct addrspace *as, const char *filename, printk ("unknown ELF segment type %08x\n", phdr.p_type); break; case PT_LOAD: - if (!load_segment (as, &file, &phdr)) + if (!load_segment (t, &file, &phdr)) goto error; break; } } /* Set up stack. */ - if (!setup_stack (as)) + if (!setup_stack (t)) goto error; /* Start address. */ @@ -249,23 +254,26 @@ addrspace_load (struct addrspace *as, const char *filename, if (file_open) file_close (&file); if (!success) - addrspace_destroy (as); + addrspace_destroy (t); return success; } void -addrspace_destroy (struct addrspace *as) +addrspace_destroy (struct thread *t) { - if (as != NULL && as->pagedir != NULL) - pagedir_destroy (as->pagedir); + if (t->pagedir != NULL) + { + pagedir_destroy (t->pagedir); + t->pagedir = NULL; + } } void -addrspace_activate (struct addrspace *as) +addrspace_activate (struct thread *t) { - ASSERT (as != NULL); + ASSERT (t != NULL); - if (as->pagedir != NULL) - pagedir_activate (as->pagedir); - tss->esp0 = (uint32_t) pg_round_down (as) + PGSIZE; + if (t->pagedir != NULL) + pagedir_activate (t->pagedir); + tss_set_esp0 ((uint8_t *) t + PGSIZE); }