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>
027 #include <sos/list.h> 026 #include <sos/list.h>
028 #include <sos/physmem.h> 027 #include <sos/physmem.h>
>> 028 #include <hwcore/paging.h>
>> 029 #include <hwcore/mm_context.h>
>> 030 #include <hwcore/swintr.h>
>> 031 #include <sos/kmem_vmm.h>
>> 032 #include <sos/kmalloc.h>
>> 033 #include <sos/time.h>
>> 034 #include <sos/thread.h>
>> 035 #include <sos/process.h>
>> 036 #include <sos/umem_vmm.h>
029 #include <sos/klibc.h> 037 #include <sos/klibc.h>
030 #include <sos/assert.h> 038 #include <sos/assert.h>
031 #include <drivers/x86_videomem.h> 039 #include <drivers/x86_videomem.h>
032 #include <drivers/bochs.h> 040 #include <drivers/bochs.h>
>> 041 #include <sos/calcload.h>
>> 042 #include <sos/umem_vmm.h>
>> 043 #include <sos/binfmt_elf32.h>
>> 044 #include <drivers/zero.h>
033 045
034 046
035 047
036 048
037 static void display_bits(unsigned char row, un !! 049 void display_bits(unsigned char row, unsigned char col,
038 unsigned char attribu !! 050 unsigned char attribute,
039 sos_ui32_t integer) !! 051 sos_ui32_t integer)
040 { 052 {
041 int i; 053 int i;
042 054
043 for (i = 31 ; i >= 0 ; i--) 055 for (i = 31 ; i >= 0 ; i--)
044 { 056 {
045 057
046 int bit_i = (integer & (1 << i)); 058 int bit_i = (integer & (1 << i));
047 059
048 unsigned char ascii_code = bit_i?219:177 060 unsigned char ascii_code = bit_i?219:177;
049 sos_x86_videomem_putchar(row, col++, 061 sos_x86_videomem_putchar(row, col++,
050 attribute, 062 attribute,
051 ascii_code); 063 ascii_code);
052 } 064 }
053 } 065 }
054 066
055 067
056 068
057 static void clk_it(int intid) 069 static void clk_it(int intid)
058 { 070 {
059 static sos_ui32_t clock_count = 0; 071 static sos_ui32_t clock_count = 0;
060 072
061 display_bits(0, 48, 073 display_bits(0, 48,
062 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 074 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
063 clock_count); 075 clock_count);
064 clock_count++; 076 clock_count++;
065 077
>> 078
>> 079 sos_time_do_tick();
>> 080
>> 081
>> 082 sos_sched_do_timer_tick();
066 } 083 }
067 084
068 #define MY_PPAGE_NUM_INT 511 !! 085
069 struct my_ppage !! 086
>> 087
>> 088
>> 089
>> 090
>> 091
>> 092 static void pgflt_ex(int intid, struct sos_cpu_state *ctxt)
070 { 093 {
071 sos_ui32_t before[MY_PPAGE_NUM_INT]; !! 094 static sos_ui32_t demand_paging_count = 0;
072 struct my_ppage *prev, *next; !! 095 struct sos_thread * cur_thr = sos_thread_get_current();
073 sos_ui32_t after[MY_PPAGE_NUM_INT]; !! 096 sos_vaddr_t faulting_vaddr = sos_cpu_context_get_EX_faulting_vaddr(ctxt);
074 }; !! 097 sos_paddr_t ppage_paddr;
075 !! 098
076 static void test_physmem() !! 099 if (sos_cpu_context_is_in_user_mode(ctxt)
077 { !! 100 || (cur_thr->fixup_uaccess.return_vaddr))
078 <<
079 struct my_ppage *ppage_list, *my_ppage; <<
080 sos_count_t num_alloc_ppages = 0, num_free_p <<
081 <<
082 ppage_list = NULL; <<
083 while ((my_ppage = (struct my_ppage*)sos_phy <<
084 != NULL) <<
085 { 101 {
086 int i; !! 102 __label__ unforce_address_space;
087 num_alloc_ppages++; !! 103 sos_bool_t need_to_setup_mmu;
088 !! 104 sos_ui32_t errcode = sos_cpu_context_get_EX_info(ctxt);
089 !! 105
090 sos_x86_videomem_printf(2, 0, !! 106
091 SOS_X86_VIDEO_FG !! 107
092 | SOS_X86_VIDEO_ !! 108 need_to_setup_mmu = (cur_thr->squatted_mm_context
093 "Could allocate !! 109 != sos_process_get_mm_context(cur_thr->process));
094 num_alloc_ppages !! 110 if (need_to_setup_mmu)
095 !! 111 sos_thread_prepare_user_space_access(NULL, 0);
096 !! 112
097 for (i = 0 ; i < MY_PPAGE_NUM_INT ; i++) !! 113 if (SOS_OK ==
098 my_ppage->before[i] = my_ppage->after[ !! 114 sos_umem_vmm_try_resolve_page_fault(faulting_vaddr,
099 !! 115 errcode & (1 << 1),
100 !! 116 TRUE))
101 list_add_tail(ppage_list, my_ppage); !! 117 goto unforce_address_space;
102 } !! 118
103 !! 119
104 !! 120
105 while ((my_ppage = list_pop_head(ppage_list) !! 121 if (! sos_cpu_context_is_in_user_mode(ctxt))
106 { <<
107 <<
108 <<
109 int i; <<
110 for (i = 0 ; i < MY_PPAGE_NUM_INT ; i++) <<
111 { 122 {
112 !! 123 cur_thr->fixup_uaccess.faulted_uaddr = faulting_vaddr;
113 if ((my_ppage->before[i] != (sos_ui !! 124 sos_cpu_context_set_EX_return_address(ctxt,
114 || (my_ppage->after[i] != (sos_ !! 125 cur_thr->fixup_uaccess.return_vaddr);
115 { !! 126 goto unforce_address_space;
116 <<
117 sos_x86_videomem_putstring(20, 0 <<
118 SOS_X <<
119 | S <<
120 "Page <<
121 return; <<
122 } <<
123 } 127 }
124 128
125 !! 129 if (need_to_setup_mmu)
126 if (sos_physmem_unref_physpage((sos_padd !! 130 sos_thread_end_user_space_access();
127 { !! 131
128 !! 132 sos_bochs_printf("Unresolved USER page Fault at instruction 0x%x on access to address 0x%x (info=%x)!\n",
129 sos_x86_videomem_putstring(20, 0, !! 133 sos_cpu_context_get_PC(ctxt),
130 SOS_X86_V !! 134 (unsigned)faulting_vaddr,
131 | SOS_X !! 135 (unsigned)sos_cpu_context_get_EX_info(ctxt));
132 "Cannot r !! 136 sos_bochs_printf("Terminating User thread\n");
133 return; !! 137 sos_thread_exit();
134 } !! 138
>> 139 unforce_address_space:
>> 140 if (need_to_setup_mmu)
>> 141 sos_thread_end_user_space_access();
>> 142 return;
>> 143 }
>> 144
>> 145
>> 146 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
>> 147 {
>> 148
>> 149
>> 150 sos_display_fatal_error("Unresolved page Fault at instruction 0x%x on access to address 0x%x (info=%x)!",
>> 151 sos_cpu_context_get_PC(ctxt),
>> 152 (unsigned)faulting_vaddr,
>> 153 (unsigned)sos_cpu_context_get_EX_info(ctxt));
>> 154 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
>> 155 }
>> 156
>> 157
>> 158
>> 159
>> 160
>> 161
>> 162
>> 163 demand_paging_count ++;
>> 164 display_bits(0, 0,
>> 165 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 166 demand_paging_count);
>> 167
>> 168
>> 169 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
>> 170 if (! ppage_paddr)
>> 171 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
>> 172 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
>> 173 SOS_PAGE_ALIGN_INF(faulting_vaddr),
>> 174 FALSE,
>> 175 SOS_VM_MAP_PROT_READ
>> 176 | SOS_VM_MAP_PROT_WRITE
>> 177 | SOS_VM_MAP_ATOMIC));
>> 178 sos_physmem_unref_physpage(ppage_paddr);
>> 179
>> 180
>> 181 }
>> 182
>> 183
>> 184
>> 185
>> 186
>> 187
>> 188
>> 189 static void idle_thread()
>> 190 {
>> 191 sos_ui32_t idle_twiddle = 0;
>> 192
>> 193 while (1)
>> 194 {
>> 195
>> 196
>> 197 asm("hlt\n");
>> 198
>> 199 idle_twiddle ++;
>> 200 display_bits(0, 0, SOS_X86_VIDEO_FG_GREEN | SOS_X86_VIDEO_BG_BLUE,
>> 201 idle_twiddle);
>> 202
>> 203
>> 204 sos_thread_yield();
>> 205 }
>> 206 }
>> 207
>> 208
>> 209
>> 210
>> 211
>> 212 static void stat_thread()
>> 213 {
>> 214 while (1)
>> 215 {
>> 216 sos_ui32_t flags;
>> 217 sos_ui32_t load1, load5, load15;
>> 218 char str1[11], str5[11], str15[11];
>> 219 struct sos_time t;
>> 220 t.sec = 1;
>> 221 t.nanosec = 0;
>> 222
>> 223 sos_thread_sleep(& t);
>> 224
>> 225 sos_disable_IRQs(flags);
>> 226
>> 227
>> 228 sos_load_get_sload(&load1, &load5, &load15);
>> 229 sos_load_to_string(str1, load1);
>> 230 sos_load_to_string(str5, load5);
>> 231 sos_load_to_string(str15, load15);
>> 232 sos_x86_videomem_printf(16, 34,
>> 233 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 234 "Kernel (- Idle): %s %s %s ",
>> 235 str1, str5, str15);
>> 236
>> 237 sos_load_get_uload(&load1, &load5, &load15);
>> 238 sos_load_to_string(str1, load1);
>> 239 sos_load_to_string(str5, load5);
>> 240 sos_load_to_string(str15, load15);
>> 241 sos_x86_videomem_printf(17, 34,
>> 242 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 243 "User: %s %s %s ",
>> 244 str1, str5, str15);
>> 245
>> 246 sos_load_get_uratio(&load1, &load5, &load15);
>> 247 sos_load_to_string(str1, load1);
>> 248 sos_load_to_string(str5, load5);
>> 249 sos_load_to_string(str15, load15);
>> 250 sos_x86_videomem_printf(18, 34,
>> 251 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 252 "User CPU %%: %s %s %s ",
>> 253 str1, str5, str15);
>> 254
>> 255
>> 256 sos_load_get_sratio(&load1, &load5, &load15);
>> 257 sos_load_to_string(str1, load1);
>> 258 sos_load_to_string(str5, load5);
>> 259 sos_load_to_string(str15, load15);
>> 260 sos_x86_videomem_printf(19, 34,
>> 261 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 262 "Kernel CPU %% (+ Idle): %s %s %s ",
>> 263 str1, str5, str15);
>> 264 sos_restore_IRQs(flags);
>> 265 }
>> 266 }
>> 267
135 268
136 !! 269
137 num_free_ppages ++; !! 270
138 sos_x86_videomem_printf(2, 0, !! 271
139 SOS_X86_VIDEO_FG !! 272 static sos_ret_t start_init()
140 | SOS_X86_VIDEO_ !! 273 {
141 "Could free %d p !! 274 sos_ret_t retval;
142 num_free_ppages) !! 275 struct sos_umem_vmm_as *as_init;
>> 276 struct sos_process *proc_init;
>> 277 struct sos_thread *new_thr;
>> 278 sos_uaddr_t ustack, start_uaddr;
>> 279
>> 280
>> 281 proc_init = sos_process_create("init", FALSE);
>> 282 if (! proc_init)
>> 283 return -SOS_ENOMEM;
>> 284 as_init = sos_process_get_address_space(proc_init);
>> 285
>> 286
>> 287 start_uaddr = sos_binfmt_elf32_map(as_init, "init");
>> 288 if (0 == start_uaddr)
>> 289 {
>> 290 sos_process_unref(proc_init);
>> 291 return -SOS_ENOENT;
>> 292 }
>> 293
>> 294
>> 295 ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_DEFAULT_USER_STACK_SIZE) + 1;
>> 296 retval = sos_dev_zero_map(as_init, &ustack, SOS_DEFAULT_USER_STACK_SIZE,
>> 297 SOS_VM_MAP_PROT_READ | SOS_VM_MAP_PROT_WRITE,
>> 298 0);
>> 299 if (SOS_OK != retval)
>> 300 {
>> 301 sos_bochs_printf("ici 2\n");
>> 302 sos_process_unref(proc_init);
>> 303 return -SOS_ENOMEM;
143 } 304 }
144 305
145 !! 306
146 sos_x86_videomem_printf(2, 0, !! 307 new_thr = sos_create_user_thread(NULL,
147 SOS_X86_VIDEO_FG_LTG !! 308 proc_init,
148 | SOS_X86_VIDEO_BG_B !! 309 start_uaddr,
149 "Could allocate %d b !! 310 0, 0,
150 num_alloc_ppages << !! 311 ustack + SOS_DEFAULT_USER_STACK_SIZE - 4,
151 num_free_ppages << S !! 312 SOS_SCHED_PRIO_TS_LOWEST);
>> 313 if (! new_thr)
>> 314 {
>> 315 sos_bochs_printf("ici 3\n");
>> 316 sos_process_unref(proc_init);
>> 317 return -SOS_ENOMEM;
>> 318 }
152 319
153 SOS_ASSERT_FATAL(num_alloc_ppages == num_fre !! 320 sos_process_unref(proc_init);
>> 321 return SOS_OK;
154 } 322 }
155 323
156 324
157 !! 325
>> 326
>> 327
158 void sos_main(unsigned long magic, unsigned lo 328 void sos_main(unsigned long magic, unsigned long addr)
159 { 329 {
160 unsigned i; 330 unsigned i;
161 sos_paddr_t sos_kernel_core_base_paddr, sos_ 331 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
>> 332 struct sos_time tick_resolution;
162 333
163 334
164 335
165 336
166 multiboot_info_t *mbi; 337 multiboot_info_t *mbi;
167 mbi = (multiboot_info_t *) addr; 338 mbi = (multiboot_info_t *) addr;
168 339
169 340
170 sos_bochs_setup(); 341 sos_bochs_setup();
171 342
172 sos_x86_videomem_setup(); 343 sos_x86_videomem_setup();
173 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 344 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
174 345
175 346
176 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 347 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
177 348
178 sos_x86_videomem_printf(1, 0, 349 sos_x86_videomem_printf(1, 0,
179 SOS_X86_VIDEO_FG_Y 350 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
180 "Welcome From GRUB 351 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
181 "SOS", ',', !! 352 "SOS article 7.5", ',',
182 (unsigned)(mbi->me 353 (unsigned)(mbi->mem_upper >> 10) + 1,
183 (unsigned)mbi->mem 354 (unsigned)mbi->mem_upper);
184 else 355 else
185 356
186 sos_x86_videomem_printf(1, 0, 357 sos_x86_videomem_printf(1, 0,
187 SOS_X86_VIDEO_FG_Y 358 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
188 "Welcome to SOS"); !! 359 "Welcome to SOS article 7.5");
189 360
190 sos_bochs_putstring("Message in a bochs\n"); !! 361 sos_bochs_putstring("Message in a bochs: This is SOS article 7.5.\n");
191 362
192 363
193 sos_gdt_setup(); !! 364 sos_gdt_subsystem_setup();
194 sos_idt_setup(); !! 365 sos_idt_subsystem_setup();
195 366
196 367
197 sos_exceptions_setup(); !! 368 sos_exception_subsystem_setup();
198 sos_irq_setup(); !! 369 sos_irq_subsystem_setup();
199 370
200 371
201 sos_i8254_set_frequency(100); 372 sos_i8254_set_frequency(100);
202 373
>> 374
>> 375
>> 376 tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL };
>> 377 sos_time_subsysem_setup(& tick_resolution);
203 378
204 379
205 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 380 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
206 { 381 {
207 sos_x86_videomem_putstring(20, 0, 382 sos_x86_videomem_putstring(20, 0,
208 SOS_X86_VIDEO 383 SOS_X86_VIDEO_FG_LTRED
209 | SOS_X86_V 384 | SOS_X86_VIDEO_BG_BLUE
210 | SOS_X86_V 385 | SOS_X86_VIDEO_FG_BLINKING,
211 "I'm not load 386 "I'm not loaded with Grub !");
212 387
213 for (;;) 388 for (;;)
214 continue; 389 continue;
215 } 390 }
216 391
>> 392
>> 393
>> 394
>> 395
217 396
218 sos_irq_set_routine(SOS_IRQ_TIMER, 397 sos_irq_set_routine(SOS_IRQ_TIMER,
219 clk_it); !! 398 clk_it);
220 !! 399
221 !! 400
222 asm volatile ("sti\n"); !! 401
>> 402
>> 403
223 404
224 405
225 406
226 sos_physmem_setup((mbi->mem_upper<<10) + (1< !! 407 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
227 & sos_kernel_core_base_pad !! 408 & sos_kernel_core_base_paddr,
228 & sos_kernel_core_top_padd !! 409 & sos_kernel_core_top_paddr);
229 test_physmem(); !! 410
230 !! 411
231 !! 412
232 for (;;) !! 413
233 continue; !! 414
>> 415
>> 416
>> 417 SOS_ASSERT_FATAL(SOS_OK ==
>> 418 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
>> 419 sos_kernel_core_top_paddr));
>> 420
>> 421
>> 422 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
>> 423 pgflt_ex);
>> 424
>> 425
>> 426
>> 427
>> 428
>> 429 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
>> 430 sos_kernel_core_top_paddr,
>> 431 bootstrap_stack_bottom,
>> 432 bootstrap_stack_bottom
>> 433 + bootstrap_stack_size))
>> 434 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
>> 435
>> 436 if (sos_kmalloc_subsystem_setup())
>> 437 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
>> 438
>> 439
>> 440
>> 441
>> 442 sos_mm_context_subsystem_setup();
>> 443
>> 444
>> 445
>> 446
>> 447 sos_cpu_context_subsystem_setup();
>> 448
>> 449
>> 450
>> 451
>> 452 sos_swintr_subsystem_setup();
>> 453
>> 454
>> 455
>> 456
>> 457
>> 458
>> 459
>> 460 sos_thread_subsystem_setup(bootstrap_stack_bottom,
>> 461 bootstrap_stack_size);
>> 462
>> 463
>> 464 sos_sched_subsystem_setup();
>> 465
>> 466
>> 467 SOS_ASSERT_FATAL(sos_create_kernel_thread("idle", idle_thread, NULL,
>> 468 SOS_SCHED_PRIO_TS_LOWEST) != NULL);
>> 469
>> 470
>> 471 sos_load_subsystem_setup();
>> 472
>> 473
>> 474 SOS_ASSERT_FATAL(sos_create_kernel_thread("stat_thread", stat_thread,
>> 475 NULL,
>> 476 SOS_SCHED_PRIO_TS_LOWEST) != NULL);
>> 477
>> 478
>> 479
>> 480
>> 481
>> 482 sos_umem_vmm_subsystem_setup();
>> 483 sos_dev_zero_subsystem_setup();
>> 484
>> 485
>> 486
>> 487
>> 488 sos_process_subsystem_setup();
>> 489
>> 490
>> 491
>> 492
>> 493 asm volatile ("sti\n");
234 494
235 return; !! 495
>> 496
>> 497 start_init();
>> 498
>> 499
>> 500
>> 501
>> 502
>> 503
>> 504
>> 505
>> 506
>> 507
>> 508
>> 509
>> 510
>> 511 sos_bochs_printf("Bye from primary thread !\n");
>> 512 sos_thread_exit();
>> 513 SOS_FATAL_ERROR("No trespassing !");
236 } 514 }