Don't assume 4 kB pages.
[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 static void ram_init (void);
50 static void argv_init (void);
51
52 int main (void) NO_RETURN;
53
54 int
55 main (void)
56 {
57   /* Initialize everything needed for printf() first. */
58   ram_init ();
59   thread_init ();
60   vga_init ();
61   serial_init_poll ();
62   console_init ();
63
64   /* Greet user. */
65   printf ("Pintos booting with %'d kB RAM...\n", ram_pages * (PGSIZE / 1024));
66
67   /* Parse command line. */
68   argv_init ();
69
70   /* Initialize memory system, segments, paging. */
71   palloc_init ();
72   paging_init ();
73 #ifdef USERPROG
74   tss_init ();
75   gdt_init ();
76 #endif
77   malloc_init ();
78
79   /* Set random seed if argv_init() didn't. */
80   random_init (0);
81
82   /* Initialize interrupt handlers. */
83   intr_init ();
84   timer_init ();
85   kbd_init ();
86 #ifdef USERPROG
87   exception_init ();
88   syscall_init ();
89 #endif
90
91   /* Start thread scheduler and enable interrupts. */
92   thread_start ();
93   serial_init_queue ();
94
95 #ifdef FILESYS
96   /* Initialize filesystem. */
97   disk_init ();
98   filesys_init (format_filesys);
99   fsutil_run ();
100 #endif
101
102   printf ("Boot complete.\n");
103   
104 #ifdef USERPROG
105   /* Run a user program. */
106   if (initial_program != NULL)
107     {
108       printf ("\nExecuting '%s':\n", initial_program);
109       thread_execute (initial_program); 
110     }
111 #else
112   test ();
113 #endif
114
115   /* Terminate this thread. */
116   thread_exit ();
117 }
118 \f
119 /* Clear BSS and obtain RAM size from loader. */
120 static void
121 ram_init (void) 
122 {
123   /* The "BSS" is a segment that should be initialized to zeros.
124      It isn't actually stored on disk or zeroed by the kernel
125      loader, so we have to zero it ourselves.
126
127      The start and end of the BSS segment is recorded by the
128      linker as _start_bss and _end_bss.  See kernel.lds. */
129   extern char _start_bss, _end_bss;
130   memset (&_start_bss, 0, &_end_bss - &_start_bss);
131
132   /* Get RAM size from loader.  See loader.S. */
133   ram_pages = *(uint32_t *) ptov (LOADER_RAM_PAGES);
134 }
135
136 /* Parses the command line. */
137 static void
138 argv_init (void) 
139 {
140   char *cmd_line, *pos;
141   char *argv[LOADER_CMD_LINE_LEN / 2 + 1];
142   int argc = 0;
143   int i;
144
145   /* The command line is made up of null terminated strings
146      followed by an empty string.  Break it up into words. */
147   cmd_line = pos = ptov (LOADER_CMD_LINE);
148   while (pos < cmd_line + LOADER_CMD_LINE_LEN)
149     {
150       ASSERT (argc < LOADER_CMD_LINE_LEN / 2);
151       if (*pos == '\0')
152         break;
153       argv[argc++] = pos;
154       pos = strchr (pos, '\0') + 1;
155     }
156   argv[argc] = "";
157
158   /* Parse the words. */
159   for (i = 0; i < argc; i++)
160     if (!strcmp (argv[i], "-rs")) 
161       random_init (atoi (argv[++i]));
162     else if (!strcmp (argv[i], "-d")) 
163       debug_enable (argv[++i]);
164 #ifdef USERPROG
165     else if (!strcmp (argv[i], "-ex")) 
166       initial_program = argv[++i];
167 #endif
168 #ifdef FILESYS
169   else if (!strcmp (argv[i], "-f"))
170       format_filesys = true;
171     else if (!strcmp (argv[i], "-cp")) 
172       fsutil_copy_arg = argv[++i];
173     else if (!strcmp (argv[i], "-p")) 
174       fsutil_print_file = argv[++i];
175     else if (!strcmp (argv[i], "-r"))
176       fsutil_remove_file = argv[++i];
177     else if (!strcmp (argv[i], "-ls"))
178       fsutil_list_files = true;
179     else if (!strcmp (argv[i], "-D"))
180       fsutil_dump_filesys = true;
181 #endif
182     else if (!strcmp (argv[i], "-u"))
183       {
184         printf (
185           "Kernel options:\n"
186           " -rs SEED            Seed random seed to SEED.\n"
187           " -d CLASS[,...]      Enable the given classes of debug messages.\n"
188 #ifdef USERPROG
189           " -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
190 #endif
191 #ifdef FILESYS
192           " -f                  Format the filesystem disk (hdb or hd0:1).\n"
193           " -cp FILENAME:SIZE   Copy SIZE bytes from the scratch disk (hdc\n"
194           "                     or hd1:0) into the filesystem as FILENAME\n"
195           " -p FILENAME         Print the contents of FILENAME\n"
196           " -r FILENAME         Delete FILENAME\n"
197           " -ls                 List the files in the filesystem\n"
198           " -D                  Dump complete filesystem contents\n"
199 #endif
200           );
201       }
202     else 
203       PANIC ("unknown option `%s'", argv[i]);
204 }