Make userspace actually work.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 27 Aug 2004 07:18:38 +0000 (07:18 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 27 Aug 2004 07:18:38 +0000 (07:18 +0000)
13 files changed:
src/devices/kbd.c
src/devices/timer.c
src/threads/init.c
src/threads/init.h
src/threads/interrupt.c
src/threads/interrupt.h
src/threads/loader.S
src/threads/paging.c
src/threads/switch.S
src/threads/switch.h
src/threads/thread.c
src/threads/thread.h
src/userprog/addrspace.c

index e5d3d820c3f17d58cb8fdb2ea6a511f4129874e1..ed52cfab82872ea9b05eaf0924f1a99a2ce3b8b0 100644 (file)
@@ -14,5 +14,5 @@ irq21_keyboard (struct intr_frame *args UNUSED)
 void
 kbd_init (void) 
 {
-  intr_register (0x21, 0, IF_OFF, irq21_keyboard);
+  intr_register (0x21, 0, IF_OFF, irq21_keyboard, "8042 Keyboard");
 }
index 4adca8989cf1192612a0c009d187f999c2d5e25a..4b8dd2a47865b8828b9a6f326d4a7f03d970e222 100644 (file)
@@ -3,6 +3,10 @@
 #include "interrupt.h"
 #include "io.h"
   
+#if TIMER_FREQ < 19
+#error 8254 timer requires TIMER_FREQ >= 19
+#endif
+
 static volatile uint64_t ticks;
 
 static void
@@ -26,7 +30,7 @@ timer_init (void)
   outb (0x40, count & 0xff);
   outb (0x40, count >> 8);
 
-  intr_register (0x20, 0, IF_OFF, irq20_timer);
+  intr_register (0x20, 0, IF_OFF, irq20_timer, "8254 Timer");
 }
 
 uint64_t
index 234c41eb249c64def96f49d22d6775c3d3ee52ba..f2476124da7d2a0a7a597d312da5715cb1985943 100644 (file)
@@ -32,7 +32,7 @@ void power_off (void);
 static void
 main_thread (void *aux UNUSED) 
 {
-  printk ("execute=%d\n", (int) thread_execute ("a.out"));
+  thread_execute ("a.out");
 }
 
 int
@@ -71,7 +71,6 @@ main (void)
 
 #ifdef FILESYS
   filesys_init (false);
-  filesys_self_test ();
 #endif
 
   thread_init ();
index b4820796255e054e649eb6352b1aa6c6e089719e..2c73fd96179f1c640c2f09c166c537b1ecfd7673 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <stddef.h>
 
+struct tss *tss;
+
 extern size_t kernel_pages;
 extern size_t ram_pages;
 
index 6250f817fec9010e9e23dae3ed5849d5f4ac587a..90587756988a71b0e4c2125e6dd4898f3e9e7073 100644 (file)
@@ -1,4 +1,5 @@
 #include "interrupt.h"
+#include <inttypes.h>
 #include <stdint.h>
 #include "intr-stubs.h"
 #include "debug.h"
@@ -93,15 +94,26 @@ pic_eoi (void)
   outb (0x20, 0x20);
 }
 \f
-uint64_t idt[256];
+#define INTR_CNT 256
 
-intr_handler_func *intr_handlers[256];
+static uint64_t idt[INTR_CNT];
+static intr_handler_func *intr_handlers[INTR_CNT];
+static const char *intr_names[INTR_CNT];
 
 void intr_handler (struct intr_frame *args);
 
 bool intr_in_progress;
 bool yield_on_return;
 
+const char *
+intr_name (int vec) 
+{
+  if (vec < 0 || vec >= INTR_CNT || intr_names[vec] == NULL)
+    return "unknown";
+  else
+    return intr_names[vec];
+}
+
 void
 intr_handler (struct intr_frame *args) 
 {
@@ -128,10 +140,7 @@ intr_handler (struct intr_frame *args)
     }
 
   if (yield_on_return) 
