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 020
020 #include <bootstrap/multiboot.h> 021 #include <bootstrap/multiboot.h>
021 #include <hwcore/idt.h> 022 #include <hwcore/idt.h>
022 #include <hwcore/gdt.h> 023 #include <hwcore/gdt.h>
023 #include <hwcore/irq.h> 024 #include <hwcore/irq.h>
024 #include <hwcore/exception.h> 025 #include <hwcore/exception.h>
025 #include <hwcore/i8254.h> 026 #include <hwcore/i8254.h>
026 #include <sos/list.h> 027 #include <sos/list.h>
027 #include <sos/physmem.h> 028 #include <sos/physmem.h>
028 #include <hwcore/paging.h> 029 #include <hwcore/paging.h>
029 #include <hwcore/mm_context.h> !! 030 #include <sos/list.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> <<
037 #include <sos/klibc.h> 031 #include <sos/klibc.h>
038 #include <sos/assert.h> 032 #include <sos/assert.h>
039 #include <drivers/x86_videomem.h> 033 #include <drivers/x86_videomem.h>
040 #include <drivers/bochs.h> 034 #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> <<
045 035
046 036
047 037
048 038
049 void display_bits(unsigned char row, unsigned !! 039 static void display_bits(unsigned char row, unsigned char col,
050 unsigned char attribute, !! 040 unsigned char attribute,
051 sos_ui32_t integer) !! 041 sos_ui32_t integer)
052 { 042 {
053 int i; 043 int i;
054 044
055 for (i = 31 ; i >= 0 ; i--) 045 for (i = 31 ; i >= 0 ; i--)
056 { 046 {
057 047
058 int bit_i = (integer & (1 << i)); 048 int bit_i = (integer & (1 << i));
059 049
060 unsigned char ascii_code = bit_i?219:177 050 unsigned char ascii_code = bit_i?219:177;
061 sos_x86_videomem_putchar(row, col++, 051 sos_x86_videomem_putchar(row, col++,
062 attribute, 052 attribute,
063 ascii_code); 053 ascii_code);
064 } 054 }
065 } 055 }
066 056
067 057
068 058
069 static void clk_it(int intid) 059 static void clk_it(int intid)
070 { 060 {
071 static sos_ui32_t clock_count = 0; 061 static sos_ui32_t clock_count = 0;
072 062
073 display_bits(0, 48, 063 display_bits(0, 48,
074 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 064 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
075 clock_count); 065 clock_count);
076 clock_count++; 066 clock_count++;
077 067
078 <<
079 sos_time_do_tick(); <<
080 <<
081 <<
082 sos_sched_do_timer_tick(); <<
083 } 068 }
084 069
085 !! 070
086 !! 071 static void pgflt_ex(int exid)
087 <<
088 <<
089 <<
090 <<
091 <<
092 static void pgflt_ex(int intid, struct sos_cpu <<
093 { 072 {
094 static sos_ui32_t demand_paging_count = 0; !! 073 sos_bochs_printf("Got page fault\n");
095 struct sos_thread * cur_thr = sos_thread_get !! 074 sos_x86_videomem_printf(10, 30,
096 sos_vaddr_t faulting_vaddr = sos_cpu_contex !! 075 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
097 sos_paddr_t ppage_paddr; !! 076 "Got EXPECTED (?) Page fault ! But where ???");
>> 077 for (;;) ;
>> 078 }
098 079
099 if (sos_cpu_context_is_in_user_mode(ctxt) !! 080 static void test_paging(sos_vaddr_t sos_kernel_core_top_vaddr)
100 || (cur_thr->fixup_uaccess.return_vaddr) !! 081 {
101 { !! 082
102 __label__ unforce_address_space; !! 083
103 sos_bool_t need_to_setup_mmu; !! 084 sos_vaddr_t vpage_code = SOS_PAGE_ALIGN_INF(test_paging);
104 sos_ui32_t errcode = sos_cpu_context_get !! 085
105 !! 086
106 !! 087 sos_paddr_t ppage_new;
107 !! 088
108 need_to_setup_mmu = (cur_thr->squatted_m !! 089
109 != sos_process_get_ !! 090
110 if (need_to_setup_mmu) !! 091 sos_vaddr_t vpage_tmp = sos_kernel_core_top_vaddr;
111 sos_thread_prepare_user_space_access(N <<
112 <<
113 if (SOS_OK == <<
114 sos_umem_vmm_try_resolve_page_fault( <<
115 <<
116 <<
117 goto unforce_address_space; <<
118 <<
119 <<
120 <<
121 if (! sos_cpu_context_is_in_user_mode(ct <<
122 { <<
123 cur_thr->fixup_uaccess.faulted_uaddr <<
124 sos_cpu_context_set_EX_return_addres <<
125 <<
126 goto unforce_address_space; <<
127 } <<
128 <<
129 if (need_to_setup_mmu) <<
130 sos_thread_end_user_space_access(); <<
131 <<
132 sos_bochs_printf("Unresolved USER page F <<
133 sos_cpu_context_get_PC( <<
134 (unsigned)faulting_vadd <<
135 (unsigned)sos_cpu_conte <<
136 sos_bochs_printf("Terminating User threa <<
137 sos_thread_exit(); <<
138 <<
139 unforce_address_space: <<
140 if (need_to_setup_mmu) <<
141 sos_thread_end_user_space_access(); <<
142 return; <<
143 } <<
144 092
145 !! 093 unsigned i;
146 if (! sos_kmem_vmm_is_valid_vaddr(faulting_v <<
147 { <<
148 <<
149 <<
150 sos_display_fatal_error("Unresolved page <<
151 sos_cpu_context_ <<
152 (unsigned)faulti <<
153 (unsigned)sos_cp <<
154 SOS_ASSERT_FATAL(! "Got page fault (note <<
155 } <<
156 094
>> 095
>> 096 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
>> 097 pgflt_ex);
157 098
158 099
159 !! 100
>> 101
160 102
161 !! 103 sos_x86_videomem_printf(4, 0,
162 !! 104 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
163 demand_paging_count ++; !! 105 "Moving current code elsewhere in physical memory:");
164 display_bits(0, 0, <<
165 SOS_X86_VIDEO_FG_LTRED | SOS_X8 <<
166 demand_paging_count); <<
167 <<
168 <<
169 ppage_paddr = sos_physmem_ref_physpage_new(F <<
170 if (! ppage_paddr) <<
171 SOS_ASSERT_FATAL(! "TODO: implement swap. <<
172 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp <<
173 SO <<
174 FA <<
175 SO <<
176 | <<
177 | <<
178 sos_physmem_unref_physpage(ppage_paddr); <<
179 <<
180 <<
181 } <<
182 <<
183 106
184 107
185 !! 108
186 !! 109 ppage_new = sos_physmem_ref_physpage_new(FALSE);
187 !! 110 if (! ppage_new)
188 <<
189 static void idle_thread() <<
190 { <<
191 sos_ui32_t idle_twiddle = 0; <<
192 <<
193 while (1) <<
194 { 111 {
195 !! 112
196 !! 113 sos_x86_videomem_putstring(20, 0,
197 asm("hlt\n"); !! 114 SOS_X86_VIDEO_FG_LTRED
198 !! 115 | SOS_X86_VIDEO_BG_BLUE,
199 idle_twiddle ++; !! 116 "test_paging : Cannot allocate page");
200 display_bits(0, 0, SOS_X86_VIDEO_FG_GREE !! 117 return;
201 idle_twiddle); <<
202 <<
203 <<
204 sos_thread_yield(); <<
205 } 118 }
206 } <<
207 <<
208 119
209 !! 120 sos_x86_videomem_printf(5, 0,
210 !! 121 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
211 !! 122 "Hello from the address 0x%x in physical memory",
212 static void stat_thread() !! 123 sos_paging_get_paddr(vpage_code));
213 { !! 124
214 while (1) !! 125 sos_x86_videomem_printf(6, 0,
>> 126 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 127 "Transfer vpage 0x%x: ppage 0x%x -> 0x%x (tmp vpage 0x%x)",
>> 128 vpage_code,
>> 129 sos_paging_get_paddr(vpage_code),
>> 130 ppage_new,
>> 131 (unsigned)vpage_tmp);
>> 132
>> 133
>> 134
>> 135 sos_paging_map(ppage_new, vpage_tmp,
>> 136 FALSE,
>> 137 SOS_VM_MAP_ATOMIC
>> 138 | SOS_VM_MAP_PROT_READ
>> 139 | SOS_VM_MAP_PROT_WRITE);
>> 140
>> 141
>> 142
>> 143 sos_physmem_unref_physpage(ppage_new);
>> 144
>> 145
>> 146
>> 147 memcpy((void*)vpage_tmp,
>> 148 (void*)vpage_code,
>> 149 SOS_PAGE_SIZE);
>> 150
>> 151
>> 152 sos_paging_map(ppage_new, vpage_code,
>> 153 FALSE,
>> 154 SOS_VM_MAP_ATOMIC
>> 155 | SOS_VM_MAP_PROT_READ
>> 156 | SOS_VM_MAP_PROT_WRITE);
>> 157
>> 158
>> 159
>> 160
>> 161
>> 162
>> 163
>> 164
>> 165 sos_paging_unmap(vpage_tmp);
>> 166
>> 167 sos_x86_videomem_printf(7, 0,
>> 168 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 169 "Hello from the address 0x%x in physical memory",
>> 170 sos_paging_get_paddr(vpage_code));
>> 171
>> 172 sos_x86_videomem_printf(9, 0,
>> 173 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
>> 174 "Provoking a page fault:");
>> 175
>> 176
>> 177
>> 178
>> 179
>> 180
>> 181
>> 182
>> 183
>> 184 for (i = vpage_code ; ; i += SOS_PAGE_SIZE)
215 { 185 {
216 sos_ui32_t flags; !! 186 unsigned *pint = (unsigned *)SOS_PAGE_ALIGN_INF(i);
217 sos_ui32_t load1, load5, load15; !! 187 sos_bochs_printf("Test vaddr 0x%x : val=", (unsigned)pint);
218 char str1[11], str5[11], str15[11]; !! 188 sos_x86_videomem_printf(10, 0,
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, &load <<
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 189 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
234 "Kernel (- Idle) !! 190 "Test vaddr 0x%x : val= ",
235 str1, str5, str1 !! 191 (unsigned)pint);
236 !! 192 sos_bochs_printf("0x%x\n", *pint);
237 sos_load_get_uload(&load1, &load5, &load !! 193 sos_x86_videomem_printf(10, 30,
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 194 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
243 "User: %s %s %s !! 195 "0x%x ", *pint);
244 str1, str5, str1 <<
245 <<
246 sos_load_get_uratio(&load1, &load5, &loa <<
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 <<
252 "User CPU %%: %s <<
253 str1, str5, str1 <<
254 <<
255 <<
256 sos_load_get_sratio(&load1, &load5, &loa <<
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 <<
262 "Kernel CPU %% ( <<
263 str1, str5, str1 <<
264 sos_restore_IRQs(flags); <<
265 } <<
266 } <<
267 <<
268 <<
269 <<
270 <<
271 <<
272 static sos_ret_t start_init() <<
273 { <<
274 sos_ret_t retval; <<
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 <<
285 <<
286 <<
287 start_uaddr = sos_binfmt_elf32_map(as_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_ <<
296 retval = sos_dev_zero_map(as_init, &ustack, <<
297 SOS_VM_MAP_PROT_RE <<
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; <<
304 } 196 }
305 197
306 !! 198
307 new_thr = sos_create_user_thread(NULL, !! 199 sos_x86_videomem_printf(20, 0,
308 proc_init, !! 200 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
309 start_uaddr !! 201 "We should have had a #PF at vaddr 0x%x !",
310 0, 0, !! 202 vpage_tmp);
311 ustack + SO <<
312 SOS_SCHED_P <<
313 if (! new_thr) <<
314 { <<
315 sos_bochs_printf("ici 3\n"); <<
316 sos_process_unref(proc_init); <<
317 return -SOS_ENOMEM; <<
318 } <<
319 <<
320 sos_process_unref(proc_init); <<
321 return SOS_OK; <<
322 } 203 }
323 204
324 !! 205
325 <<
326 <<
327 <<
328 void sos_main(unsigned long magic, unsigned lo 206 void sos_main(unsigned long magic, unsigned long addr)
329 { 207 {
330 unsigned i; 208 unsigned i;
331 sos_paddr_t sos_kernel_core_base_paddr, sos_ 209 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
332 struct sos_time tick_resolution; <<
333 210
334 211
335 212
336 213
337 multiboot_info_t *mbi; 214 multiboot_info_t *mbi;
338 mbi = (multiboot_info_t *) addr; 215 mbi = (multiboot_info_t *) addr;
339 216
340 217
341 sos_bochs_setup(); 218 sos_bochs_setup();
342 219
343 sos_x86_videomem_setup(); 220 sos_x86_videomem_setup();
344 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 221 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
345 222
346 223
347 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 224 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
348 225
349 sos_x86_videomem_printf(1, 0, 226 sos_x86_videomem_printf(1, 0,
350 SOS_X86_VIDEO_FG_Y 227 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
351 "Welcome From GRUB 228 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
352 "SOS article 7.5", !! 229 "SOS", ',',
353 (unsigned)(mbi->me 230 (unsigned)(mbi->mem_upper >> 10) + 1,
354 (unsigned)mbi->mem 231 (unsigned)mbi->mem_upper);
355 else 232 else
356 233
357 sos_x86_videomem_printf(1, 0, 234 sos_x86_videomem_printf(1, 0,
358 SOS_X86_VIDEO_FG_Y 235 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
359 "Welcome to SOS ar !! 236 "Welcome to SOS");
360 237
361 sos_bochs_putstring("Message in a bochs: Thi !! 238 sos_bochs_putstring("Message in a bochs\n");
362 239
363 240
364 sos_gdt_subsystem_setup(); !! 241 sos_gdt_setup();
365 sos_idt_subsystem_setup(); !! 242 sos_idt_setup();
366 243
367 244
368 sos_exception_subsystem_setup(); !! 245 sos_exceptions_setup();
369 sos_irq_subsystem_setup(); !! 246 sos_irq_setup();
370 247
371 248
372 sos_i8254_set_frequency(100); 249 sos_i8254_set_frequency(100);
373 250
374 <<
375 <<
376 tick_resolution = (struct sos_time) { .sec=0 <<
377 sos_time_subsysem_setup(& tick_resolution); <<
378 251
379 252
380 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 253 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
381 { 254 {
382 sos_x86_videomem_putstring(20, 0, 255 sos_x86_videomem_putstring(20, 0,
383 SOS_X86_VIDEO 256 SOS_X86_VIDEO_FG_LTRED
384 | SOS_X86_V 257 | SOS_X86_VIDEO_BG_BLUE
385 | SOS_X86_V 258 | SOS_X86_VIDEO_FG_BLINKING,
386 "I'm not load 259 "I'm not loaded with Grub !");
387 260
388 for (;;) 261 for (;;)
389 continue; 262 continue;
390 } 263 }
391 264
392 <<
393 <<
394 <<
395 <<
396 265
397 sos_irq_set_routine(SOS_IRQ_TIMER, 266 sos_irq_set_routine(SOS_IRQ_TIMER,
398 clk_it); !! 267 clk_it);
399 !! 268
400 !! 269
401 !! 270 asm volatile ("sti\n");
402 <<
403 <<
404 271
405 272
406 273
407 sos_physmem_subsystem_setup((mbi->mem_upper< !! 274 sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
408 & sos_kernel_cor !! 275 & sos_kernel_core_base_paddr,
409 & sos_kernel_cor !! 276 & sos_kernel_core_top_paddr);
410 277
411 278
412 279
413 280
414 281
415 282
416 283
417 SOS_ASSERT_FATAL(SOS_OK == !! 284 if (sos_paging_setup(sos_kernel_core_base_paddr,
418 sos_paging_subsystem_setup( !! 285 sos_kernel_core_top_paddr))
419 !! 286 sos_bochs_printf("Could not setup paged memory mode\n");
420 !! 287 sos_x86_videomem_printf(2, 0,
421 !! 288 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
422 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA !! 289 "Paged-memory mode is activated");
423 pgflt_ex); !! 290
424 !! 291 test_paging(sos_kernel_core_top_paddr);
425 !! 292
426 !! 293
427 !! 294 for (;;)
428 !! 295 continue;
429 if (sos_kmem_vmm_subsystem_setup(sos_kernel_ <<
430 sos_kernel_ <<
431 bootstrap_s <<
432 bootstrap_s <<
433 + bootstrap <<
434 sos_bochs_printf("Could not setup the Kern <<
435 <<
436 if (sos_kmalloc_subsystem_setup()) <<
437 sos_bochs_printf("Could not setup the Kmal <<
438 <<
439 <<
440 <<
441 <<
442 sos_mm_context_subsystem_setup(); <<
443 <<
444 <<
445 <<
446 <<
447 sos_cpu_context_subsystem_setup(); <<
448 296
449 !! 297 return;
450 <<
451 <<
452 sos_swintr_subsystem_setup(); <<
453 <<
454 <<
455 <<
456 <<
457 <<
458 <<
459 <<
460 sos_thread_subsystem_setup(bootstrap_stack_b <<
461 bootstrap_stack_s <<
462 <<
463 <<
464 sos_sched_subsystem_setup(); <<
465 <<
466 <<
467 SOS_ASSERT_FATAL(sos_create_kernel_thread("i <<
468 SO <<
469 <<
470 <<
471 sos_load_subsystem_setup(); <<
472 <<
473 <<
474 SOS_ASSERT_FATAL(sos_create_kernel_thread("s <<
475 NU <<
476 SO <<
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"); <<
494 <<
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 !\ <<
512 sos_thread_exit(); <<
513 SOS_FATAL_ERROR("No trespassing !"); <<
514 } 298 }