Change -cp option to -ci ("copy in").
[pintos-anon] / src / threads / init.c
1 #include "threads/init.h"
2 #include <console.h>
3 #include <debug.h>
4 #include <limits.h>
5 #include <random.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "devices/kbd.h"
12 #include "devices/serial.h"
13 #include "devices/timer.h"
14 #include "devices/vga.h"
15 #include "threads/interrupt.h"
16 #include "threads/io.h"
17 #include "threads/loader.h"
18 #include "threads/malloc.h"
19 #include "threads/mmu.h"
20 #include "threads/paging.h"
21 #include "threads/palloc.h"
22 #include "threads/test.h"
23 #include "threads/thread.h"
24 #ifdef USERPROG
25 #include "userprog/exception.h"
26 #include "userprog/gdt.h"
27 #include "userprog/syscall.h"
28 #include "userprog/tss.h"
29 #endif
30 #ifdef FILESYS
31 #include "devices/disk.h"
32 #include "filesys/filesys.h"
33 #include "filesys/fsutil.h"
34 #endif
35
36 /* Amount of physical memory, in 4 kB pages. */
37 size_t ram_pages;
38
39 #ifdef FILESYS
40 /* Format the filesystem? */
41 static bool format_filesys;
42 #endif
43
44 #ifdef USERPROG
45 /* Initial program to run. */
46 static char *initial_program;
47 #endif
48
49 /* Power off after running requested actions? */
50 static bool power_off;
51
52 static void ram_init (void);
53 static void argv_init (void);
54 static void do_power_off (void);
55
56 int main (void) NO_RETURN;
57
58 int
59 main (void)
60 {
61   /* Initialize everything needed for printf() first. */
62   ram_init ();
63   thread_init ();
64   vga_init ();
65   serial_init_poll ();
66   console_init ();
67
68   /* Greet user. */
69   printf ("Pintos booting with %'zd kB RAM...\n", ram_pages * (PGSIZE / 1024));
70
71   /* Parse command line. */
72   argv_init ();
73
74   /* Initialize memory system, segments, paging. */
75   palloc_init ();
76   paging_init ();
77 #ifdef USERPROG
78   tss_init ();
79   gdt_init ();
80 #endif
81   malloc_init ();
82
83   /* Set random seed if argv_init() didn't. */
84   random_init (0);
85
86   /* Initialize interrupt handlers. */
87   intr_init ();
88   timer_init ();
89   kbd_init ();
90 #ifdef USERPROG
91   exception_init ();
92   syscall_init ();
93 #endif
94
95   /* Start thread scheduler and enable interrupts. */
96   thread_start ();
97   serial_init_queue ();
98
99 #ifdef FILESYS
100   /* Initialize filesystem. */
101   disk_init ();
102   filesys_init (format_filesys);
103   fsutil_run ();
104 #endif
105
106   printf ("Boot complete.\n");
107   
108 #ifdef USERPROG
109   /* Run a user program. */
110   if (initial_program != NULL)
111     {
112       printf ("\nExecuting '%s':\n", initial_program);
113       thread_execute (initial_program); 
114     }
115 #else
116   test ();
117 #endif
118
119   if (power_off) 
120     do_power_off ();
121
122   /* Terminate this thread. */
123   thread_exit ();
124 }
125 \f
126 /* Clear BSS and obtain RAM size from loader. */
127 static void
128 ram_init (void) 
129 {
130   /* The "BSS" is a segment that should be initialized to zeros.
131      It isn't actually stored on disk or zeroed by the kernel
132      loader, so we have to zero it ourselves.
133
134      The start and end of the BSS segment is recorded by the
135      linker as _start_bss and _end_bss.  See kernel.lds. */
136   extern char _start_bss, _end_bss;
137   memset (&_start_bss, 0, &_end_bss - &_start_bss);
138
139   /* Get RAM size from loader.  See loader.S. */
140   ram_pages = *(uint32_t *) ptov (LOADER_RAM_PAGES);
141 }
142
143 /* Parses the command line. */
144 static void
145 argv_init (void) 
146 {
147   char *cmd_line, *pos;
148   char *argv[LOADER_CMD_LINE_LEN / 2 + 2];
149   int argc = 0;
150   int i;
151
152   /* The command line is made up of null terminated strings
153      followed by an empty string.  Break it up into words. */
154   cmd_line = pos = ptov (LOADER_CMD_LINE);
155   while (pos < cmd_line + LOADER_CMD_LINE_LEN)
156     {
157       ASSERT (argc < LOADER_CMD_LINE_LEN / 2);
158       if (*pos == '\0')
159         break;
160       argv[argc++] = pos;
161       pos = strchr (pos, '\0') + 1;
162     }
163   argv[argc] = "";
164   argv[argc + 1] = "";
165
166   /* Parse the words. */
167   for (i = 0; i < argc; i++)
168     if (!strcmp (argv[i], "-rs")) 
169       random_init (atoi (argv[++i]));
170     else if (!strcmp (argv[i], "-d")) 
171       debug_enable (argv[++i]);
172     else if (!strcmp (argv[i], "-q"))
173       power_off = true;
174 #ifdef USERPROG
175     else if (!strcmp (argv[i], "-ex")) 
176       initial_program = argv[++i];
177 #endif
178 #ifdef FILESYS
179   else if (!strcmp (argv[i], "-f"))
180       format_filesys = true;
181     else if (!strcmp (argv[i], "-ci")) 
182       {
183         fsutil_copyin_file = argv[++i]; 
184         fsutil_copyin_size = atoi (argv[++i]); 
185       }
186     else if (!strcmp (argv[i], "-co"))
187       fsutil_copyout_file = argv[++i];
188     else if (!strcmp (argv[i], "-p")) 
189       fsutil_print_file = argv[++i];
190     else if (!strcmp (argv[i], "-r"))
191       fsutil_remove_file = argv[++i];
192     else if (!strcmp (argv[i], "-ls"))
193       fsutil_list_files = true;
194     else if (!strcmp (argv[i], "-D"))
195       fsutil_dump_filesys = true;
196 #endif
197     else if (!strcmp (argv[i], "-u"))
198       {
199         printf (
200           "Kernel options:\n"
201           " -rs SEED            Seed random seed to SEED.\n"
202           " -d CLASS[,...]      Enable the given classes of debug messages.\n"
203 #ifdef USERPROG
204           " -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
205 #endif
206 #ifdef FILESYS
207           " -f                  Format the filesystem disk (hdb or hd0:1).\n"
208           " -ci FILENAME SIZE   Copy SIZE bytes from the scratch disk (hdc\n"
209           "                     or hd1:0) into the filesystem as FILENAME\n"
210           " -co FILENAME        Copy FILENAME to the scratch disk, with\n"
211           "                     size at start of sector 0 and data afterward\n"
212           " -p FILENAME         Print the contents of FILENAME\n"
213           " -r FILENAME         Delete FILENAME\n"
214           " -ls                 List the files in the filesystem\n"
215           " -D                  Dump complete filesystem contents\n"
216 #endif
217           " -q                  Power off after doing requested actions.\n"
218           );
219       }
220     else 
221       PANIC ("unknown option `%s'", argv[i]);
222 }
223
224 void
225 do_power_off (void) 
226 {
227   const char s[] = "Shutdown";
228   const char *p;
229
230 #ifdef FILESYS
231   filesys_done ();
232 #endif
233
234   printf ("Powering off...\n");
235   for (p = s; *p != '\0'; p++)
236     outb (0x8900, *p);
237   for (;;);
238 }