-    {
-      printk (".");
-      thread_yield (); 
-    }
+    thread_yield (); 
 }
 
 bool
@@ -146,29 +155,8 @@ intr_yield_on_return (void)
   yield_on_return = true;
 }
 
-/* Handles interrupts we don't know about. */
-intr_handler_func intr_unexpected;
-
-/* Handlers for CPU exceptions. */
-intr_handler_func excp00_divide_error;
-intr_handler_func excp01_debug;
-intr_handler_func excp02_nmi;
-intr_handler_func excp03_breakpoint;
-intr_handler_func excp04_overflow;
-intr_handler_func excp05_bound;
-intr_handler_func excp06_invalid_opcode;
-intr_handler_func excp07_device_not_available;
-intr_handler_func excp08_double_fault;
-intr_handler_func excp09_coprocessor_overrun;
-intr_handler_func excp0a_invalid_tss;
-intr_handler_func excp0b_segment_not_present;
-intr_handler_func excp0c_stack_fault;
-intr_handler_func excp0d_general_protection;
-intr_handler_func excp0e_page_fault;
-intr_handler_func excp10_fp_error;
-intr_handler_func excp11_alignment;
-intr_handler_func excp12_machine_check;
-intr_handler_func excp13_simd_error;
+intr_handler_func intr_panic NO_RETURN;
+intr_handler_func intr_kill NO_RETURN;
 
 static uint64_t
 make_intr_gate (void (*target) (void),
@@ -200,13 +188,15 @@ make_trap_gate (void (*target) (void),
    enabled. */
 void
 intr_register (uint8_t vec_no, int dpl, enum if_level level,
-               intr_handler_func *handler) 
+               intr_handler_func *handler,
+               const char *name) 
 {
   if (level == IF_ON)
     idt[vec_no] = make_trap_gate (intr_stubs[vec_no], dpl);
   else
     idt[vec_no] = make_intr_gate (intr_stubs[vec_no], dpl);
   intr_handlers[vec_no] = handler;
+  intr_names[vec_no] = name;
 }
 
 void
@@ -219,46 +209,81 @@ intr_init (void)
 
   /* Install default handlers. */
   for (i = 0; i < 256; i++)
-    intr_register (i, 0, IF_OFF, intr_unexpected);
+    intr_register (i, 0, IF_OFF, intr_panic, NULL);
 
   /* Most exceptions require ring 0.
-     Exceptions 3, 4, and 5 can be caused by ring 3 directly.
-
-     Most exceptions can be handled with interrupts turned on.
+     Exceptions 3, 4, and 5 can be caused by ring 3 directly. */
+  intr_register (0, 0, IF_ON, intr_kill, "#DE Divide Error");
+  intr_register (1, 0, IF_ON, intr_kill, "#DB Debug Exception");
+  intr_register (2, 0, IF_ON, intr_panic, "NMI Interrupt");
+  intr_register (3, 3, IF_ON, intr_kill, "#BP Breakpoint Exception");
+  intr_register (4, 3, IF_ON, intr_kill, "#OF Overflow Exception");
+  intr_register (5, 3, IF_ON, intr_kill, "#BR BOUND Range Exceeded Exception");
+  intr_register (6, 0, IF_ON, intr_kill, "#UD Invalid Opcode Exception");
+  intr_register (7, 0, IF_ON, intr_kill, "#NM Device Not Available Exception");
+  intr_register (8, 0, IF_ON, intr_panic, "#DF Double Fault Exception");
+  intr_register (9, 0, IF_ON, intr_panic, "Coprocessor Segment Overrun");
+  intr_register (10, 0, IF_ON, intr_panic, "#TS Invalid TSS Exception");
+  intr_register (11, 0, IF_ON, intr_kill, "#NP Segment Not Present");
+  intr_register (12, 0, IF_ON, intr_kill, "#SS Stack Fault Exception");
+  intr_register (13, 0, IF_ON, intr_kill, "#GP General Protection Exception");
+  intr_register (16, 0, IF_ON, intr_kill, "#MF x87 FPU Floating-Point Error");
+  intr_register (17, 0, IF_ON, intr_panic, "#AC Alignment Check Exception");
+  intr_register (18, 0, IF_ON, intr_panic, "#MC Machine-Check Exception");
+  intr_register (19, 0, IF_ON, intr_kill, "#XF SIMD Floating-Point Exception");
+
+  /* Most exceptions can be handled with interrupts turned on.
      We need to disable interrupts for page faults because the
-     fault address is stored in CR2 and needs to be preserved.
-  */
-#if 0
-  intr_register (0x00, 0, IF_ON, excp00_divide_error);
-  intr_register (0x01, 0, IF_ON, excp01_debug);
-  intr_register (0x02, 0, IF_ON, excp02_nmi);
-  intr_register (0x03, 3, IF_ON, excp03_breakpoint);
-  intr_register (0x04, 3, IF_ON, excp04_overflow);
-  intr_register (0x05, 3, IF_ON, excp05_bound);
-  intr_register (0x06, 0, IF_ON, excp06_invalid_opcode);
-  intr_register (0x07, 0, IF_ON, excp07_device_not_available);
-  intr_register (0x08, 0, IF_ON, excp08_double_fault);
-  intr_register (0x09, 0, IF_ON, excp09_coprocessor_overrun);
-  intr_register (0x0a, 0, IF_ON, excp0a_invalid_tss);
-  intr_register (0x0b, 0, IF_ON, excp0b_segment_not_present);
-  intr_register (0x0c, 0, IF_ON, excp0c_stack_fault);
-  intr_register (0x0d, 0, IF_ON, excp0d_general_protection);
-  intr_register (0x0e, 0, IF_OFF, excp0e_page_fault);
-  intr_register (0x10, 0, IF_ON, excp10_fp_error);
-  intr_register (0x11, 0, IF_ON, excp11_alignment);
-  intr_register (0x12, 0, IF_ON, excp12_machine_check);
-  intr_register (0x13, 0, IF_ON, excp13_simd_error);
-#endif
+     fault address is stored in CR2 and needs to be preserved. */
+  intr_register (14, 0, IF_OFF, intr_kill, "#PF Page-Fault Exception");
 
   idtr_operand = make_dtr_operand (sizeof idt - 1, idt);
   asm volatile ("lidt %0" :: "m" (idtr_operand));
 }
 
