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