Diff markup
001 001
002 <<
003 002
004 003
005 004
006 005
007 006
008 007
009 008
010 009
011 010
012 011
013 012
014 013
015 014
016 015
017 016
018 017
019 018
020 019
021 #include <bootstrap/multiboot.h> 020 #include <bootstrap/multiboot.h>
>> 021 #include <hwcore/idt.h>
>> 022 #include <hwcore/gdt.h>
>> 023 #include <hwcore/irq.h>
>> 024 #include <hwcore/exception.h>
>> 025 #include <hwcore/i8254.h>
>> 026 #include <sos/list.h>
>> 027 #include <sos/physmem.h>
>> 028 #include <hwcore/paging.h>
>> 029 #include <sos/kmem_vmm.h>
>> 030 #include <sos/kmalloc.h>
>> 031 #include <sos/time.h>
>> 032 #include <sos/thread.h>
022 #include <sos/klibc.h> 033 #include <sos/klibc.h>
023 #include <sos/assert.h> 034 #include <sos/assert.h>
024 #include <drivers/x86_videomem.h> 035 #include <drivers/x86_videomem.h>
025 #include <drivers/bochs.h> 036 #include <drivers/bochs.h>
026 037
027 038
>> 039
>> 040
>> 041 void display_bits(unsigned char row, unsigned char col,
>> 042 unsigned char attribute,
>> 043 sos_ui32_t integer)
>> 044 {
>> 045 int i;
>> 046
>> 047 for (i = 31 ; i >= 0 ; i--)
>> 048 {
>> 049
>> 050 int bit_i = (integer & (1 << i));
>> 051
>> 052 unsigned char ascii_code = bit_i?219:177;
>> 053 sos_x86_videomem_putchar(row, col++,
>> 054 attribute,
>> 055 ascii_code);
>> 056 }
>> 057 }
>> 058
>> 059
>> 060
>> 061 static void clk_it(int intid)
>> 062 {
>> 063 static sos_ui32_t clock_count = 0;
>> 064
>> 065 display_bits(0, 48,
>> 066 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
>> 067 clock_count);
>> 068 clock_count++;
>> 069
>> 070
>> 071 sos_time_do_tick();
>> 072 }
>> 073
>> 074
>> 075
>> 076
>> 077
>> 078
>> 079
>> 080 static void dump_backtrace(const struct sos_cpu_state *cpu_state,
>> 081 sos_vaddr_t stack_bottom,
>> 082 sos_size_t stack_size,
>> 083 sos_bool_t on_console,
>> 084 sos_bool_t on_bochs)
>> 085 {
>> 086 static void backtracer(sos_vaddr_t PC,
>> 087 sos_vaddr_t params,
>> 088 sos_ui32_t depth,
>> 089 void *custom_arg)
>> 090 {
>> 091 sos_ui32_t invalid = 0xffffffff, *arg1, *arg2, *arg3, *arg4;
>> 092
>> 093
>> 094
>> 095
>> 096
>> 097 arg1 = (sos_ui32_t*)params;
>> 098 arg2 = (sos_ui32_t*)(params+4);
>> 099 arg3 = (sos_ui32_t*)(params+8);
>> 100 arg4 = (sos_ui32_t*)(params+12);
>> 101
>> 102
>> 103
>> 104 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vaddr_t)(v)) \
>> 105 && ((sos_vaddr_t)(v) < (u)) )
>> 106 if (!INTERVAL_OK(stack_bottom, arg1, stack_bottom + stack_size))
>> 107 arg1 = &invalid;
>> 108 if (!INTERVAL_OK(stack_bottom, arg2, stack_bottom + stack_size))
>> 109 arg2 = &invalid;
>> 110 if (!INTERVAL_OK(stack_bottom, arg3, stack_bottom + stack_size))
>> 111 arg3 = &invalid;
>> 112 if (!INTERVAL_OK(stack_bottom, arg4, stack_bottom + stack_size))
>> 113 arg4 = &invalid;
>> 114
>> 115
>> 116 if (on_bochs)
>> 117 sos_bochs_printf("[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n",
>> 118 (unsigned)depth, (unsigned)PC,
>> 119 (unsigned)*arg1, (unsigned)*arg2,
>> 120 (unsigned)*arg3);
>> 121
>> 122 if (on_console)
>> 123 sos_x86_videomem_printf(23-depth, 3,
>> 124 SOS_X86_VIDEO_BG_BLUE
>> 125 | SOS_X86_VIDEO_FG_LTGREEN,
>> 126 "[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x arg4=0x%x",
>> 127 (unsigned)depth, PC,
>> 128 (unsigned)*arg1, (unsigned)*arg2,
>> 129 (unsigned)*arg3, (unsigned)*arg4);
>> 130
>> 131 }
>> 132
>> 133 sos_backtrace(cpu_state, 15, stack_bottom, stack_size, backtracer, NULL);
>> 134 }
>> 135
>> 136
>> 137
>> 138 static void pgflt_ex(int intid, const struct sos_cpu_state *ctxt)
>> 139 {
>> 140 static sos_ui32_t demand_paging_count = 0;
>> 141 sos_vaddr_t faulting_vaddr = sos_cpu_context_get_EX_faulting_vaddr(ctxt);
>> 142 sos_paddr_t ppage_paddr;
>> 143
>> 144
>> 145 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
>> 146 {
>> 147
>> 148
>> 149 dump_backtrace(ctxt,
>> 150 bootstrap_stack_bottom,
>> 151 bootstrap_stack_size,
>> 152 TRUE, TRUE);
>> 153 sos_display_fatal_error("Unresolved page Fault at instruction 0x%x on access to address 0x%x (info=%x)!",
>> 154 sos_cpu_context_get_PC(ctxt),
>> 155 (unsigned)faulting_vaddr,
>> 156 (unsigned)sos_cpu_context_get_EX_info(ctxt));
>> 157 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
>> 158 }
>> 159
>> 160
>> 161
>> 162
>> 163
>> 164
>> 165
>> 166 demand_paging_count ++;
>> 167 display_bits(0, 0,
>> 168 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 169 demand_paging_count);
>> 170
>> 171
>> 172 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
>> 173 if (! ppage_paddr)
>> 174 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
>> 175 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
>> 176 SOS_PAGE_ALIGN_INF(faulting_vaddr),
>> 177 FALSE,
>> 178 SOS_VM_MAP_PROT_READ
>> 179 | SOS_VM_MAP_PROT_WRITE
>> 180 | SOS_VM_MAP_ATOMIC));
>> 181 sos_physmem_unref_physpage(ppage_paddr);
>> 182
>> 183
>> 184 }
>> 185
>> 186
>> 187
>> 188
>> 189
>> 190
>> 191
>> 192
>> 193
>> 194 struct thr_arg
>> 195 {
>> 196 char character;
>> 197 int color;
>> 198
>> 199 int col;
>> 200 int row;
>> 201 };
>> 202
>> 203
>> 204 static void demo_thread(void *arg)
>> 205 {
>> 206 struct thr_arg *thr_arg = (struct thr_arg*)arg;
>> 207 int progress = 0;
>> 208
>> 209 sos_bochs_printf("start %c", thr_arg->character);
>> 210 while (1)
>> 211 {
>> 212 progress ++;
>> 213 display_bits(thr_arg->row, thr_arg->col+1, thr_arg->color, progress);
>> 214
>> 215 sos_bochs_putchar(thr_arg->character);
>> 216
>> 217
>> 218 if ((random() % 100) == 0)
>> 219 {
>> 220 sos_bochs_printf("[37myield(%c)[m\n", thr_arg->character);
>> 221 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'Y');
>> 222 SOS_ASSERT_FATAL(SOS_OK == sos_thread_yield());
>> 223 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 224 }
>> 225
>> 226
>> 227 else if ((random() % 200) == 0)
>> 228 {
>> 229 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=50000000 };
>> 230 sos_bochs_printf("[37msleep1(%c)[m\n", thr_arg->character);
>> 231 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 's');
>> 232 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
>> 233 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
>> 234 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 235 }
>> 236
>> 237
>> 238 else if ((random() % 300) == 0)
>> 239 {
>> 240 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=300000000 };
>> 241 sos_bochs_printf("[37msleep2(%c)[m\n", thr_arg->character);
>> 242 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'S');
>> 243 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
>> 244 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
>> 245 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 246 }
>> 247
>> 248
>> 249 }
>> 250 }
028 251
029 !! 252
>> 253 static void test_thread()
>> 254 {
>> 255
>> 256
>> 257 static struct thr_arg arg_b, arg_c, arg_d, arg_e, arg_R, arg_S;
>> 258 sos_ui32_t flags;
>> 259
>> 260 sos_disable_IRQs(flags);
>> 261
>> 262 arg_b = (struct thr_arg) { .character='b', .col=0, .row=21, .color=0x14 };
>> 263 sos_create_kernel_thread("YO[b]", demo_thread, (void*)&arg_b);
>> 264
>> 265 arg_c = (struct thr_arg) { .character='c', .col=46, .row=21, .color=0x14 };
>> 266 sos_create_kernel_thread("YO[c]", demo_thread, (void*)&arg_c);
>> 267
>> 268 arg_d = (struct thr_arg) { .character='d', .col=0, .row=20, .color=0x14 };
>> 269 sos_create_kernel_thread("YO[d]", demo_thread, (void*)&arg_d);
>> 270
>> 271 arg_e = (struct thr_arg) { .character='e', .col=0, .row=19, .color=0x14 };
>> 272 sos_create_kernel_thread("YO[e]", demo_thread, (void*)&arg_e);
>> 273
>> 274 arg_R = (struct thr_arg) { .character='R', .col=0, .row=17, .color=0x1c };
>> 275 sos_create_kernel_thread("YO[R]", demo_thread, (void*)&arg_R);
>> 276
>> 277 arg_S = (struct thr_arg) { .character='S', .col=0, .row=16, .color=0x1c };
>> 278 sos_create_kernel_thread("YO[S]", demo_thread, (void*)&arg_S);
>> 279
>> 280 sos_restore_IRQs(flags);
>> 281 }
>> 282
>> 283
>> 284
>> 285
>> 286
>> 287
>> 288 static void idle_thread()
>> 289 {
>> 290 sos_ui32_t idle_twiddle = 0;
>> 291
>> 292 while (1)
>> 293 {
>> 294
>> 295
>> 296 asm("hlt\n");
>> 297
>> 298 idle_twiddle ++;
>> 299 display_bits(0, 0, SOS_X86_VIDEO_FG_GREEN | SOS_X86_VIDEO_BG_BLUE,
>> 300 idle_twiddle);
>> 301
>> 302
>> 303 sos_thread_yield();
>> 304 }
>> 305 }
>> 306
>> 307
>> 308
>> 309
>> 310
030 void sos_main(unsigned long magic, unsigned lo 311 void sos_main(unsigned long magic, unsigned long addr)
031 { 312 {
032 unsigned i; 313 unsigned i;
>> 314 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
>> 315 struct sos_time tick_resolution;
033 316
034 317
035 318
036 319
037 multiboot_info_t *mbi; 320 multiboot_info_t *mbi;
038 mbi = (multiboot_info_t *) addr; 321 mbi = (multiboot_info_t *) addr;
039 322
040 323
041 sos_bochs_setup(); 324 sos_bochs_setup();
042 325
043 sos_x86_videomem_setup(); 326 sos_x86_videomem_setup();
044 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 327 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
045 328
046 329
047 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 330 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
048 331
049 sos_x86_videomem_printf(1, 0, 332 sos_x86_videomem_printf(1, 0,
050 SOS_X86_VIDEO_FG_Y 333 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
051 "Welcome From GRUB 334 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
052 "SOS", ',', !! 335 "SOS article 6.5", ',',
053 (unsigned)(mbi->me 336 (unsigned)(mbi->mem_upper >> 10) + 1,
054 (unsigned)mbi->mem 337 (unsigned)mbi->mem_upper);
055 else 338 else
056 339
057 sos_x86_videomem_printf(1, 0, 340 sos_x86_videomem_printf(1, 0,
058 SOS_X86_VIDEO_FG_Y 341 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
059 "Welcome to SOS"); !! 342 "Welcome to SOS article 6.5");
060 <<
061 sos_bochs_putstring("Message in a bochs\n"); <<
062 <<
063 343
064 !! 344 sos_bochs_putstring("Message in a bochs: This is SOS article 6.5.\n");
065 for (;;) <<
066 continue; <<
067 345
068 return; !! 346
>> 347 sos_gdt_subsystem_setup();
>> 348 sos_idt_subsystem_setup();
>> 349
>> 350
>> 351 sos_exception_subsystem_setup();
>> 352 sos_irq_subsystem_setup();
>> 353
>> 354
>> 355 sos_i8254_set_frequency(100);
>> 356
>> 357
>> 358
>> 359 tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL };
>> 360 sos_time_subsysem_setup(& tick_resolution);
>> 361
>> 362
>> 363 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
>> 364 {
>> 365 sos_x86_videomem_putstring(20, 0,
>> 366 SOS_X86_VIDEO_FG_LTRED
>> 367 | SOS_X86_VIDEO_BG_BLUE
>> 368 | SOS_X86_VIDEO_FG_BLINKING,
>> 369 "I'm not loaded with Grub !");
>> 370
>> 371 for (;;)
>> 372 continue;
>> 373 }
>> 374
>> 375
>> 376
>> 377
>> 378
>> 379
>> 380 sos_irq_set_routine(SOS_IRQ_TIMER,
>> 381 clk_it);
>> 382
>> 383
>> 384
>> 385
>> 386
>> 387
>> 388
>> 389
>> 390 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
>> 391 & sos_kernel_core_base_paddr,
>> 392 & sos_kernel_core_top_paddr);
>> 393
>> 394
>> 395
>> 396
>> 397
>> 398
>> 399
>> 400 SOS_ASSERT_FATAL(SOS_OK ==
>> 401 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
>> 402 sos_kernel_core_top_paddr));
>> 403
>> 404
>> 405 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
>> 406 pgflt_ex);
>> 407
>> 408
>> 409
>> 410
>> 411
>> 412 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
>> 413 sos_kernel_core_top_paddr,
>> 414 bootstrap_stack_bottom,
>> 415 bootstrap_stack_bottom
>> 416 + bootstrap_stack_size))
>> 417 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
>> 418
>> 419 if (sos_kmalloc_subsystem_setup())
>> 420 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
>> 421
>> 422
>> 423
>> 424
>> 425
>> 426
>> 427 sos_thread_subsystem_setup(bootstrap_stack_bottom,
>> 428 bootstrap_stack_size);
>> 429
>> 430
>> 431 sos_sched_subsystem_setup();
>> 432
>> 433
>> 434 SOS_ASSERT_FATAL(sos_create_kernel_thread("idle", idle_thread, NULL) != NULL);
>> 435
>> 436
>> 437
>> 438 asm volatile ("sti\n");
>> 439
>> 440
>> 441
>> 442 extern void MouseSim();
>> 443 MouseSim();
>> 444 test_thread();
>> 445
>> 446
>> 447
>> 448
>> 449
>> 450
>> 451
>> 452
>> 453
>> 454
>> 455
>> 456
>> 457
>> 458 sos_bochs_printf("Bye from primary thread !\n");
>> 459 sos_thread_exit();
>> 460 SOS_FATAL_ERROR("No trespassing !");
069 } 461 }