-void
-intr_unexpected (struct intr_frame *regs)
+static void
+dump_intr_frame (struct intr_frame *f) 
 {
-  uint32_t cr2;
+  uint32_t cr2, ss;
   asm ("movl %%cr2, %0" : "=r" (cr2));
-  panic ("Unexpected interrupt 0x%02x, error code %08x, cr2=%08x, eip=%p",
-         regs->vec_no, regs->error_code, cr2, (void *) regs->eip);
+  asm ("movl %%ss, %0" : "=r" (ss));
+
+  printk ("Interrupt %#04x (%s) at eip=%p\n",
+          f->vec_no, intr_name (f->vec_no), f->eip);
+  printk (" cr2=%08"PRIx32" error=%08"PRIx32"\n", cr2, f->error_code);
+  printk (" eax=%08"PRIx32" ebx=%08"PRIx32" ecx=%08"PRIx32" edx=%08"PRIx32"\n",
+          f->eax, f->ebx, f->ecx, f->edx);
+  printk (" esi=%08"PRIx32" edi=%08"PRIx32" esp=%08"PRIx32" ebp=%08"PRIx32"\n",
+          f->esi, f->edi, (uint32_t) f->esp, f->ebp);
+  printk (" cs=%04"PRIx16" ds=%04"PRIx16" es=%04"PRIx16" ss=%04"PRIx16"\n",
+          f->cs, f->ds, f->es, f->cs != SEL_KCSEG ? f->ss : ss);
 }
