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