summaryrefslogtreecommitdiffstats
path: root/userprog
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-06-19 01:44:56 +0200
committermanuel <manuel@mausz.at>2012-06-19 01:44:56 +0200
commite88a8c4c379d721e9901752d440a05295087da11 (patch)
treeb89070c525614267811a10b77a4dbc49ffd96b03 /userprog
parentd9e0c55d118d0a3923b440b7811f8d1d6db9e1d7 (diff)
downloadprogos-e88a8c4c379d721e9901752d440a05295087da11.tar.gz
progos-e88a8c4c379d721e9901752d440a05295087da11.tar.bz2
progos-e88a8c4c379d721e9901752d440a05295087da11.zip
implement page table and use it for lazy loading of segments
Diffstat (limited to 'userprog')
-rw-r--r--userprog/exception.c16
-rw-r--r--userprog/process.c35
-rw-r--r--userprog/process.h1
3 files changed, 28 insertions, 24 deletions
diff --git a/userprog/exception.c b/userprog/exception.c
index 17620ad..54621fa 100644
--- a/userprog/exception.c
+++ b/userprog/exception.c
@@ -5,6 +5,7 @@
5#include "threads/interrupt.h" 5#include "threads/interrupt.h"
6#include "threads/thread.h" 6#include "threads/thread.h"
7#include "threads/vaddr.h" 7#include "threads/vaddr.h"
8#include "vm/page.h"
8 9
9/* Number of page faults processed. */ 10/* Number of page faults processed. */
10static long long page_fault_cnt; 11static long long page_fault_cnt;
@@ -121,12 +122,13 @@ kill (struct intr_frame *f)
121 description of "Interrupt 14--Page Fault Exception (#PF)" in 122 description of "Interrupt 14--Page Fault Exception (#PF)" in
122 [IA32-v3a] section 5.15 "Exception and Interrupt Reference". */ 123 [IA32-v3a] section 5.15 "Exception and Interrupt Reference". */
123static void 124static void
124page_fault (struct intr_frame *f) 125page_fault (struct intr_frame *f)
125{ 126{
126 bool not_present; /* True: not-present page, false: writing r/o page. */ 127 bool not_present; /* True: not-present page, false: writing r/o page. */
127 bool write; /* True: access was write, false: access was read. */ 128 bool write; /* True: access was write, false: access was read. */
128 bool user; /* True: access by user, false: access by kernel. */ 129 bool user; /* True: access by user, false: access by kernel. */
129 void *fault_addr; /* Fault address. */ 130 void *fault_addr; /* Fault address. */
131 struct page_table_entry *pte;
130 132
131 /* Obtain faulting address, the virtual address that was 133 /* Obtain faulting address, the virtual address that was
132 accessed to cause the fault. It may point to code or to 134 accessed to cause the fault. It may point to code or to
@@ -153,6 +155,17 @@ page_fault (struct intr_frame *f)
153 body, adding code that brings in the page to 155 body, adding code that brings in the page to
154 which fault_addr refers. */ 156 which fault_addr refers. */
155 if (is_user_vaddr(fault_addr)) { 157 if (is_user_vaddr(fault_addr)) {
158 pte = page_table_fetch (&thread_current ()->page_table, pg_round_down (fault_addr));
159 if (pte != NULL)
160 page_load (pte);
161 else
162 {
163 printf ("Page fault %p\n", pte);
164 kill (f);
165 }
166
167 //TODO
168#if 0
156 if (! user) { 169 if (! user) {
157 /* syscall exception; set eax and eip */ 170 /* syscall exception; set eax and eip */
158 f->eip = (void*)f->eax; 171 f->eip = (void*)f->eax;
@@ -162,6 +175,7 @@ page_fault (struct intr_frame *f)
162 /* user process access violation */ 175 /* user process access violation */
163 thread_exit(); 176 thread_exit();
164 } 177 }
178#endif
165 } else { 179 } else {
166 printf ("Page fault at %p: %s error %s page in %s context.\n", 180 printf ("Page fault at %p: %s error %s page in %s context.\n",
167 fault_addr, 181 fault_addr,
diff --git a/userprog/process.c b/userprog/process.c
index c13c051..15883d9 100644
--- a/userprog/process.c
+++ b/userprog/process.c
@@ -18,6 +18,7 @@
18#include "threads/synch.h" 18#include "threads/synch.h"
19#include "threads/thread.h" 19#include "threads/thread.h"
20#include "threads/vaddr.h" 20#include "threads/vaddr.h"
21#include "vm/page.h"
21 22
22/* data structure to communicate with the thread initializing a new process */ 23/* data structure to communicate with the thread initializing a new process */
23struct start_aux_data { 24struct start_aux_data {
@@ -128,6 +129,8 @@ start_process (void *aux)
128 process->parent_tid = aux_data->parent_thread->tid; 129 process->parent_tid = aux_data->parent_thread->tid;
129 thread->process = process; 130 thread->process = process;
130 131
132 page_table_init (&thread->page_table);
133
131 /* Initialize interrupt frame and load executable. */ 134 /* Initialize interrupt frame and load executable. */
132 memset (&if_, 0, sizeof if_); 135 memset (&if_, 0, sizeof if_);
133 if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG; 136 if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
@@ -251,6 +254,8 @@ process_exit (void)
251 pagedir_destroy (pd); 254 pagedir_destroy (pd);
252 } 255 }
253 256
257 page_table_free (&thread->page_table);
258
254 /* Destroy the process structure if the parent is not alive 259 /* Destroy the process structure if the parent is not alive
255 * any more. Atomic test and set would be sufficient here. 260 * any more. Atomic test and set would be sufficient here.
256 */ 261 */
@@ -478,8 +483,6 @@ load (const char *args, void (**eip) (void), void **esp)
478 483
479/* load() helpers. */ 484/* load() helpers. */
480 485
481static bool install_page (void *upage, void *kpage, bool writable);
482
483/* Checks whether PHDR describes a valid, loadable segment in 486/* Checks whether PHDR describes a valid, loadable segment in
484 FILE and returns true if so, false otherwise. */ 487 FILE and returns true if so, false otherwise. */
485static bool 488static bool
@@ -556,29 +559,15 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
556 size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE; 559 size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
557 size_t page_zero_bytes = PGSIZE - page_read_bytes; 560 size_t page_zero_bytes = PGSIZE - page_read_bytes;
558 561
559 /* Get a page of memory. */ 562 /* add segment to page table for on demand loading */
560 uint8_t *kpage = palloc_get_page (PAL_USER); 563 if (!page_table_insert_segment (file, ofs, upage, page_read_bytes,
561 if (kpage == NULL) 564 page_zero_bytes, writable))
562 return false;
563
564 /* Load this page. */
565 if (file_read (file, kpage, page_read_bytes) != (int) page_read_bytes)
566 {
567 palloc_free_page (kpage);
568 return false; 565 return false;
569 }
570 memset (kpage + page_read_bytes, 0, page_zero_bytes);
571
572 /* Add the page to the process's address space. */
573 if (!install_page (upage, kpage, writable))
574 {
575 palloc_free_page (kpage);
576 return false;
577 }
578 566
579 /* Advance. */ 567 /* Advance. */
580 read_bytes -= page_read_bytes; 568 read_bytes -= page_read_bytes;
581 zero_bytes -= page_zero_bytes; 569 zero_bytes -= page_zero_bytes;
570 ofs += page_read_bytes;
582 upage += PGSIZE; 571 upage += PGSIZE;
583 } 572 }
584 return true; 573 return true;
@@ -602,7 +591,7 @@ setup_stack (uint32_t **esp, const char *args)
602 if (kpage == NULL) 591 if (kpage == NULL)
603 return false; 592 return false;
604 593
605 if (! install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true)) { 594 if (! process_install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true)) {
606 palloc_free_page (kpage); 595 palloc_free_page (kpage);
607 return false; 596 return false;
608 } 597 }
@@ -706,8 +695,8 @@ setup_stack (uint32_t **esp, const char *args)
706 with palloc_get_page(). 695 with palloc_get_page().
707 Returns true on success, false if UPAGE is already mapped or 696 Returns true on success, false if UPAGE is already mapped or
708 if memory allocation fails. */ 697 if memory allocation fails. */
709static bool 698bool
710install_page (void *upage, void *kpage, bool writable) 699process_install_page (void *upage, void *kpage, bool writable)
711{ 700{
712 struct thread *t = thread_current (); 701 struct thread *t = thread_current ();
713 702
diff --git a/userprog/process.h b/userprog/process.h
index 1609801..b7bca5d 100644
--- a/userprog/process.h
+++ b/userprog/process.h
@@ -37,6 +37,7 @@ tid_t process_execute (const char *file_name);
37int process_wait (tid_t); 37int process_wait (tid_t);
38void process_exit (void); 38void process_exit (void);
39void process_activate (void); 39void process_activate (void);
40bool process_install_page (void *upage, void *kpage, bool writable);
40 41
41int process_open_file(const char* fname); 42int process_open_file(const char* fname);
42struct file* process_get_file(int fd); 43struct file* process_get_file(int fd);