1 #include "threads/init.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/palloc.h"
21 #include "threads/test.h"
22 #include "threads/thread.h"
24 #include "userprog/process.h"
25 #include "userprog/exception.h"
26 #include "userprog/gdt.h"
27 #include "userprog/syscall.h"
28 #include "userprog/tss.h"
31 #include "devices/disk.h"
32 #include "filesys/filesys.h"
33 #include "filesys/fsutil.h"
36 /* Amount of physical memory, in 4 kB pages. */
39 /* Page directory with kernel mappings only. */
40 uint32_t *base_page_dir;
43 /* -f: Format the filesystem? */
44 static bool format_filesys;
48 /* -ex: Initial program to run. */
49 static char *initial_program;
52 /* -q: Power off after running requested actions? */
53 static bool do_power_off;
55 static void ram_init (void);
56 static void paging_init (void);
57 static void argv_init (void);
59 int main (void) NO_RETURN;
64 /* Initialize everything needed for printf() first. */
72 printf ("Pintos booting with %'zd kB RAM...\n", ram_pages * (PGSIZE / 1024));
74 /* Parse command line. */
77 /* Initialize memory system, segments, paging. */
86 /* Set random seed if argv_init() didn't. */
89 /* Initialize interrupt handlers. */
98 /* Start thread scheduler and enable interrupts. */
100 serial_init_queue ();
103 /* Initialize filesystem. */
105 filesys_init (format_filesys);
109 printf ("Boot complete.\n");
112 /* Run a user program. */
113 if (initial_program != NULL)
115 printf ("\nExecuting '%s':\n", initial_program);
116 process_execute (initial_program);
125 /* Terminate this thread. */
129 /* Clear BSS and obtain RAM size from loader. */
133 /* The "BSS" is a segment that should be initialized to zeros.
134 It isn't actually stored on disk or zeroed by the kernel
135 loader, so we have to zero it ourselves.
137 The start and end of the BSS segment is recorded by the
138 linker as _start_bss and _end_bss. See kernel.lds. */
139 extern char _start_bss, _end_bss;
140 memset (&_start_bss, 0, &_end_bss - &_start_bss);
142 /* Get RAM size from loader. See loader.S. */
143 ram_pages = *(uint32_t *) ptov (LOADER_RAM_PAGES);
146 /* Populates the base page directory and page table with the
147 kernel virtual mapping, and then sets up the CPU to use the
148 new page directory. Points base_page_dir to the page
149 directory it creates.
151 At the time this function is called, the active page table
152 (set up by loader.S) only maps the first 4 MB of RAM, so we
153 should not try to use extravagant amounts of memory.
154 Fortunately, there is no need to do so. */
161 pd = base_page_dir = palloc_get (PAL_ASSERT | PAL_ZERO);
163 for (page = 0; page < ram_pages; page++)
165 uintptr_t paddr = page * PGSIZE;
166 void *vaddr = ptov (paddr);
167 size_t pde_idx = pd_no (vaddr);
168 size_t pte_idx = pt_no (vaddr);
170 if (pd[pde_idx] == 0)
172 pt = palloc_get (PAL_ASSERT | PAL_ZERO);
173 pd[pde_idx] = pde_create (pt);
176 pt[pte_idx] = pte_create_kernel (vaddr, true);
179 asm volatile ("movl %0,%%cr3" :: "r" (vtop (base_page_dir)));
182 /* Parses the command line. */
186 char *cmd_line, *pos;
187 char *argv[LOADER_CMD_LINE_LEN / 2 + 2];
191 /* The command line is made up of null terminated strings
192 followed by an empty string. Break it up into words. */
193 cmd_line = pos = ptov (LOADER_CMD_LINE);
194 printf ("Kernel command line:");
195 while (pos < cmd_line + LOADER_CMD_LINE_LEN)
197 ASSERT (argc < LOADER_CMD_LINE_LEN / 2);
202 pos = strchr (pos, '\0') + 1;
208 /* Parse the words. */
209 for (i = 0; i < argc; i++)
210 if (!strcmp (argv[i], "-rs"))
211 random_init (atoi (argv[++i]));
212 else if (!strcmp (argv[i], "-d"))
213 debug_enable (argv[++i]);
214 else if (!strcmp (argv[i], "-q"))
217 else if (!strcmp (argv[i], "-ex"))
218 initial_program = argv[++i];
221 else if (!strcmp (argv[i], "-f"))
222 format_filesys = true;
223 else if (!strcmp (argv[i], "-ci"))
225 fsutil_copyin_file = argv[++i];
226 fsutil_copyin_size = atoi (argv[++i]);
228 else if (!strcmp (argv[i], "-co"))
229 fsutil_copyout_file = argv[++i];
230 else if (!strcmp (argv[i], "-p"))
231 fsutil_print_file = argv[++i];
232 else if (!strcmp (argv[i], "-r"))
233 fsutil_remove_file = argv[++i];
234 else if (!strcmp (argv[i], "-ls"))
235 fsutil_list_files = true;
236 else if (!strcmp (argv[i], "-D"))
237 fsutil_dump_filesys = true;
239 else if (!strcmp (argv[i], "-u"))
243 " -rs SEED Seed random seed to SEED.\n"
244 " -d CLASS[,...] Enable the given classes of debug messages.\n"
246 " -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
249 " -f Format the filesystem disk (hdb or hd0:1).\n"
250 " -ci FILENAME SIZE Copy SIZE bytes from the scratch disk (hdc\n"
251 " or hd1:0) into the filesystem as FILENAME\n"
252 " -co FILENAME Copy FILENAME to the scratch disk, with\n"
253 " size at start of sector 0 and data afterward\n"
254 " -p FILENAME Print the contents of FILENAME\n"
255 " -r FILENAME Delete FILENAME\n"
256 " -ls List the files in the filesystem\n"
257 " -D Dump complete filesystem contents\n"
259 " -q Power off after doing requested actions.\n"
260 " -u Print this help message and power off.\n"
265 PANIC ("unknown option `%s' (use -u for help)", argv[i]);
268 /* Powers down the machine we're running on,
269 as long as we're running on Bochs or qemu. */
273 const char s[] = "Shutdown";
280 printf ("Powering off...\n");
283 for (p = s; *p != '\0'; p++)