Diff markup
001 001
>> 002
002 003
003 004
004 005
005 006
006 007
007 008
008 009
009 010
010 011
011 012
012 013
013 014
014 015
015 016
016 017
017 018
018 019
019 #include <sos/errno.h> <<
020 <<
021 020
022 #include <bootstrap/multiboot.h> 021 #include <bootstrap/multiboot.h>
023 #include <hwcore/idt.h> 022 #include <hwcore/idt.h>
024 #include <hwcore/gdt.h> 023 #include <hwcore/gdt.h>
025 #include <hwcore/irq.h> 024 #include <hwcore/irq.h>
026 #include <hwcore/exception.h> 025 #include <hwcore/exception.h>
027 #include <hwcore/i8254.h> 026 #include <hwcore/i8254.h>
028 #include <sos/list.h> 027 #include <sos/list.h>
029 #include <sos/physmem.h> 028 #include <sos/physmem.h>
030 #include <hwcore/paging.h> <<
031 #include <hwcore/mm_context.h> <<
032 #include <hwcore/swintr.h> <<
033 #include <sos/kmem_vmm.h> <<
034 #include <sos/kmalloc.h> <<
035 #include <sos/time.h> <<
036 #include <sos/thread.h> <<
037 #include <sos/process.h> <<
038 #include <sos/umem_vmm.h> <<
039 #include <sos/klibc.h> 029 #include <sos/klibc.h>
040 #include <sos/assert.h> 030 #include <sos/assert.h>
041 #include <drivers/x86_videomem.h> 031 #include <drivers/x86_videomem.h>
042 #include <drivers/bochs.h> 032 #include <drivers/bochs.h>
043 #include <sos/calcload.h> !! 033
044 #include <sos/umem_vmm.h> <<
045 #include <sos/binfmt_elf32.h> <<
046 #include <drivers/zero.h> <<
047 #include <sos/fs.h> <<
048 #include <drivers/fs_virtfs.h> <<
049 #include <drivers/devices.h> <<
050 #include <drivers/mem.h> <<
051 #include <drivers/tty.h> <<
052 #include <drivers/console.h> <<
053 #include <drivers/serial.h> <<
054 #include <sos/blkdev.h> <<
055 #include <sos/fs_pagecache.h> <<
056 #include <drivers/ide.h> <<
057 034
058 035
059 036
060 void display_bits(unsigned char row, unsigned !! 037 static void display_bits(unsigned char row, unsigned char col,
061 unsigned char attribute, !! 038 unsigned char attribute,
062 sos_ui32_t integer) !! 039 sos_ui32_t integer)
063 { 040 {
064 int i; 041 int i;
065 042
066 for (i = 31 ; i >= 0 ; i--) 043 for (i = 31 ; i >= 0 ; i--)
067 { 044 {
068 045
069 int bit_i = (integer & (1 << i)); 046 int bit_i = (integer & (1 << i));
070 047
071 unsigned char ascii_code = bit_i?219:177 048 unsigned char ascii_code = bit_i?219:177;
072 sos_x86_videomem_putchar(row, col++, 049 sos_x86_videomem_putchar(row, col++,
073 attribute, 050 attribute,
074 ascii_code); 051 ascii_code);
075 } 052 }
076 } 053 }
077 054
>> 055
078 056
079 static void clk_it(int intid) 057 static void clk_it(int intid)
080 { 058 {
081 static sos_ui32_t clock_count = 0; 059 static sos_ui32_t clock_count = 0;
082 060
083 display_bits(0, 48, 061 display_bits(0, 48,
084 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 062 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
085 clock_count); 063 clock_count);
086 clock_count++; 064 clock_count++;
087 065
088 <<
089 sos_time_do_tick(); <<
090 <<
091 <<
092 sos_sched_do_timer_tick(); <<
093 } 066 }
094 067
095 !! 068 #define MY_PPAGE_NUM_INT 511
096 !! 069 struct my_ppage
097 <<
098 <<
099 <<
100 <<
101 <<
102 static void pgflt_ex(int intid, struct sos_cpu <<
103 { 070 {
104 static sos_ui32_t demand_paging_count = 0; !! 071 sos_ui32_t before[MY_PPAGE_NUM_INT];
105 struct sos_thread * cur_thr = sos_thread_get !! 072 struct my_ppage *prev, *next;
106 sos_vaddr_t faulting_vaddr = sos_cpu_contex !! 073 sos_ui32_t after[MY_PPAGE_NUM_INT];
107 sos_paddr_t ppage_paddr; !! 074 };
108 !! 075
109 if (sos_cpu_context_is_in_user_mode(ctxt) !! 076 static void test_physmem()
110 || (cur_thr->fixup_uaccess.return_vaddr) !! 077 {
>> 078
>> 079 struct my_ppage *ppage_list, *my_ppage;
>> 080 sos_count_t num_alloc_ppages = 0, num_free_ppages = 0;
>> 081
>> 082 ppage_list = NULL;
>> 083 while ((my_ppage = (struct my_ppage*)sos_physmem_ref_physpage_new(FALSE))
>> 084 != NULL)
111 { 085 {
112 __label__ unforce_address_space; !! 086 int i;
113 sos_bool_t need_to_setup_mmu; !! 087 num_alloc_ppages++;
114 sos_ui32_t errcode = sos_cpu_context_get !! 088
115 !! 089
116 !! 090 sos_x86_videomem_printf(2, 0,
117 !! 091 SOS_X86_VIDEO_FG_YELLOW
118 need_to_setup_mmu = (cur_thr->squatted_m !! 092 | SOS_X86_VIDEO_BG_BLUE,
119 != sos_process_get_ !! 093 "Could allocate %d pages ",
120 if (need_to_setup_mmu) !! 094 num_alloc_ppages);
121 sos_thread_prepare_user_space_access(N !! 095
122 !! 096
123 if (SOS_OK == !! 097 for (i = 0 ; i < MY_PPAGE_NUM_INT ; i++)
124 sos_umem_vmm_try_resolve_page_fault( !! 098 my_ppage->before[i] = my_ppage->after[i] = (sos_ui32_t)my_ppage;
125 !! 099
126 !! 100
127 goto unforce_address_space; !! 101 list_add_tail(ppage_list, my_ppage);
128 !! 102 }
129 !! 103
130 !! 104
131 if (! sos_cpu_context_is_in_user_mode(ct !! 105 while ((my_ppage = list_pop_head(ppage_list)) != NULL)
>> 106 {
>> 107
>> 108
>> 109 int i;
>> 110 for (i = 0 ; i < MY_PPAGE_NUM_INT ; i++)
132 { 111 {
133 cur_thr->fixup_uaccess.faulted_uaddr !! 112
134 sos_cpu_context_set_EX_return_addres !! 113 if ((my_ppage->before[i] != (sos_ui32_t)my_ppage)
135 !! 114 || (my_ppage->after[i] != (sos_ui32_t)my_ppage))
136 goto unforce_address_space; !! 115 {
>> 116
>> 117 sos_x86_videomem_putstring(20, 0,
>> 118 SOS_X86_VIDEO_FG_LTRED
>> 119 | SOS_X86_VIDEO_BG_BLUE,
>> 120 "Page overwritten");
>> 121 return;
>> 122 }
137 } 123 }
138 124
139 if (need_to_setup_mmu) !! 125
140 sos_thread_end_user_space_access(); !! 126 if (sos_physmem_unref_physpage((sos_paddr_t)my_ppage) < 0)
141 !! 127 {
142 sos_bochs_printf("\e[35mTHR %p: Unresolv !! 128
143 (void*)sos_thread_get_c !! 129 sos_x86_videomem_putstring(20, 0,
144 sos_cpu_context_get_PC( !! 130 SOS_X86_VIDEO_FG_LTRED
145 (unsigned)faulting_vadd !! 131 | SOS_X86_VIDEO_BG_BLUE,
146 (unsigned)sos_cpu_conte !! 132 "Cannot release page");
147 sos_bochs_printf("Terminating User threa !! 133 return;
148 sos_thread_exit(); !! 134 }
149 <<
150 unforce_address_space: <<
151 if (need_to_setup_mmu) <<
152 sos_thread_end_user_space_access(); <<
153 return; <<
154 } <<
155 <<
156 <<
157 if (! sos_kmem_vmm_is_valid_vaddr(faulting_v <<
158 { <<
159 <<
160 <<
161 sos_display_fatal_error("Unresolved page <<
162 sos_cpu_context_ <<
163 (unsigned)faulti <<
164 (unsigned)sos_cp <<
165 SOS_ASSERT_FATAL(! "Got page fault (note <<
166 } <<
167 <<
168 <<
169 <<
170 <<
171 <<
172 <<
173 <<
174 demand_paging_count ++; <<
175 display_bits(0, 0, <<
176 SOS_X86_VIDEO_FG_LTRED | SOS_X8 <<
177 demand_paging_count); <<
178 <<
179 <<
180 ppage_paddr = sos_physmem_ref_physpage_new(F <<
181 if (! ppage_paddr) <<
182 SOS_ASSERT_FATAL(! "TODO: implement swap. <<
183 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp <<
184 SO <<
185 FA <<
186 SO <<
187 | <<
188 | <<
189 sos_physmem_unref_physpage(ppage_paddr); <<
190 <<
191 <<
192 } <<
193 <<
194 <<
195 <<
196 <<
197 <<
198 <<
199 <<
200 static void idle_thread(void* unused) __attrib <<
201 static void idle_thread(void* unused) <<
202 { <<
203 sos_ui32_t idle_twiddle = 0; <<
204 <<
205 while (1) <<
206 { <<
207 <<
208 <<
209 asm("hlt\n"); <<
210 <<
211 idle_twiddle ++; <<
212 display_bits(0, 0, SOS_X86_VIDEO_FG_GREE <<
213 idle_twiddle); <<
214 <<
215 <<
216 sos_thread_yield(); <<
217 } <<
218 } <<
219 <<
220 <<
221 <<
222 <<
223 <<
224 #define LOAD_DISPLAY_BASELINE 4 <<
225 #define LOAD_DISPLAY_STARTROW 34 <<
226 static void stat_thread(void * unused) __attri <<
227 static void stat_thread(void * unused) <<
228 { <<
229 while (1) <<
230 { <<
231 sos_ui32_t flags; <<
232 sos_ui32_t load1, load5, load15; <<
233 char str1[11], str5[11], str15[11]; <<
234 struct sos_time t; <<
235 t.sec = 1; <<
236 t.nanosec = 0; <<
237 <<
238 sos_thread_sleep(& t); <<
239 <<
240 sos_disable_IRQs(flags); <<
241 <<
242 <<
243 sos_load_get_sload(&load1, &load5, &load <<
244 sos_load_to_string(str1, load1); <<
245 sos_load_to_string(str5, load5); <<
246 sos_load_to_string(str15, load15); <<
247 sos_x86_videomem_printf(LOAD_DISPLAY_BAS <<
248 SOS_X86_VIDEO_FG <<
249 "Kernel (- Idle) <<
250 str1, str5, str1 <<
251 <<
252 sos_load_get_uload(&load1, &load5, &load <<
253 sos_load_to_string(str1, load1); <<
254 sos_load_to_string(str5, load5); <<
255 sos_load_to_string(str15, load15); <<
256 sos_x86_videomem_printf(LOAD_DISPLAY_BAS <<
257 SOS_X86_VIDEO_FG <<
258 "User: %s %s %s <<
259 str1, str5, str1 <<
260 <<
261 sos_load_get_uratio(&load1, &load5, &loa <<
262 sos_load_to_string(str1, load1); <<
263 sos_load_to_string(str5, load5); <<
264 sos_load_to_string(str15, load15); <<
265 sos_x86_videomem_printf(LOAD_DISPLAY_BAS <<
266 SOS_X86_VIDEO_FG <<
267 "User CPU %%: %s <<
268 str1, str5, str1 <<
269 <<
270 <<
271 sos_load_get_sratio(&load1, &load5, &loa <<
272 sos_load_to_string(str1, load1); <<
273 sos_load_to_string(str5, load5); <<
274 sos_load_to_string(str15, load15); <<
275 sos_x86_videomem_printf(LOAD_DISPLAY_BAS <<
276 SOS_X86_VIDEO_FG <<
277 "Kernel CPU %% ( <<
278 str1, str5, str1 <<
279 sos_restore_IRQs(flags); <<
280 } <<
281 } <<
282 <<
283 <<
284 <<
285 <<
286 <<
287 static sos_ret_t <<
288 start_init(struct sos_fs_manager_instance * ro <<
289 { <<
290 sos_ret_t retval; <<
291 struct sos_umem_vmm_as *as_init; <<
292 struct sos_process *proc_init; <<
293 struct sos_thread *new_thr; <<
294 sos_uaddr_t ustack, start_uaddr; <<
295 struct sos_fs_opened_file * init_root, * ini <<
296 <<
297 <<
298 proc_init = sos_process_create("init", FALSE <<
299 if (! proc_init) <<
300 return -SOS_ENOMEM; <<
301 as_init = sos_process_get_address_space(proc <<
302 <<
303 <<
304 <<
305 <<
306 <<
307 <<
308 <<
309 retval = sos_fs_new_opened_file(proc_init, r <<
310 SOS_FS_OPEN_ <<
311 & init_root) <<
312 if (SOS_OK != retval) <<
313 { <<
314 sos_process_unref(proc_init); <<
315 return -SOS_ENOENT; <<
316 } <<
317 <<
318 <<
319 <<
320 retval = sos_fs_duplicate_opened_file(init_r <<
321 & init <<
322 if (SOS_OK != retval) <<
323 { <<
324 sos_fs_close(init_root); <<
325 sos_process_unref(proc_init); <<
326 return -SOS_ENOENT; <<
327 } <<
328 <<
329 <<
330 if ( ( SOS_OK != sos_process_chroot(proc_ini <<
331 || ( SOS_OK != sos_process_chdir(proc_i <<
332 { <<
333 sos_fs_close(init_root); <<
334 sos_fs_close(init_cwd); <<
335 sos_process_chroot(proc_init, NULL, & un <<
336 sos_process_chdir(proc_init, NULL, & unu <<
337 sos_process_unref(proc_init); <<
338 return -SOS_ENOENT; <<
339 } <<
340 <<
341 <<
342 <<
343 <<
344 start_uaddr = sos_binfmt_elf32_map(as_init, <<
345 if (0 == start_uaddr) <<
346 { <<
347 sos_process_unref(proc_init); <<
348 return -SOS_ENOENT; <<
349 } <<
350 135
351 !! 136
352 ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_ !! 137 num_free_ppages ++;
353 retval = sos_dev_zero_map(as_init, &ustack, !! 138 sos_x86_videomem_printf(2, 0,
354 SOS_VM_MAP_PROT_RE !! 139 SOS_X86_VIDEO_FG_YELLOW
355 0); !! 140 | SOS_X86_VIDEO_BG_BLUE,
356 if (SOS_OK != retval) !! 141 "Could free %d pages ",
357 { !! 142 num_free_ppages);
358 sos_process_unref(proc_init); <<
359 return -SOS_ENOMEM; <<
360 } 143 }
361 144
362 !! 145
363 new_thr = sos_create_user_thread(NULL, !! 146 sos_x86_videomem_printf(2, 0,
364 proc_init, !! 147 SOS_X86_VIDEO_FG_LTGREEN
365 start_uaddr !! 148 | SOS_X86_VIDEO_BG_BLUE,
366 0, 0, !! 149 "Could allocate %d bytes, could free %d bytes ",
367 ustack + SO !! 150 num_alloc_ppages << SOS_PAGE_SHIFT,
368 SOS_SCHED_P !! 151 num_free_ppages << SOS_PAGE_SHIFT);
369 if (! new_thr) <<
370 { <<
371 sos_process_unref(proc_init); <<
372 return -SOS_ENOMEM; <<
373 } <<
374 152
375 sos_process_unref(proc_init); !! 153 SOS_ASSERT_FATAL(num_alloc_ppages == num_free_ppages);
376 return SOS_OK; <<
377 } 154 }
378 155
379 156
380 !! 157
381 !! 158 void sos_main(unsigned long magic, unsigned long addr)
382 <<
383 <<
384 void sos_main(unsigned long magic, unsigned lo <<
385 __attribute__((noreturn)); <<
386 void sos_main(unsigned long magic, unsigned lo <<
387 { 159 {
>> 160 unsigned i;
388 sos_paddr_t sos_kernel_core_base_paddr, sos_ 161 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
389 struct sos_time tick_resolution; <<
390 struct sos_fs_manager_instance * rootfs; <<
391 162
392 !! 163
393 unsigned long int upper_mem = 0; !! 164
>> 165
>> 166 multiboot_info_t *mbi;
>> 167 mbi = (multiboot_info_t *) addr;
394 168
395 169
396 sos_bochs_subsystem_setup(); !! 170 sos_bochs_setup();
397 171
398 sos_x86_videomem_setup(); 172 sos_x86_videomem_setup();
399 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 173 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
400 174
401 175
402 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 176 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
403 { !! 177
404 !! 178 sos_x86_videomem_printf(1, 0,
405 !! 179 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
406 !! 180 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
407 multiboot_info_t *mbi = (multiboot_info_ !! 181 "SOS", ',',
408 !! 182 (unsigned)(mbi->mem_upper >> 10) + 1,
409 !! 183 (unsigned)mbi->mem_upper);
410 <<
411 <<
412 <<
413 upper_mem = mbi->mem_upper; <<
414 sos_x86_videomem_printf(1, 0, <<
415 SOS_X86_VIDEO_FG <<
416 "Welcome From GR <<
417 "SOS article 9.5 <<
418 (unsigned)(upper <<
419 (unsigned)upper_ <<
420 } <<
421 else if (magic == 0x42244224) <<
422 { <<
423 <<
424 upper_mem = arg; <<
425 sos_x86_videomem_printf(1, 0, <<
426 SOS_X86_VIDEO_FG <<
427 "Welcome to %s%c <<
428 "SOS article 9.5 <<
429 (unsigned)(upper <<
430 (unsigned)upper_ <<
431 } <<
432 else 184 else
433 !! 185
434 sos_x86_videomem_printf(1, 0, 186 sos_x86_videomem_printf(1, 0,
435 SOS_X86_VIDEO_FG_Y 187 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
436 "Welcome to SOS ar !! 188 "Welcome to SOS");
437 189
438 sos_bochs_putstring("Message in a bochs: Thi !! 190 sos_bochs_putstring("Message in a bochs\n");
439 191
440 192
441 sos_gdt_subsystem_setup(); !! 193 sos_gdt_setup();
442 sos_idt_subsystem_setup(); !! 194 sos_idt_setup();
443 195
444 196
445 sos_exception_subsystem_setup(); !! 197 sos_exceptions_setup();
446 sos_irq_subsystem_setup(); !! 198 sos_irq_setup();
447 199
448 200
449 sos_i8254_set_frequency(100); 201 sos_i8254_set_frequency(100);
450 202
451 <<
452 <<
453 tick_resolution = (struct sos_time) { .sec=0 <<
454 sos_time_subsysem_setup(& tick_resolution); <<
455 203
456 !! 204
457 if (upper_mem == 0) !! 205 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
458 { 206 {
459 sos_x86_videomem_putstring(20, 0, 207 sos_x86_videomem_putstring(20, 0,
460 SOS_X86_VIDEO 208 SOS_X86_VIDEO_FG_LTRED
461 | SOS_X86_V 209 | SOS_X86_VIDEO_BG_BLUE
462 | SOS_X86_V 210 | SOS_X86_VIDEO_FG_BLINKING,
463 "I don't know !! 211 "I'm not loaded with Grub !");
464 212
465 for (;;) 213 for (;;)
466 continue; 214 continue;
467 } 215 }
468 216
469 <<
470 <<
471 <<
472 <<
473 217
474 sos_irq_set_routine(SOS_IRQ_TIMER, 218 sos_irq_set_routine(SOS_IRQ_TIMER,
475 clk_it); !! 219 clk_it);
476 <<
477 <<
478 <<
479 <<
480 <<
481 SOS_ASSERT_FATAL(SOS_OK <<
482 == sos_physmem_subsystem_se <<
483 <<
484 <<
485 <<
486 <<
487 <<
488 <<
489 <<
490 <<
491 <<
492 SOS_ASSERT_FATAL(SOS_OK == <<
493 sos_paging_subsystem_setup( <<
494 <<
495 <<
496 <<
497 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA <<
498 pgflt_ex); <<
499 <<
500 <<
501 <<
502 <<
503 <<
504 if (sos_kmem_vmm_subsystem_setup(sos_kernel_ <<
505 sos_kernel_ <<
506 bootstrap_s <<
507 bootstrap_s <<
508 + bootstrap <<
509 sos_bochs_printf("Could not setup the Kern <<
510 <<
511 if (sos_kmalloc_subsystem_setup()) <<
512 sos_bochs_printf("Could not setup the Kmal <<
513 <<
514 <<
515 <<
516 <<
517 sos_mm_context_subsystem_setup(); <<
518 <<
519 <<
520 <<
521 <<
522 sos_cpu_context_subsystem_setup(); <<
523 <<
524 <<
525 <<
526 <<
527 sos_swintr_subsystem_setup(); <<
528 <<
529 <<
530 <<
531 <<
532 <<
533 <<
534 <<
535 sos_thread_subsystem_setup(bootstrap_stack_b <<
536 bootstrap_stack_s <<
537 <<
538 <<
539 sos_sched_subsystem_setup(); <<
540 <<
541 <<
542 SOS_ASSERT_FATAL(sos_create_kernel_thread("i <<
543 SO <<
544 <<
545 <<
546 sos_load_subsystem_setup(); <<
547 <<
548 <<
549 SOS_ASSERT_FATAL(sos_create_kernel_thread("s <<
550 NU <<
551 SO <<
552 <<
553 <<
554 <<
555 <<
556 <<
557 sos_umem_vmm_subsystem_setup(); <<
558 sos_dev_zero_subsystem_setup(); <<
559 <<
560 <<
561 sos_fs_pagecache_subsystem_setup(); <<
562 sos_blockdev_subsystem_setup(); <<
563 sos_dev_mem_chardev_setup(); <<
564 <<
565 <<
566 <<
567 <<
568 sos_process_subsystem_setup(); <<
569 <<
570 <<
571 220
572 !! 221
573 asm volatile ("sti\n"); 222 asm volatile ("sti\n");
>> 223
>> 224
>> 225
>> 226 sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
>> 227 & sos_kernel_core_base_paddr,
>> 228 & sos_kernel_core_top_paddr);
>> 229 test_physmem();
>> 230
>> 231
>> 232 for (;;)
>> 233 continue;
574 234
575 !! 235 return;
576 SOS_ASSERT_FATAL(SOS_OK == sos_fs_virtfs_sub <<
577 SOS_ASSERT_FATAL(SOS_OK == sos_fs_subsystem_ <<
578 <<
579 <<
580 <<
581 <<
582 <<
583 tty_subsystem_setup(); <<
584 sos_ttyS0_subsystem_setup(); <<
585 sos_console_subsystem_setup(); <<
586 <<
587 <<
588 sos_ide_subsystem_setup(); <<
589 <<
590 <<
591 <<
592 <<
593 <<
594 start_init(rootfs); <<
595 <<
596 <<
597 <<
598 <<
599 <<
600 <<
601 <<
602 <<
603 <<
604 <<
605 <<
606 <<
607 sos_bochs_printf("Bye from primary thread !\ <<
608 sos_thread_exit(); <<
609 SOS_FATAL_ERROR("No trespassing !"); <<
610 } 236 }