Move user exception support into userprog.
[pintos-anon] / src / threads / init.c
1 #include "init.h"
2 #include <stdint.h>
3 #include <stddef.h>
4 #include <limits.h>
5 #include "debug.h"
6 #include "interrupt.h"
7 #include "io.h"
8 #include "kbd.h"
9 #include "lib.h"
10 #include "loader.h"
11 #include "malloc.h"
12 #include "mmu.h"
13 #include "paging.h"
14 #include "palloc.h"
15 #include "random.h"
16 #include "serial.h"
17 #include "thread.h"
18 #include "timer.h"
19 #include "vga.h"
20 #ifdef USERPROG
21 #include "exception.h"
22 #include "gdt.h"
23 #include "tss.h"
24 #endif
25 #ifdef FILESYS
26 #include "filesys.h"
27 #include "disk.h"
28 #include "fsutil.h"
29 #endif
30
31 /* Amount of physical memory, in 4 kB pages. */
32 size_t ram_pages;
33
34 #ifdef FILESYS
35 /* Format the filesystem? */
36 static bool format_filesys;
37 #endif
38
39 #ifdef USERPROG
40 /* Initial program to run. */
41 static char *initial_program;
42 #endif
43
44 static thread_func main_thread;
45 static void ram_init (void);
46 static void argv_init (void);
47
48 int
49 main (void)
50 {
51   /* Needed by printk(), so initialize them very early. */
52   ram_init ();
53   vga_init ();
54   serial_init ();
55
56   /* Greet user. */
57   printk ("Booting cnachos86 with %'d kB RAM...\n", ram_pages * 4);
58
59   /* Parse command line. */
60   argv_init ();
61
62   /* Initialize memory system, segments, paging. */
63   palloc_init ();
64   paging_init ();
65 #ifdef USERPROG
66   tss_init ();
67   gdt_init ();
68 #endif
69   malloc_init ();
70
71   /* Set random seed if not already done. */
72   random_init (0);
73
74   /* Initialize interrupt handlers. */
75   intr_init ();
76   timer_init ();
77   kbd_init ();
78 #ifdef USERPROG
79   exception_init ();
80 #endif
81
82   /* Do everything else in a system thread. */
83   thread_init ();
84   thread_create ("main", main_thread, NULL);
85   thread_start ();
86 }
87
88 /* Initial thread. */
89 static void
90 main_thread (void *aux UNUSED) 
91 {
92 #ifdef FILESYS
93   disk_init ();
94   filesys_init (format_filesys);
95   fsutil_run ();
96 #endif
97
98 #ifdef USERPROG
99   if (initial_program != NULL)
100     thread_execute (initial_program);
101   else
102     PANIC ("no initial program specified");
103 #else
104   PANIC ("boot successful");
105 #endif
106 }
107 \f
108 /* Clear BSS and obtain RAM size from loader. */
109 static void
110 ram_init (void) 
111 {
112   /* The "BSS" is a segment that should be initialized to zeros.
113      It isn't actually stored on disk or zeroed by the kernel
114      loader, so we have to zero it ourselves.
115
116      The start and end of the BSS segment is recorded by the
117      linker as _start_bss and _end_bss.  See kernel.lds. */
118   extern char _start_bss, _end_bss;
119   memset (&_start_bss, 0, &_end_bss - &_start_bss);
120
121   /* Get RAM size from loader.  See loader.S. */
122   ram_pages = *(uint32_t *) ptov (LOADER_RAM_PAGES);
123 }
124
125 /* Parses the command line. */
126 static void
127 argv_init (void) 
128 {
129   char *cmd_line, *pos;
130   char *argv[LOADER_CMD_LINE_LEN / 2 + 1];
131   int argc = 0;
132   int i;
133
134   /* The command line is made up of null terminated strings
135      followed by an empty string.  Break it up into words. */
136   cmd_line = pos = ptov (LOADER_CMD_LINE);
137   while (pos < cmd_line + LOADER_CMD_LINE_LEN)
138     {
139       ASSERT (argc < LOADER_CMD_LINE_LEN / 2);
140       if (*pos == '\0')
141         break;
142       argv[argc++] = pos;
143       pos = strchr (pos, '\0') + 1;
144     }
145   argv[argc] = "";
146
147   /* Parse the words. */
148   for (i = 0; i < argc; i++)
149     if (!strcmp (argv[i], "-rs")) 
150       random_init (atoi (argv[++i]));
151     else if (!strcmp (argv[i], "-d")) 
152       debug_enable (argv[++i]);
153 #ifdef USERPROG
154     else if (!strcmp (argv[i], "-ex")) 
155       initial_program = argv[++i];
156 #endif
157 #ifdef FILESYS
158   else if (!strcmp (argv[i], "-f"))
159       format_filesys = true;
160     else if (!strcmp (argv[i], "-cp")) 
161       fsutil_copy_arg = argv[++i];
162     else if (!strcmp (argv[i], "-p")) 
163       fsutil_print_file = argv[++i];
164     else if (!strcmp (argv[i], "-r"))
165       fsutil_remove_file = argv[++i];
166     else if (!strcmp (argv[i], "-ls"))
167       fsutil_list_files = true;
168     else if (!strcmp (argv[i], "-D"))
169       fsutil_dump_filesys = true;
170 #endif
171     else if (!strcmp (argv[i], "-u"))
172       {
173         printk (
174           "Kernel options:\n"
175           " -rs SEED            Seed random seed to SEED.\n"
176           " -d CLASS[,...]      Enable the given classes of debug messages.\n"
177 #ifdef USERPROG
178           " -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
179 #endif
180 #ifdef FILESYS
181           " -f                  Format the filesystem disk (hdb or hd0:1).\n"
182           " -cp FILENAME:SIZE   Copy SIZE bytes from the scratch disk (hdc\n"
183           "                     or hd1:0) into the filesystem as FILENAME\n"
184           " -p FILENAME         Print the contents of FILENAME\n"
185           " -r FILENAME         Delete FILENAME\n"
186           " -ls                 List the files in the filesystem\n"
187           " -D                  Dump complete filesystem contents\n"
188 #endif
189           );
190       }
191     else 
192       PANIC ("unknown option `%s'", argv[i]);
193 }