Rename ram_pages to init_ram_pages.
[pintos-anon] / src / threads / init.c
index a624ef57edf02a2b3aa7b392e5a4fc37abded034..d2d3e087de286cb8f5b48fd960d1568ae2d1cab4 100644 (file)
@@ -9,9 +9,12 @@
 #include <stdlib.h>
 #include <string.h>
 #include "devices/kbd.h"
 #include <stdlib.h>
 #include <string.h>
 #include "devices/kbd.h"
+#include "devices/input.h"
 #include "devices/serial.h"
 #include "devices/serial.h"
+#include "devices/shutdown.h"
 #include "devices/timer.h"
 #include "devices/vga.h"
 #include "devices/timer.h"
 #include "devices/vga.h"
+#include "devices/rtc.h"
 #include "threads/interrupt.h"
 #include "threads/io.h"
 #include "threads/loader.h"
 #include "threads/interrupt.h"
 #include "threads/io.h"
 #include "threads/loader.h"
 #endif
 
 /* Amount of physical memory, in 4 kB pages. */
 #endif
 
 /* Amount of physical memory, in 4 kB pages. */
-size_t ram_pages;
+size_t init_ram_pages;
 
 /* Page directory with kernel mappings only. */
 
 /* Page directory with kernel mappings only. */
-uint32_t *base_page_dir;
-
-/* -mlfqs:
-   If false (default), use round-robin scheduler.
-   If true, use multi-level feedback queue scheduler. */
-bool enable_mlfqs;
+uint32_t *init_page_dir;
 
 #ifdef FILESYS
 /* -f: Format the file system? */
 static bool format_filesys;
 #endif
 
 
 #ifdef FILESYS
 /* -f: Format the file system? */
 static bool format_filesys;
 #endif
 
-/* -q: Power off after kernel tasks complete? */
-bool power_off_when_done;
+/* -ul: Maximum number of pages to put into palloc's user pool. */
+static size_t user_page_limit = SIZE_MAX;
 
 static void ram_init (void);
 static void paging_init (void);
 
 static void ram_init (void);
 static void paging_init (void);
@@ -61,9 +59,6 @@ static char **parse_options (char **argv);
 static void run_actions (char **argv);
 static void usage (void);
 
 static void run_actions (char **argv);
 static void usage (void);
 
-static void print_stats (void);
-
-
 int main (void) NO_RETURN;
 
 /* Pintos main program. */
 int main (void) NO_RETURN;
 
 /* Pintos main program. */
@@ -75,26 +70,21 @@ main (void)
   /* Clear BSS and get machine's RAM size. */  
   ram_init ();
 
   /* Clear BSS and get machine's RAM size. */  
   ram_init ();
 
-  /* Initialize ourselves as a thread so we can use locks. */
-  thread_init ();
-
-  /* Initialize the console so we can use printf(). */
-  vga_init ();
-  serial_init_poll ();
-  console_init ();
-
-  /* Greet user. */
-  printf ("Pintos booting with %'zu kB RAM...\n", ram_pages * PGSIZE / 1024);
-
   /* Break command line into arguments and parse options. */
   argv = read_command_line ();
   argv = parse_options (argv);
 
   /* Break command line into arguments and parse options. */
   argv = read_command_line ();
   argv = parse_options (argv);
 
-  /* Set random seed if parse_options() didn't. */
-  random_init (0);
+  /* Initialize ourselves as a thread so we can use locks,
+     then enable console locking. */
+  thread_init ();
+  console_init ();  
+
+  /* Greet user. */
+  printf ("Pintos booting with %'zu kB RAM...\n",
+          init_ram_pages * PGSIZE / 1024);
 
   /* Initialize memory system. */
 
   /* Initialize memory system. */
-  palloc_init ();
+  palloc_init (user_page_limit);
   malloc_init ();
   paging_init ();
 
   malloc_init ();
   paging_init ();
 
@@ -108,6 +98,7 @@ main (void)
   intr_init ();
   timer_init ();
   kbd_init ();
   intr_init ();
   timer_init ();
   kbd_init ();
+  input_init ();
 #ifdef USERPROG
   exception_init ();
   syscall_init ();
 #ifdef USERPROG
   exception_init ();
   syscall_init ();
@@ -130,8 +121,7 @@ main (void)
   run_actions (argv);
 
   /* Finish up. */
   run_actions (argv);
 
   /* Finish up. */
-  if (power_off_when_done)
-    power_off ();
+  shutdown ();
   thread_exit ();
 }
 \f
   thread_exit ();
 }
 \f
