Eliminate user_page_limit global symbol.
[pintos-anon] / src / threads / init.c
index b89b282435ffa4fd284c776049dcc4c45a60c66c..8a037058a7358bea829c75153cfdca313570febd 100644 (file)
@@ -40,7 +40,7 @@
 size_t ram_pages;
 
 /* Page directory with kernel mappings only. */
 size_t ram_pages;
 
 /* Page directory with kernel mappings only. */
-uint32_t *base_page_dir;
+uint32_t *init_page_dir;
 
 #ifdef FILESYS
 /* -f: Format the file system? */
 
 #ifdef FILESYS
 /* -f: Format the file system? */
@@ -50,6 +50,12 @@ static bool format_filesys;
 /* -q: Power off after kernel tasks complete? */
 bool power_off_when_done;
 
 /* -q: Power off after kernel tasks complete? */
 bool power_off_when_done;
 
+/* -r: Reboot after kernel tasks complete? */
+static bool reboot_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);
 
@@ -85,7 +91,7 @@ main (void)
   printf ("Pintos booting with %'zu kB RAM...\n", ram_pages * PGSIZE / 1024);
 
   /* Initialize memory system. */
   printf ("Pintos booting with %'zu kB RAM...\n", ram_pages * PGSIZE / 1024);
 
   /* Initialize memory system. */
-  palloc_init ();
+  palloc_init (user_page_limit);
   malloc_init ();
   paging_init ();
 
   malloc_init ();
   paging_init ();
 
@@ -122,6 +128,9 @@ main (void)
   run_actions (argv);
 
   /* Finish up. */
   run_actions (argv);
 
   /* Finish up. */
+  if (reboot_when_done)
+    reboot ();
+
   if (power_off_when_done)
     power_off ();
   thread_exit ();
   if (power_off_when_done)
     power_off ();
   thread_exit ();
@@ -146,7 +155,7 @@ ram_init (void)
 
 /* 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
@@ -160,7 +169,7 @@ paging_init (void)
   size_t page;
   extern char _start, _end_kernel_text;
 
   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;
   for (page = 0; page < ram_pages; page++) 
     {
   pt = NULL;
   for (page = 0; page < ram_pages; page++) 
     {
@@ -184,7 +193,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
@@ -237,6 +246,8 @@ parse_options (char **argv)
         usage ();
       else if (!strcmp (name, "-q"))
         power_off_when_done = true;
         usage ();
       else if (!strcmp (name, "-q"))
         power_off_when_done = true;
+      else if (!strcmp (name, "-r"))
+        reboot_when_done = true;
 #ifdef FILESYS
       else if (!strcmp (name, "-f"))
         format_filesys = true;
 #ifdef FILESYS
       else if (!strcmp (name, "-f"))
         format_filesys = true;
@@ -302,8 +313,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},
     };
@@ -351,12 +362,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"
@@ -367,6 +379,40 @@ usage (void)
   power_off ();
 }
 
   power_off ();
 }
 
+/* Keyboard control register port. */
+#define CONTROL_REG 0x64
+
+/* Reboots the machine via the keyboard controller. */
+void
+reboot (void)
+{
+  int i;
+
+  printf ("Rebooting...\n");
+
+    /* See [kbd] for details on how to program the keyboard
+     * controller. */
+  for (i = 0; i < 100; i++) 
+    {
+      int j;
+
+      /* Poll keyboard controller's status byte until 
+       * 'input buffer empty' is reported. */
+      for (j = 0; j < 0x10000; j++) 
+        {
+          if ((inb (CONTROL_REG) & 0x02) == 0)   
+            break;
+          timer_udelay (2);
+        }
+
+      timer_udelay (50);
+
+      /* Pulse bit 0 of the output port P2 of the keyboard controller. 
+       * This will reset the CPU. */
+      outb (CONTROL_REG, 0xfe);
+      timer_udelay (50);
+    }
+}
 
 /* Powers down the machine we're running on,
    as long as we're running on Bochs or QEMU. */
 
 /* Powers down the machine we're running on,
    as long as we're running on Bochs or QEMU. */