+
+void
+intr_panic (struct intr_frame *regs) 
+{
+  dump_intr_frame (regs);
+  panic ("Panic!");
+}
+
+void
+intr_kill (struct intr_frame *f) 
+{
+  switch (f->cs)
+    {
+    case SEL_UCSEG:
+      printk ("[%p] Interrupt %#04x (%s), killing process.\n",
+              thread_current (), f->vec_no, intr_name (f->vec_no));
+      thread_exit (); 
+
+    default:
+      panic ("Interrupt %#04x (%s) in unknown segment %04x",
+             f->vec_no, intr_name (f->vec_no), f->cs);
+
+    case SEL_KCSEG:
+      printk ("intr_kill -> panic %d\n", f->vec_no);
+      intr_panic (f);
+    }
+}
+
+
index a40276a5852340ef5dd54f969c9346ba5dcca281..5fa67b213062ede957930919958768ee4db8702c 100644 (file)
@@ -44,8 +44,11 @@ struct intr_frame
 typedef void intr_handler_func (struct intr_frame *);
 
 void intr_init (void);
-void intr_register (uint8_t vec, int dpl, enum if_level, intr_handler_func *);
+void intr_register (uint8_t vec, int dpl, enum if_level, intr_handler_func *,
+                    const char *name);
 bool intr_context (void);
 void intr_yield_on_return (void);
 
+const char *intr_name (int vec);
+
 #endif /* interrupt.h */
index 18086ede8993c44805e6ebe742c64bd2cdc5c524..c60e8dd6bd3347551b30f727617b113b88494388 100644 (file)
@@ -153,6 +153,13 @@ read_sector:
        movl %eax, %cr0
        jmp 1f
 1:
+
+##### Turn on EM bit in CR0, forcing most floating-point instructions
+##### to trap.  We don't support floating-point or MMX.
+
+       movl %cr0, %eax
+       orl $CR0_EM, %eax
+       movl %eax, %cr0
        
 ##### Jump to kernel entry point.
 
index 2fa549cd9424c73a0abc133b506aabf0cc13fe20..d54fef8e021db91d046f69bb74e2443b11a22bf9 100644 (file)
@@ -8,29 +8,22 @@
 
 static uint32_t *base_page_dir;
 
-static uint32_t
-make_pde (uint32_t *pagetab) 
-{
-  ASSERT (pg_ofs (pagetab) == 0);
-  
-  return vtop (pagetab) | PG_U | PG_P | PG_W;
+static uint32_t make_pde (uint32_t *pt) {
+  ASSERT (pg_ofs (pt) == 0);
+  return vtop (pt) | PG_U | PG_P | PG_W;
 }
 
-static uint32_t
-make_pte (uint32_t *page, bool writable)
-{
-  uint32_t entry;
-
+static uint32_t make_kernel_pte (uint32_t *page, bool writable) {
   ASSERT (pg_ofs (page) == 0);
-  
-  entry = vtop (page) | PG_U | PG_P;
-  if (writable)
-    entry |= PG_W;
-  return entry;
+  return vtop (page) | PG_P | (writable ? PG_W : 0);
+}
+
+static uint32_t make_user_pte (uint32_t *page, bool writable) {
+  return make_kernel_pte (page, writable) | PG_U;
 }
 
 static uint32_t *
-pde_get_pagetab (uint32_t pde) 
+pde_get_pt (uint32_t pde) 
 {
   ASSERT (pde & PG_P);
 
@@ -74,7 +67,7 @@ paging_init (void)
           pd[pde_idx] = make_pde (pt);
         }
 
-      pt[pte_idx] = make_pte (vaddr, true);
+      pt[pte_idx] = make_kernel_pte (vaddr, true);
     }
 
   pagedir_activate (pd);
@@ -100,49 +93,49 @@ pagedir_destroy (uint32_t *pd)
 }
 
 static uint32_t *