@@ -149,12 +139,12 @@ ram_init (void)
   memset (&_start_bss, 0, &_end_bss - &_start_bss);
 
   /* Get RAM size from loader.  See loader.S. */
   memset (&_start_bss, 0, &_end_bss - &_start_bss);
 
   /* Get RAM size from loader.  See loader.S. */
-  ram_pages = *(uint32_t *) ptov (LOADER_RAM_PGS);
+  init_ram_pages = *(uint32_t *) ptov (LOADER_RAM_PGS);
 }
 
 /* Populates the base page directory and page table with the
    kernel virtual mapping, and then sets up the CPU to use the
 }
 
 /* Populates the base page directory and page table with the
    kernel virtual mapping, and then sets up the CPU to use the
-   new page directory.  Points base_page_dir to the page
+   new page directory.  Points init_page_dir to the page
    directory it creates.
 
    At the time this function is called, the active page table
    directory it creates.
 
    At the time this function is called, the active page table
@@ -166,15 +156,17 @@ paging_init (void)
 {
   uint32_t *pd, *pt;
   size_t page;
 {
   uint32_t *pd, *pt;
   size_t page;
+  extern char _start, _end_kernel_text;
 
 
-  pd = base_page_dir = palloc_get_page (PAL_ASSERT | PAL_ZERO);
+  pd = init_page_dir = palloc_get_page (PAL_ASSERT | PAL_ZERO);
   pt = NULL;
   pt = NULL;
-  for (page = 0; page < ram_pages; page++) 
+  for (page = 0; page < init_ram_pages; page++)
     {
       uintptr_t paddr = page * PGSIZE;
     {
       uintptr_t paddr = page * PGSIZE;
-      void *vaddr = ptov (paddr);
+      char *vaddr = ptov (paddr);
       size_t pde_idx = pd_no (vaddr);
       size_t pte_idx = pt_no (vaddr);
       size_t pde_idx = pd_no (vaddr);
       size_t pte_idx = pt_no (vaddr);
+      bool in_kernel_text = &_start <= vaddr && vaddr < &_end_kernel_text;
 
       if (pd[pde_idx] == 0)
         {
 
       if (pd[pde_idx] == 0)
         {
@@ -182,7 +174,7 @@ paging_init (void)
           pd[pde_idx] = pde_create (pt);
         }
 
           pd[pde_idx] = pde_create (pt);
         }
 
-      pt[pte_idx] = pte_create_kernel (vaddr, true);
+      pt[pte_idx] = pte_create_kernel (vaddr, !in_kernel_text);
     }
 
   /* Store the physical address of the page directory into CR3
     }
 
   /* Store the physical address of the page directory into CR3
@@ -190,7 +182,7 @@ paging_init (void)
      new page tables immediately.  See [IA32-v2a] "MOV--Move
      to/from Control Registers" and [IA32-v3a] 3.7.5 "Base Address
      of the Page Directory". */
      new page tables immediately.  See [IA32-v2a] "MOV--Move
      to/from Control Registers" and [IA32-v3a] 3.7.5 "Base Address
      of the Page Directory". */
-  asm volatile ("movl %0, %%cr3" :: "r" (vtop (base_page_dir)));
+  asm volatile ("movl %0, %%cr3" : : "r" (vtop (init_page_dir)));
 }
 
 /* Breaks the kernel command line into words and returns them as
 }
 
 /* Breaks the kernel command line into words and returns them as
@@ -219,7 +211,10 @@ read_command_line (void)
   /* Print kernel command line. */
   printf ("Kernel command line:");
   for (i = 0; i < argc; i++)
   /* Print kernel command line. */
   printf ("Kernel command line:");
   for (i = 0; i < argc; i++)
-    printf (" %s", argv[i]);
+    if (strchr (argv[i], ' ') == NULL)
+      printf (" %s", argv[i]);
+    else
+      printf (" '%s'", argv[i]);
   printf ("\n");
 
   return argv;
   printf ("\n");
 
   return argv;
@@ -239,7 +234,9 @@ parse_options (char **argv)
       if (!strcmp (name, "-h"))
         usage ();
       else if (!strcmp (name, "-q"))
       if (!strcmp (name, "-h"))
         usage ();
       else if (!strcmp (name, "-q"))
-        power_off_when_done = true;
+        shutdown_configure (SHUTDOWN_POWER_OFF);
+      else if (!strcmp (name, "-r"))
+        shutdown_configure (SHUTDOWN_REBOOT);
 #ifdef FILESYS
       else if (!strcmp (name, "-f"))
         format_filesys = true;
 #ifdef FILESYS
       else if (!strcmp (name, "-f"))
         format_filesys = true;
