26 /* Amount of physical memory, in 4 kB pages. */
30 /* Format the filesystem? */
31 static bool format_filesys;
35 /* Initial program to run. */
36 static char *initial_program;
39 static void ram_init (void);
40 static void gdt_init (void);
41 static void argv_init (void);
44 main_thread (void *aux UNUSED)
48 filesys_init (format_filesys);
53 if (initial_program != NULL)
54 thread_execute (initial_program);
56 PANIC ("no initial program specified");
63 /* Initialize prerequisites for calling printk(). */
69 printk ("Booting cnachos86 with %'d kB RAM...\n", ram_pages * 4);
71 /* Parse command line. */
74 /* Initialize memory system. */
82 /* Initialize interrupt handlers. */
87 /* Do everything else in a system thread. */
89 thread_create ("main", main_thread, NULL);
94 make_seg_desc (uint32_t base,
96 enum seg_system system,
99 enum seg_granularity granularity)
101 uint32_t e0 = ((limit & 0xffff) /* Limit 15:0. */
102 | (base << 16)); /* Base 15:0. */
103 uint32_t e1 = (((base >> 16) & 0xff) /* Base 23:16. */
104 | (system << 12) /* 0=system, 1=code/data. */
105 | (type << 8) /* Segment type. */
106 | (dpl << 13) /* Descriptor privilege. */
107 | (1 << 15) /* Present. */
108 | (limit & 0xf0000) /* Limit 16:19. */
109 | (1 << 22) /* 32-bit segment. */
110 | (granularity << 23) /* Byte/page granularity. */
111 | (base & 0xff000000)); /* Base 31:24. */
112 return e0 | ((uint64_t) e1 << 32);
116 make_code_desc (int dpl)
118 return make_seg_desc (0, 0xfffff, SYS_CODE_DATA, TYPE_CODE | TYPE_READABLE,
123 make_data_desc (int dpl)
125 return make_seg_desc (0, 0xfffff, SYS_CODE_DATA, TYPE_WRITABLE,
130 make_tss_desc (void *vaddr)
132 return make_seg_desc ((uint32_t) vaddr,
133 0x67, SYS_SYSTEM, TYPE_TSS_32_A, 0, GRAN_BYTE);
136 static uint64_t gdt[SEL_CNT];
140 /* Sets up a proper GDT. The bootstrap loader's GDT didn't
141 include user-mode selectors or a TSS. */
145 uint64_t gdtr_operand;
147 /* Our TSS is never used in a call gate or task gate, so only a
148 few fields of it are ever referenced, and those are the only
149 ones we initialize. */
150 tss = palloc_get (PAL_ASSERT | PAL_ZERO);
151 tss->esp0 = (uint32_t) ptov(0x20000);
152 tss->ss0 = SEL_KDSEG;
153 tss->bitmap = 0xdfff;
155 /* Initialize GDT. */
156 gdt[SEL_NULL / sizeof *gdt] = 0;
157 gdt[SEL_KCSEG / sizeof *gdt] = make_code_desc (0);
158 gdt[SEL_KDSEG / sizeof *gdt] = make_data_desc (0);
159 gdt[SEL_UCSEG / sizeof *gdt] = make_code_desc (3);
160 gdt[SEL_UDSEG / sizeof *gdt] = make_data_desc (3);
161 gdt[SEL_TSS / sizeof *gdt] = make_tss_desc (tss);
164 gdtr_operand = make_dtr_operand (sizeof gdt - 1, gdt);
165 asm volatile ("lgdt %0" :: "m" (gdtr_operand));
166 asm volatile ("ltr %w0" :: "r" (SEL_TSS));
172 /* The "BSS" is a segment that should be initialized to zeros.
173 It isn't actually stored on disk or zeroed by the kernel
174 loader, so we have to zero it ourselves.
176 The start and end of the BSS segment is recorded by the
177 linker as _start_bss and _end_bss. See kernel.lds. */
178 extern char _start_bss, _end_bss;
179 memset (&_start_bss, 0, &_end_bss - &_start_bss);
181 /* Get RAM size from loader. */
182 ram_pages = *(uint32_t *) ptov (LOADER_RAM_PAGES);
188 char *cmd_line, *pos;
189 char *argv[LOADER_CMD_LINE_LEN / 2 + 1];
193 /* The command line is made up of null terminated strings
194 followed by an empty string. Break it up into words. */
195 cmd_line = pos = ptov (LOADER_CMD_LINE);
196 while (pos < cmd_line + LOADER_CMD_LINE_LEN)
198 ASSERT (argc < LOADER_CMD_LINE_LEN / 2);
202 pos = strchr (pos, '\0') + 1;
206 /* Parse the words. */
207 for (i = 0; i < argc; i++)
208 if (!strcmp (argv[i], "-rs"))
209 random_init (atoi (argv[++i]));
210 else if (!strcmp (argv[i], "-d"))
211 debug_enable (argv[++i]);
213 else if (!strcmp (argv[i], "-ex"))
214 initial_program = argv[++i];
217 else if (!strcmp (argv[i], "-f"))
218 format_filesys = true;
219 else if (!strcmp (argv[i], "-cp"))
220 fsutil_copy_arg = argv[++i];
221 else if (!strcmp (argv[i], "-p"))
222 fsutil_print_file = argv[++i];
223 else if (!strcmp (argv[i], "-r"))
224 fsutil_remove_file = argv[++i];
225 else if (!strcmp (argv[i], "-ls"))
226 fsutil_list_files = true;
227 else if (!strcmp (argv[i], "-D"))
228 fsutil_dump_filesys = true;
230 else if (!strcmp (argv[i], "-u"))
234 " -rs SEED Seed random seed to SEED.\n"
235 " -d CLASS[,...] Enable the given classes of debug messages.\n"
237 " -ex 'PROG [ARG...]' Run PROG, passing the optional arguments.\n"
240 " -f Format the filesystem disk (hdb or hd0:1).\n"
241 " -cp FILENAME:SIZE Copy SIZE bytes from the scratch disk (hdc\n"
242 " or hd1:0) into the filesystem as FILENAME\n"
243 " -p FILENAME Print the contents of FILENAME\n"
244 " -r FILENAME Delete FILENAME\n"
245 " -ls List the files in the filesystem\n"
246 " -D Dump complete filesystem contents\n");
250 PANIC ("unknown option `%s'", argv[i]);