Rename printk() to printf().
[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 ();
59
60   /* Greet user. */
61   printf ("Booting cnachos86 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
91 #ifdef FILESYS
92   /* Initialize filesystem. */
93   disk_init ();
94   filesys_init (format_filesys);
95   fsutil_run ();
96 #endif
97
98   printf ("Boot complete.\n");
99
100 #ifdef USERPROG
101   /* Run a user program. */
102   if (initial_program != NULL)
103     {
104       printf ("\nExecuting '%s':\n", initial_program);
105       thread_execute (initial_program); 
106     }
107 #endif
108
109   /* Terminate this thread. */
110   thread_exit ();
111 }
112 \f
113 /* Clear BSS and obtain RAM size from loader. */
114 static void
115 ram_init (void) 
116 {
117   /* The "BSS" is a segment that should be initialized to zeros.
118      It isn't actually stored on disk or zeroed by the kernel
119      loader, so we have to zero it ourselves.
120
121      The start and end of the BSS segment is recorded by the
122      linker as _start_bss and _end_bss.  See kernel.lds. */
123   extern char _start_bss, _end_bss;
124   memset (&_start_bss, 0, &_end_bss - &_start_bss);
125
126   /* Get RAM size from loader.  See loader.S. */
127   ram_pages = *(uint32_t *) ptov (LOADER_RAM_PAGES);
128 }
129
130 /* Parses the command line. */
131 static void
132 argv_init (void) 
133 {
134   char *cmd_line, *pos;
135   char *argv[LOADER_CMD_LINE_LEN / 2 + 1];
136   int argc = 0;
137   int i;
138
139   /* The command line is made up of null terminated strings
140      followed by an empty string.  Break it up into words. */
141   cmd_line = pos = ptov (LOADER_CMD_LINE);
142   while (pos < cmd_line + LOADER_CMD_LINE_LEN)
143     {
144       ASSERT (argc < LOADER_CMD_LINE_LEN / 2);
145       if (*pos == '\0')
146         break;
147       argv[argc++] = pos;
148       pos = strchr (pos, '\0') + 1;
149     }
150   argv[argc] = "";
151
152   /* Parse the words. */
153   for (i = 0; i < argc; i++)
154     if (!strcmp (argv[i], "-rs")) 
155       random_init (atoi (argv[++i]));
156     else if (!strcmp (argv[i], "-d")) 
157       debug_enable (argv[++i]);
158 #ifdef USERPROG
159     else if (!strcmp (argv[i], "-ex")) 
160       initial_program = argv[++i];
161 #endif
162 #ifdef FILESYS
163   else if (!strcmp (argv[i], "-f"))
164       format_filesys = true;
165     else if (!strcmp (argv[i], "-cp")) 
166       fsutil_copy_arg = argv[++i];
167     else if (!strcmp (argv[i], "-p")) 
168       fsutil_print_file = argv[++i];
169     else if (!strcmp (argv[i], "-r"))
170       fsutil_remove_file = argv[++i];
171     else if (!strcmp (argv[i], "-ls"))
172       fsutil_list_files = true;
173     else if (!strcmp (argv[i], "-D"))
174       fsutil_dump_filesys = true;
175 #endif
176     else if (!strcmp (argv[i], "-u"))
177       {
178         printf (
179           "Kernel options:\n"
180           " -rs SEED            Seed random seed to SEED.\n"
181           " -d CLASS[,...]      Enable the given classes of debug messages.\n"
182 #ifdef USERPROG
183           " -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
184 #endif
185 #ifdef FILESYS
186           " -f                  Format the filesystem disk (hdb or hd0:1).\n"
187           " -cp FILENAME:SIZE   Copy SIZE bytes from the scratch disk (hdc\n"
188           "                     or hd1:0) into the filesystem as FILENAME\n"
189           " -p FILENAME         Print the contents of FILENAME\n"
190           " -r FILENAME         Delete FILENAME\n"
191           " -ls                 List the files in the filesystem\n"
192           " -D                  Dump complete filesystem contents\n"
193 #endif
194           );
195       }
196     else 
197       PANIC ("unknown option `%s'", argv[i]);
198 }