@@ -247,7 +244,7 @@ parse_options (char **argv)
       else if (!strcmp (name, "-rs"))
         random_init (atoi (value));
       else if (!strcmp (name, "-mlfqs"))
       else if (!strcmp (name, "-rs"))
         random_init (atoi (value));
       else if (!strcmp (name, "-mlfqs"))
-        enable_mlfqs = true;
+        thread_mlfqs = true;
 #ifdef USERPROG
       else if (!strcmp (name, "-ul"))
         user_page_limit = atoi (value);
 #ifdef USERPROG
       else if (!strcmp (name, "-ul"))
         user_page_limit = atoi (value);
@@ -255,6 +252,16 @@ parse_options (char **argv)
       else
         PANIC ("unknown option `%s' (use -h for help)", name);
     }
       else
         PANIC ("unknown option `%s' (use -h for help)", name);
     }
+
+  /* Initialize the random number generator based on the system
+     time.  This has no effect if an "-rs" option was specified.
+
+     When running under Bochs, this is not enough by itself to
+     get a good seed value, because the pintos script sets the
+     initial time to a predictable value, not to the local time,
+     for reproducibility.  To fix this, give the "-r" option to
+     the pintos script to request real-time execution. */
+  random_init (rtc_get_time ());
   
   return argv;
 }
   
   return argv;
 }
@@ -295,8 +302,8 @@ run_actions (char **argv)
       {"ls", 1, fsutil_ls},
       {"cat", 2, fsutil_cat},
       {"rm", 2, fsutil_rm},
       {"ls", 1, fsutil_ls},
       {"cat", 2, fsutil_cat},
       {"rm", 2, fsutil_rm},
-      {"put", 2, fsutil_put},
-      {"get", 2, fsutil_get},
+      {"extract", 1, fsutil_extract},
+      {"append", 2, fsutil_append},
 #endif
       {NULL, 0, NULL},
     };
 #endif
       {NULL, 0, NULL},
     };
@@ -344,12 +351,13 @@ usage (void)
           "  cat FILE           Print FILE to the console.\n"
           "  rm FILE            Delete FILE.\n"
           "Use these actions indirectly via `pintos' -g and -p options:\n"
           "  cat FILE           Print FILE to the console.\n"
           "  rm FILE            Delete FILE.\n"
           "Use these actions indirectly via `pintos' -g and -p options:\n"
-          "  put FILE           Put FILE into file system from scratch disk.\n"
-          "  get FILE           Get FILE from file system into scratch disk.\n"
+          "  extract            Untar from scratch disk into file system.\n"
+          "  append FILE        Append FILE to tar file on scratch disk.\n"
 #endif
           "\nOptions:\n"
           "  -h                 Print this help message and power off.\n"
           "  -q                 Power off VM after actions or on panic.\n"
 #endif
           "\nOptions:\n"
           "  -h                 Print this help message and power off.\n"
           "  -q                 Power off VM after actions or on panic.\n"
+          "  -r                 Reboot after actions.\n"
           "  -f                 Format file system disk during startup.\n"
           "  -rs=SEED           Set random number seed to SEED.\n"
           "  -mlfqs             Use multi-level feedback queue scheduler.\n"
           "  -f                 Format file system disk during startup.\n"
           "  -rs=SEED           Set random number seed to SEED.\n"
           "  -mlfqs             Use multi-level feedback queue scheduler.\n"
@@ -357,44 +365,5 @@ usage (void)
           "  -ul=COUNT          Limit user memory to COUNT pages.\n"
 #endif
           );
           "  -ul=COUNT          Limit user memory to COUNT pages.\n"
 #endif
           );
-  power_off ();
-}
-
-
-/* Powers down the machine we're running on,
-   as long as we're running on Bochs or qemu. */
-void
-power_off (void) 
-{
-  const char s[] = "Shutdown";
-  const char *p;
-
-#ifdef FILESYS
-  filesys_done ();
-#endif
-
-  print_stats ();
-
-  printf ("Powering off...\n");
-  serial_flush ();
-
-  for (p = s; *p != '\0'; p++)
-    outb (0x8900, *p);
-  for (;;);
-}
-
-/* Print statistics about Pintos execution. */
-static void
-print_stats (void) 
-{
-  timer_print_stats ();
-  thread_print_stats ();
-#ifdef FILESYS
-  disk_print_stats ();
-#endif
-  console_print_stats ();
-  kbd_print_stats ();
-#ifdef USERPROG
-  exception_print_stats ();
-#endif
+  shutdown_power_off ();
 }
 }