-lookup_page (uint32_t *pagedir, void *upage, bool create)
+lookup_page (uint32_t *pd, void *upage, bool create)
 {
-  uint32_t *pagetab;
+  uint32_t *pt;
   uint32_t *pde;
 
-  ASSERT (pagedir != NULL);
+  ASSERT (pd != NULL);
   ASSERT (pg_ofs (upage) == 0);
   ASSERT (upage < PHYS_BASE);
 
   /* Check for a page table for UPAGE.
      If one is missing, create one if requested. */
-  pde = pagedir + pd_no (upage);
+  pde = pd + pd_no (upage);
   if (*pde == 0) 
     {
       if (create)
         {
-          pagetab = palloc_get (PAL_ZERO);
-          if (pagetab == NULL) 
+          pt = palloc_get (PAL_ZERO);
+          if (pt == NULL) 
             return NULL; 
       
-          *pde = make_pde (pagetab);
+          *pde = make_pde (pt);
         }
       else
         return NULL;
     }
 
   /* Return the page table entry. */
-  pagetab = pde_get_pagetab (*pde);
-  return &pagetab[pt_no (upage)];
+  pt = pde_get_pt (*pde);
+  return &pt[pt_no (upage)];
 }
 
 bool
-pagedir_set_page (uint32_t *pagedir, void *upage, void *kpage,
+pagedir_set_page (uint32_t *pd, void *upage, void *kpage,
                   bool writable) 
 {
   uint32_t *pte;
 
   ASSERT (pg_ofs (kpage) == 0);
 
-  pte = lookup_page (pagedir, upage, true);
+  pte = lookup_page (pd, upage, true);
   if (pte != NULL) 
     {
-      *pte = make_pte (kpage, writable);
+      *pte = make_user_pte (kpage, writable);
       return true;
     }
   else
@@ -150,16 +143,16 @@ pagedir_set_page (uint32_t *pagedir, void *upage, void *kpage,
 }
 
 void *
-pagedir_get_page (uint32_t *pagedir, void *upage) 
+pagedir_get_page (uint32_t *pd, void *upage) 
 {
-  uint32_t *pte = lookup_page (pagedir, upage, false);
+  uint32_t *pte = lookup_page (pd, upage, false);
   return pte != NULL && *pte != 0 ? pte_get_page (*pte) : NULL;
 }
 
 void
-pagedir_clear_page (uint32_t *pagedir, void *upage)
+pagedir_clear_page (uint32_t *pd, void *upage)
 {
-  uint32_t *pte = lookup_page (pagedir, upage, false);
+  uint32_t *pte = lookup_page (pd, upage, false);
   if (pte != NULL)
     *pte = 0;
 }
@@ -194,7 +187,7 @@ scan_pd (uint32_t *pd, unsigned pde_idx, void **upage)
 
       if (pde != 0) 
         {
-          void *kpage = scan_pt (pde_get_pagetab (pde), pde_idx, 0, upage);
+          void *kpage = scan_pt (pde_get_pt (pde), pde_idx, 0, upage);
           if (kpage != NULL)
             return kpage;
         }
@@ -204,9 +197,9 @@ scan_pd (uint32_t *pd, unsigned pde_idx, void **upage)
 }
 
 void *
-pagedir_first (uint32_t *pagedir, void **upage) 
+pagedir_first (uint32_t *pd, void **upage) 
 {
-  return scan_pd (pagedir, 0, upage);
+  return scan_pd (pd, 0, upage);
 }
 
 void *
@@ -217,7 +210,7 @@ pagedir_next (uint32_t *pd, void **upage)
 
   pde_idx = pd_no (*upage);
   pte_idx = pt_no (*upage);
-  kpage = scan_pt (pde_get_pagetab (pd[pde_idx]),
+  kpage = scan_pt (pde_get_pt (pd[pde_idx]),
                    pde_idx, pte_idx + 1, upage);
   if (kpage == NULL)
     kpage = scan_pd (pd, pde_idx + 1, upage);
@@ -225,7 +218,7 @@ pagedir_next (uint32_t *pd, void **upage)
 }
 
 void
-pagedir_activate (uint32_t *pagedir
+pagedir_activate (uint32_t *pd
 {
-  asm volatile ("movl %0,%%cr3" :: "r" (vtop (pagedir)));
+  asm volatile ("movl %0,%%cr3" :: "r" (vtop (pd)));
 }
index b00823af50044cd4e2cfb0a1f73fbd5802d18fd5..fddd821afc8ef296fb22d800768e743577be89c5 100644 (file)
@@ -32,7 +32,16 @@ switch_threads:
        popl %ebx
         ret
 
-       .globl switch_thunk
-switch_thunk:
+       .globl switch_entry
+switch_entry:
+       # Discard thread_switch() arguments.
        addl $8, %esp
+
+       # Call schedule_tail(prev).
+       pushl %eax
+       .globl schedule_tail
+       call schedule_tail
+       addl $4, %esp
+
+       # Start thread proper.
        ret
index c9ae4ab8b108bbd2b9165058f36b13dfd0319d6a..8a2974fcd999bafde09a9e46bfc274ad6dbde4dd 100644 (file)
@@ -3,7 +3,7 @@
 
 #ifndef __ASSEMBLER__
 /* switch_thread()'s stack frame. */
-struct switch_frame 
+struct switch_threads_frame 
   {
     uint32_t ebx;               /*  0: Saved %ebx. */
     uint32_t ebp;               /*  4: Saved %ebp. */
@@ -19,11 +19,13 @@ struct switch_frame
    NEXT's context. */
 struct thread *switch_threads (struct thread *cur, struct thread *next);
 
-struct switch_thunk_frame 
+struct switch_entry_frame
   {
     void (*eip) (void);
   };
 
+void switch_entry (void);
+
 /* Pops the CUR and NEXT arguments off the stack, for use in
    initializing threads. */
 void switch_thunk (void);
index 82858dfca059874717e0f01c77db979634f9000e..dd98be0d2bbf846b851c86346c63c884a9191ccd 100644 (file)
@@ -67,8 +67,8 @@ thread_create (const char *name, void (*function) (void *aux), void *aux)
 {
   struct thread *t;
   struct thread_root_frame *rf;
-  struct switch_thunk_frame *tf;
-  struct switch_frame *sf;
+  struct switch_entry_frame *ef;
+  struct switch_threads_frame *sf;
 
   ASSERT (function != NULL);
 
@@ -80,13 +80,13 @@ thread_create (const char *name, void (*function) (void *aux), void *aux)
   rf->function = function;
   rf->aux = aux;
 
-  /* Stack frame for switch_thunk(). */
-  tf = alloc_frame (t, sizeof *tf);
-  tf->eip = (void (*) (void)) thread_root;
+  /* Stack frame for switch_entry(). */
+  ef = alloc_frame (t, sizeof *ef);
+  ef->eip = (void (*) (void)) thread_root;
 
   /* Stack frame for thread_switch(). */
   sf = alloc_frame (t, sizeof *sf);
-  sf->eip = (void (*) (void)) switch_thunk;
+  sf->eip = switch_entry;
 
   /* Add to run queue. */
   thread_ready (t);
@@ -108,8 +108,8 @@ thread_execute (const char *filename)
 {
   struct thread *t;
   struct intr_frame *if_;
-  struct switch_thunk_frame *tf;
-  struct switch_frame *sf;
+  struct switch_entry_frame *ef;
+  struct switch_threads_frame *sf;
   void (*start) (void);
 
   ASSERT (filename != NULL);
@@ -130,14 +130,14 @@ thread_execute (const char *filename)
   if_->eflags = FLAG_IF | 2;
   if_->esp = PHYS_BASE;
   if_->ss = SEL_UDSEG;
-  
-  /* Stack frame for switch_thunk(). */
-  tf = alloc_frame (t, sizeof *tf);
-  tf->eip = (void (*) (void)) intr_exit;
+
+  /* Stack frame for switch_entry(). */
+  ef = alloc_frame (t, sizeof *ef);
+  ef->eip = intr_exit;
 
   /* Stack frame for thread_switch(). */
   sf = alloc_frame (t, sizeof *sf);
-  sf->eip = (void (*) (void)) switch_thunk;
+  sf->eip = switch_entry;
 
   /* Add to run queue. */
   thread_ready (t);
@@ -182,6 +182,23 @@ thread_destroy (struct thread *t)
   palloc_free (t);
 }
 
+void schedule_tail (struct thread *prev);
+
+void
+schedule_tail (struct thread *prev) 
+{
+  struct thread *cur = thread_current ();
+
+#ifdef USERPROG
+  addrspace_activate (&cur->addrspace);
+#endif
+
+  if (prev != NULL && prev->status == THREAD_DYING) 
+    thread_destroy (prev);
+
+  intr_enable ();
+}
+
 void
 thread_schedule (void) 
 {
@@ -196,20 +213,16 @@ thread_schedule (void)
     idle ();
 
   next->status = THREAD_RUNNING;
-  prev = switch_threads (cur, next);
-
-  /* Prevent GCC from reordering anything around the thread
-     switch. */
-  asm volatile ("" : : : "memory");
-
-#ifdef USERPROG
-  addrspace_activate (&cur->addrspace);
-#endif
+  if (cur != next)
+    {
+      prev = switch_threads (cur, next);
 
-  if (prev != NULL && prev->status == THREAD_DYING) 
-    thread_destroy (prev);
+      /* Prevent GCC from reordering anything around the thread
+         switch. */
+      asm volatile ("" : : : "memory");
 
-  intr_enable ();
+      schedule_tail (prev); 
+    }
 }
 
 void
@@ -241,6 +254,7 @@ thread_exit (void)
   intr_disable ();
   thread_current ()->status = THREAD_DYING;
   thread_schedule ();
+  NOT_REACHED ();
 }
 
 void
index 8a0df6e254052ff7c8a8ee1b44fda01876fc1e4e..9251ad88cb3c47ec1190099a9d2511dc99f93da3 100644 (file)
@@ -2,6 +2,7 @@
 #define HEADER_THREAD_H 1
 
 #include <stdint.h>
+#include "debug.h"
 #include "list.h"
 
 #ifdef USERPROG
@@ -40,7 +41,7 @@ bool thread_execute (const char *filename);
 
 void thread_start (struct thread *);
 void thread_ready (struct thread *);
-void thread_exit (void);
+void thread_exit (void) NO_RETURN;
 
 void thread_yield (void);
 void thread_sleep (void);
index eb0de496851a5a340270e8d1cdd38074d677d88e..c136ae55d0bef505985e312e6a82b07d8ed0b9f7 100644 (file)
@@ -3,6 +3,7 @@
 #include "debug.h"
 #include "file.h"
 #include "filesys.h"
+#include "init.h"
 #include "lib.h"
 #include "mmu.h"
 #include "malloc.h"
@@ -209,11 +210,6 @@ addrspace_load (struct addrspace *as, const char *filename,
       file_seek (file, file_ofs);
       if (file_read (file, &phdr, sizeof phdr) != sizeof phdr)
         LOAD_ERROR (("error reading program header"));
-      printk ("%x: %08x, %08x %08x %08x %05x %05x\n",
-              file_tell (file),
-              phdr.p_type,
-              phdr.p_offset, phdr.p_vaddr, phdr.p_paddr,
-              phdr.p_filesz, phdr.p_memsz);
       file_ofs += sizeof phdr;
       switch (phdr.p_type) 
         {
@@ -270,4 +266,5 @@ addrspace_activate (struct addrspace *as)
   
   if (as->pagedir != NULL)
     pagedir_activate (as->pagedir);
+  tss->esp0 = (uint32_t) pg_round_down (as) + PGSIZE;
 }