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>
022 #include <hwcore/idt.h> 021 #include <hwcore/idt.h>
023 #include <hwcore/gdt.h> 022 #include <hwcore/gdt.h>
024 #include <hwcore/irq.h> 023 #include <hwcore/irq.h>
025 #include <hwcore/exception.h> 024 #include <hwcore/exception.h>
026 #include <hwcore/i8254.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>
027 #include <sos/klibc.h> 033 #include <sos/klibc.h>
028 #include <sos/assert.h> 034 #include <sos/assert.h>
029 #include <drivers/x86_videomem.h> 035 #include <drivers/x86_videomem.h>
030 #include <drivers/bochs.h> 036 #include <drivers/bochs.h>
031 037
032 038
033 039
034 040
035 static void display_bits(unsigned char row, un !! 041 void display_bits(unsigned char row, unsigned char col,
036 unsigned char attribu !! 042 unsigned char attribute,
037 sos_ui32_t integer) !! 043 sos_ui32_t integer)
038 { 044 {
039 int i; 045 int i;
040 046
041 for (i = 31 ; i >= 0 ; i--) 047 for (i = 31 ; i >= 0 ; i--)
042 { 048 {
043 049
044 int bit_i = (integer & (1 << i)); 050 int bit_i = (integer & (1 << i));
045 051
046 unsigned char ascii_code = bit_i?219:177 052 unsigned char ascii_code = bit_i?219:177;
047 sos_x86_videomem_putchar(row, col++, 053 sos_x86_videomem_putchar(row, col++,
048 attribute, 054 attribute,
049 ascii_code); 055 ascii_code);
050 } 056 }
051 } 057 }
052 058
053 059
054 060
055 static void clk_it(int intid) 061 static void clk_it(int intid)
056 { 062 {
057 static sos_ui32_t clock_count = 0; 063 static sos_ui32_t clock_count = 0;
058 064
059 display_bits(0, 48, 065 display_bits(0, 48,
060 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 066 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
061 clock_count); 067 clock_count);
062 clock_count++; 068 clock_count++;
063 069
>> 070
>> 071 sos_time_do_tick();
064 } 072 }
065 073
066 !! 074
067 static void divide_ex(int exid) !! 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)
068 { 139 {
069 static sos_ui32_t div_count = 0; !! 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 ++;
070 display_bits(0, 0, 167 display_bits(0, 0,
071 SOS_X86_VIDEO_FG_LTRED | SOS_X8 168 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
072 div_count); !! 169 demand_paging_count);
073 div_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 }
>> 251
>> 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);
074 } 281 }
075 282
076 !! 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
077 void sos_main(unsigned long magic, unsigned lo 311 void sos_main(unsigned long magic, unsigned long addr)
078 { 312 {
079 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;
080 316
081 317
082 318
083 319
084 multiboot_info_t *mbi; 320 multiboot_info_t *mbi;
085 mbi = (multiboot_info_t *) addr; 321 mbi = (multiboot_info_t *) addr;
086 322
087 323
088 sos_bochs_setup(); 324 sos_bochs_setup();
089 325
090 sos_x86_videomem_setup(); 326 sos_x86_videomem_setup();
091 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 327 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
092 328
093 329
094 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 330 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
095 331
096 sos_x86_videomem_printf(1, 0, 332 sos_x86_videomem_printf(1, 0,
097 SOS_X86_VIDEO_FG_Y 333 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
098 "Welcome From GRUB 334 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
099 "SOS", ',', !! 335 "SOS article 6.5", ',',
100 (unsigned)(mbi->me 336 (unsigned)(mbi->mem_upper >> 10) + 1,
101 (unsigned)mbi->mem 337 (unsigned)mbi->mem_upper);
102 else 338 else
103 339
104 sos_x86_videomem_printf(1, 0, 340 sos_x86_videomem_printf(1, 0,
105 SOS_X86_VIDEO_FG_Y 341 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
106 "Welcome to SOS"); !! 342 "Welcome to SOS article 6.5");
107 343
108 sos_bochs_putstring("Message in a bochs\n"); !! 344 sos_bochs_putstring("Message in a bochs: This is SOS article 6.5.\n");
109 345
110 346
111 sos_gdt_setup(); !! 347 sos_gdt_subsystem_setup();
112 sos_idt_setup(); !! 348 sos_idt_subsystem_setup();
113 349
114 350
115 sos_exceptions_setup(); !! 351 sos_exception_subsystem_setup();
116 sos_irq_setup(); !! 352 sos_irq_subsystem_setup();
117 353
118 354
119 sos_i8254_set_frequency(100); 355 sos_i8254_set_frequency(100);
120 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
121 379
122 sos_irq_set_routine(SOS_IRQ_TIMER, 380 sos_irq_set_routine(SOS_IRQ_TIMER,
123 clk_it); !! 381 clk_it);
124 sos_exception_set_routine(SOS_EXCEPT_DIVIDE_ !! 382
125 divide_ex); !! 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
126 436
127 !! 437
128 asm volatile ("sti\n"); 438 asm volatile ("sti\n");
129 439
130 <<
131 <<
132 <<
133 <<
134 i = 10; <<
135 while (1) <<
136 { <<
137 <<
138 sos_bochs_printf("i = 1 / %d...\n", i); <<
139 i = 1 / i; <<
140 } <<
141 <<
142 <<
143 <<
144 <<
145 <<
146 sos_x86_videomem_putstring(2, 0, <<
147 SOS_X86_VIDEO_FG_ <<
148 "Invisible"); <<
149 440
150 return; !! 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 !");
151 } 461 }