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>
029 #include <hwcore/paging.h> 028 #include <hwcore/paging.h>
030 #include <sos/list.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>
031 #include <sos/klibc.h> 036 #include <sos/klibc.h>
032 #include <sos/assert.h> 037 #include <sos/assert.h>
033 #include <drivers/x86_videomem.h> 038 #include <drivers/x86_videomem.h>
034 #include <drivers/bochs.h> 039 #include <drivers/bochs.h>
>> 040 #include <sos/calcload.h>
035 041
036 042
037 043
038 044
039 static void display_bits(unsigned char row, un !! 045 void display_bits(unsigned char row, unsigned char col,
040 unsigned char attribu !! 046 unsigned char attribute,
041 sos_ui32_t integer) !! 047 sos_ui32_t integer)
042 { 048 {
043 int i; 049 int i;
044 050
045 for (i = 31 ; i >= 0 ; i--) 051 for (i = 31 ; i >= 0 ; i--)
046 { 052 {
047 053
048 int bit_i = (integer & (1 << i)); 054 int bit_i = (integer & (1 << i));
049 055
050 unsigned char ascii_code = bit_i?219:177 056 unsigned char ascii_code = bit_i?219:177;
051 sos_x86_videomem_putchar(row, col++, 057 sos_x86_videomem_putchar(row, col++,
052 attribute, 058 attribute,
053 ascii_code); 059 ascii_code);
054 } 060 }
055 } 061 }
056 062
057 063
058 064
059 static void clk_it(int intid) 065 static void clk_it(int intid)
060 { 066 {
061 static sos_ui32_t clock_count = 0; 067 static sos_ui32_t clock_count = 0;
062 068
063 display_bits(0, 48, 069 display_bits(0, 48,
064 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 070 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
065 clock_count); 071 clock_count);
066 clock_count++; 072 clock_count++;
067 073
068 } !! 074
>> 075 sos_time_do_tick();
069 076
070 !! 077
071 static void pgflt_ex(int exid) !! 078 sos_sched_do_timer_tick();
072 { <<
073 sos_bochs_printf("Got page fault\n"); <<
074 sos_x86_videomem_printf(10, 30, <<
075 SOS_X86_VIDEO_FG_LTR <<
076 "Got EXPECTED (?) Pa <<
077 for (;;) ; <<
078 } 079 }
079 080
080 static void test_paging(sos_vaddr_t sos_kernel !! 081
>> 082
>> 083
>> 084
>> 085
>> 086
>> 087
>> 088 static void pgflt_ex(int intid, struct sos_cpu_state *ctxt)
081 { 089 {
082 !! 090 static sos_ui32_t demand_paging_count = 0;
083 !! 091 sos_vaddr_t faulting_vaddr = sos_cpu_context_get_EX_faulting_vaddr(ctxt);
084 sos_vaddr_t vpage_code = SOS_PAGE_ALIGN_INF( !! 092 sos_paddr_t ppage_paddr;
085 <<
086 <<
087 sos_paddr_t ppage_new; <<
088 <<
089 <<
090 <<
091 sos_vaddr_t vpage_tmp = sos_kernel_core_top_ <<
092 093
093 unsigned i; !! 094 if (sos_cpu_context_is_in_user_mode(ctxt))
>> 095 {
>> 096
>> 097
>> 098 sos_bochs_printf("Unresolved USER page Fault at instruction 0x%x on access to address 0x%x (info=%x)!\n",
>> 099 sos_cpu_context_get_PC(ctxt),
>> 100 (unsigned)faulting_vaddr,
>> 101 (unsigned)sos_cpu_context_get_EX_info(ctxt));
>> 102 sos_bochs_printf("Terminating User thread\n");
>> 103 sos_thread_exit();
>> 104 }
>> 105
>> 106
>> 107 if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
>> 108 {
>> 109
>> 110
>> 111 sos_display_fatal_error("Unresolved page Fault at instruction 0x%x on access to address 0x%x (info=%x)!",
>> 112 sos_cpu_context_get_PC(ctxt),
>> 113 (unsigned)faulting_vaddr,
>> 114 (unsigned)sos_cpu_context_get_EX_info(ctxt));
>> 115 SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
>> 116 }
094 117
095 <<
096 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA <<
097 pgflt_ex); <<
098 118
099 119
100 !! 120
101 <<
102 121
103 sos_x86_videomem_printf(4, 0, !! 122
104 SOS_X86_VIDEO_FG_LTG !! 123
105 "Moving current code !! 124 demand_paging_count ++;
>> 125 display_bits(0, 0,
>> 126 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 127 demand_paging_count);
>> 128
>> 129
>> 130 ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
>> 131 if (! ppage_paddr)
>> 132 SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
>> 133 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
>> 134 SOS_PAGE_ALIGN_INF(faulting_vaddr),
>> 135 FALSE,
>> 136 SOS_VM_MAP_PROT_READ
>> 137 | SOS_VM_MAP_PROT_WRITE
>> 138 | SOS_VM_MAP_ATOMIC));
>> 139 sos_physmem_unref_physpage(ppage_paddr);
>> 140
>> 141
>> 142 }
>> 143
>> 144
>> 145
>> 146
>> 147
>> 148
>> 149
>> 150
>> 151
>> 152 struct thr_arg
>> 153 {
>> 154 char character;
>> 155 int color;
>> 156
>> 157 int col;
>> 158 int row;
>> 159 };
>> 160
106 161
>> 162 static void demo_thread(void *arg)
>> 163 {
>> 164 struct thr_arg *thr_arg = (struct thr_arg*)arg;
>> 165 int progress = 0;
107 166
108 !! 167 sos_bochs_printf("start %c", thr_arg->character);
109 ppage_new = sos_physmem_ref_physpage_new(FAL !! 168 while (1)
110 if (! ppage_new) <<
111 { 169 {
112 !! 170 progress ++;
113 sos_x86_videomem_putstring(20, 0, !! 171 display_bits(thr_arg->row, thr_arg->col+1, thr_arg->color, progress);
114 SOS_X86_VIDEO !! 172
115 | SOS_X86_V !! 173 sos_bochs_putchar(thr_arg->character);
116 "test_paging !! 174
117 return; !! 175
>> 176 if ((random() % 100) == 0)
>> 177 {
>> 178 sos_bochs_printf("[37myield(%c)[m\n", thr_arg->character);
>> 179 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'Y');
>> 180 SOS_ASSERT_FATAL(SOS_OK == sos_thread_yield());
>> 181 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 182 }
>> 183
>> 184
>> 185 else if ((random() % 200) == 0)
>> 186 {
>> 187 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=50000000 };
>> 188 sos_bochs_printf("[37msleep1(%c)[m\n", thr_arg->character);
>> 189 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 's');
>> 190 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
>> 191 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
>> 192 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 193 }
>> 194
>> 195
>> 196 else if ((random() % 300) == 0)
>> 197 {
>> 198 struct sos_time t = (struct sos_time){ .sec=0, .nanosec=300000000 };
>> 199 sos_bochs_printf("[37msleep2(%c)[m\n", thr_arg->character);
>> 200 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'S');
>> 201 SOS_ASSERT_FATAL(SOS_OK == sos_thread_sleep(& t));
>> 202 SOS_ASSERT_FATAL(sos_time_is_zero(& t));
>> 203 sos_x86_videomem_putchar(thr_arg->row, thr_arg->col, 0x1e, 'R');
>> 204 }
>> 205
>> 206
118 } 207 }
>> 208 }
119 209
120 sos_x86_videomem_printf(5, 0, !! 210
121 SOS_X86_VIDEO_FG_YEL !! 211 static void test_thread()
122 "Hello from the addr !! 212 {
123 sos_paging_get_paddr !! 213
124 !! 214
125 sos_x86_videomem_printf(6, 0, !! 215 static struct thr_arg arg_b, arg_c, arg_d, arg_e, arg_R, arg_S;
126 SOS_X86_VIDEO_FG_YEL !! 216 sos_ui32_t flags;
127 "Transfer vpage 0x%x !! 217
128 vpage_code, !! 218 sos_disable_IRQs(flags);
129 sos_paging_get_paddr !! 219
130 ppage_new, !! 220 arg_b = (struct thr_arg) { .character='b', .col=0, .row=21, .color=0x14 };
131 (unsigned)vpage_tmp) !! 221 sos_create_kernel_thread("YO[b]", demo_thread, (void*)&arg_b, SOS_SCHED_PRIO_TS_LOWEST);
132 !! 222
133 !! 223 arg_c = (struct thr_arg) { .character='c', .col=46, .row=21, .color=0x14 };
134 !! 224 sos_create_kernel_thread("YO[c]", demo_thread, (void*)&arg_c, SOS_SCHED_PRIO_TS_LOWEST);
135 sos_paging_map(ppage_new, vpage_tmp, !! 225
136 FALSE, !! 226 arg_d = (struct thr_arg) { .character='d', .col=0, .row=20, .color=0x14 };
137 SOS_VM_MAP_ATOMIC !! 227 sos_create_kernel_thread("YO[d]", demo_thread, (void*)&arg_d, SOS_SCHED_PRIO_TS_LOWEST-1);
138 | SOS_VM_MAP_PROT_READ !! 228
139 | SOS_VM_MAP_PROT_WRITE); !! 229 arg_e = (struct thr_arg) { .character='e', .col=0, .row=19, .color=0x14 };
140 !! 230 sos_create_kernel_thread("YO[e]", demo_thread, (void*)&arg_e, SOS_SCHED_PRIO_TS_LOWEST-2);
141 !! 231
142 !! 232 arg_R = (struct thr_arg) { .character='R', .col=0, .row=17, .color=0x1c };
143 sos_physmem_unref_physpage(ppage_new); !! 233 sos_create_kernel_thread("YO[R]", demo_thread, (void*)&arg_R, SOS_SCHED_PRIO_RT_LOWEST);
144 !! 234
145 !! 235 arg_S = (struct thr_arg) { .character='S', .col=0, .row=16, .color=0x1c };
146 !! 236 sos_create_kernel_thread("YO[S]", demo_thread, (void*)&arg_S, SOS_SCHED_PRIO_RT_LOWEST-1);
147 memcpy((void*)vpage_tmp, !! 237
148 (void*)vpage_code, !! 238 sos_restore_IRQs(flags);
149 SOS_PAGE_SIZE); !! 239 }
150 !! 240
151 !! 241
152 sos_paging_map(ppage_new, vpage_code, !! 242
153 FALSE, !! 243
154 SOS_VM_MAP_ATOMIC !! 244
155 | SOS_VM_MAP_PROT_READ !! 245
156 | SOS_VM_MAP_PROT_WRITE); !! 246 static void idle_thread()
157 !! 247 {
158 !! 248 sos_ui32_t idle_twiddle = 0;
159 !! 249
160 !! 250 while (1)
161 !! 251 {
162 !! 252
163 !! 253
164 !! 254 asm("hlt\n");
165 sos_paging_unmap(vpage_tmp); !! 255
166 !! 256 idle_twiddle ++;
167 sos_x86_videomem_printf(7, 0, !! 257 display_bits(0, 0, SOS_X86_VIDEO_FG_GREEN | SOS_X86_VIDEO_BG_BLUE,
168 SOS_X86_VIDEO_FG_YEL !! 258 idle_twiddle);
169 "Hello from the addr !! 259
170 sos_paging_get_paddr !! 260
171 !! 261 sos_thread_yield();
172 sos_x86_videomem_printf(9, 0, !! 262 }
173 SOS_X86_VIDEO_FG_LTG !! 263 }
174 "Provoking a page fa !! 264
175 !! 265
176 !! 266
177 !! 267
178 !! 268
179 !! 269 static void stat_thread()
180 !! 270 {
181 !! 271 while (1)
182 <<
183 <<
184 for (i = vpage_code ; ; i += SOS_ <<
185 { 272 {
186 unsigned *pint = (unsigned *)SOS_PAGE_AL !! 273 sos_ui32_t flags;
187 sos_bochs_printf("Test vaddr 0x%x : val= !! 274 sos_ui32_t load1, load5, load15;
188 sos_x86_videomem_printf(10, 0, !! 275 char str1[11], str5[11], str15[11];
>> 276 struct sos_time t;
>> 277 t.sec = 1;
>> 278 t.nanosec = 0;
>> 279
>> 280 sos_thread_sleep(& t);
>> 281
>> 282 sos_disable_IRQs(flags);
>> 283
>> 284
>> 285 sos_load_get_sload(&load1, &load5, &load15);
>> 286 sos_load_to_string(str1, load1);
>> 287 sos_load_to_string(str5, load5);
>> 288 sos_load_to_string(str15, load15);
>> 289 sos_x86_videomem_printf(16, 34,
189 SOS_X86_VIDEO_FG 290 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
190 "Test vaddr 0x%x !! 291 "Kernel (- Idle): %s %s %s ",
191 (unsigned)pint); !! 292 str1, str5, str15);
192 sos_bochs_printf("0x%x\n", *pint); !! 293
193 sos_x86_videomem_printf(10, 30, !! 294 sos_load_get_uload(&load1, &load5, &load15);
>> 295 sos_load_to_string(str1, load1);
>> 296 sos_load_to_string(str5, load5);
>> 297 sos_load_to_string(str15, load15);
>> 298 sos_x86_videomem_printf(17, 34,
194 SOS_X86_VIDEO_FG 299 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
195 "0x%x " !! 300 "User: %s %s %s ",
196 } !! 301 str1, str5, str15);
197 302
198 !! 303 sos_load_get_uratio(&load1, &load5, &load15);
199 sos_x86_videomem_printf(20, 0, !! 304 sos_load_to_string(str1, load1);
200 SOS_X86_VIDEO_FG_LTR !! 305 sos_load_to_string(str5, load5);
201 "We should have had !! 306 sos_load_to_string(str15, load15);
202 vpage_tmp); !! 307 sos_x86_videomem_printf(18, 34,
>> 308 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 309 "User CPU %%: %s %s %s ",
>> 310 str1, str5, str15);
>> 311
>> 312
>> 313 sos_load_get_sratio(&load1, &load5, &load15);
>> 314 sos_load_to_string(str1, load1);
>> 315 sos_load_to_string(str5, load5);
>> 316 sos_load_to_string(str15, load15);
>> 317 sos_x86_videomem_printf(19, 34,
>> 318 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 319 "Kernel CPU %% (+ Idle): %s %s %s ",
>> 320 str1, str5, str15);
>> 321 sos_restore_IRQs(flags);
>> 322 }
203 } 323 }
204 324
205 !! 325
>> 326
>> 327
>> 328
206 void sos_main(unsigned long magic, unsigned lo 329 void sos_main(unsigned long magic, unsigned long addr)
207 { 330 {
208 unsigned i; 331 unsigned i;
209 sos_paddr_t sos_kernel_core_base_paddr, sos_ 332 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
>> 333 struct sos_time tick_resolution;
210 334
211 335
212 336
213 337
214 multiboot_info_t *mbi; 338 multiboot_info_t *mbi;
215 mbi = (multiboot_info_t *) addr; 339 mbi = (multiboot_info_t *) addr;
216 340
217 341
218 sos_bochs_setup(); 342 sos_bochs_setup();
219 343
220 sos_x86_videomem_setup(); 344 sos_x86_videomem_setup();
221 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 345 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
222 346
223 347
224 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 348 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
225 349
226 sos_x86_videomem_printf(1, 0, 350 sos_x86_videomem_printf(1, 0,
227 SOS_X86_VIDEO_FG_Y 351 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
228 "Welcome From GRUB 352 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
229 "SOS", ',', !! 353 "SOS article 7", ',',
230 (unsigned)(mbi->me 354 (unsigned)(mbi->mem_upper >> 10) + 1,
231 (unsigned)mbi->mem 355 (unsigned)mbi->mem_upper);
232 else 356 else
233 357
234 sos_x86_videomem_printf(1, 0, 358 sos_x86_videomem_printf(1, 0,
235 SOS_X86_VIDEO_FG_Y 359 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
236 "Welcome to SOS"); !! 360 "Welcome to SOS article 7");
237 361
238 sos_bochs_putstring("Message in a bochs\n"); !! 362 sos_bochs_putstring("Message in a bochs: This is SOS article 7.\n");
239 363
240 364
241 sos_gdt_setup(); !! 365 sos_gdt_subsystem_setup();
242 sos_idt_setup(); !! 366 sos_idt_subsystem_setup();
243 367
244 368
245 sos_exceptions_setup(); !! 369 sos_exception_subsystem_setup();
246 sos_irq_setup(); !! 370 sos_irq_subsystem_setup();
247 371
248 372
249 sos_i8254_set_frequency(100); 373 sos_i8254_set_frequency(100);
250 374
>> 375
>> 376
>> 377 tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL };
>> 378 sos_time_subsysem_setup(& tick_resolution);
251 379
252 380
253 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 381 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
254 { 382 {
255 sos_x86_videomem_putstring(20, 0, 383 sos_x86_videomem_putstring(20, 0,
256 SOS_X86_VIDEO 384 SOS_X86_VIDEO_FG_LTRED
257 | SOS_X86_V 385 | SOS_X86_VIDEO_BG_BLUE
258 | SOS_X86_V 386 | SOS_X86_VIDEO_FG_BLINKING,
259 "I'm not load 387 "I'm not loaded with Grub !");
260 388
261 for (;;) 389 for (;;)
262 continue; 390 continue;
263 } 391 }
264 392
>> 393
>> 394
>> 395
>> 396
265 397
266 sos_irq_set_routine(SOS_IRQ_TIMER, 398 sos_irq_set_routine(SOS_IRQ_TIMER,
267 clk_it); !! 399 clk_it);
268 !! 400
269 !! 401
270 asm volatile ("sti\n"); !! 402
>> 403
>> 404
271 405
272 406
273 407
274 sos_physmem_setup((mbi->mem_upper<<10) + (1< !! 408 sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
275 & sos_kernel_core_base_pad !! 409 & sos_kernel_core_base_paddr,
276 & sos_kernel_core_top_padd !! 410 & sos_kernel_core_top_paddr);
277 411
278 412
279 413
280 414
281 415
282 416
283 417
284 if (sos_paging_setup(sos_kernel_core_base_pa !! 418 SOS_ASSERT_FATAL(SOS_OK ==
285 sos_kernel_core_top_pad !! 419 sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
286 sos_bochs_printf("Could not setup paged me !! 420 sos_kernel_core_top_paddr));
287 sos_x86_videomem_printf(2, 0, !! 421
288 SOS_X86_VIDEO_FG_YEL !! 422
289 "Paged-memory mode i !! 423 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
290 !! 424 pgflt_ex);
291 test_paging(sos_kernel_core_top_paddr); !! 425
292 !! 426
293 !! 427
294 for (;;) !! 428
295 continue; !! 429
>> 430 if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
>> 431 sos_kernel_core_top_paddr,
>> 432 bootstrap_stack_bottom,
>> 433 bootstrap_stack_bottom
>> 434 + bootstrap_stack_size))
>> 435 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
>> 436
>> 437 if (sos_kmalloc_subsystem_setup())
>> 438 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
296 439
297 return; !! 440
>> 441
>> 442
>> 443 sos_mm_context_subsystem_setup();
>> 444
>> 445
>> 446
>> 447
>> 448 sos_cpu_context_subsystem_setup();
>> 449
>> 450
>> 451
>> 452
>> 453 sos_swintr_subsystem_setup();
>> 454
>> 455
>> 456
>> 457
>> 458
>> 459
>> 460
>> 461 sos_thread_subsystem_setup(bootstrap_stack_bottom,
>> 462 bootstrap_stack_size);
>> 463
>> 464
>> 465 sos_sched_subsystem_setup();
>> 466
>> 467
>> 468 SOS_ASSERT_FATAL(sos_create_kernel_thread("idle", idle_thread, NULL,
>> 469 SOS_SCHED_PRIO_TS_LOWEST) != NULL);
>> 470
>> 471
>> 472 sos_load_subsystem_setup();
>> 473
>> 474
>> 475 SOS_ASSERT_FATAL(sos_create_kernel_thread("stat_thread", stat_thread,
>> 476 NULL,
>> 477 SOS_SCHED_PRIO_TS_LOWEST) != NULL);
>> 478
>> 479
>> 480
>> 481
>> 482
>> 483 sos_process_subsystem_setup();
>> 484
>> 485
>> 486
>> 487
>> 488 asm volatile ("sti\n");
>> 489
>> 490
>> 491 extern void test_art7();
>> 492 test_art7();
>> 493
>> 494
>> 495 extern void MouseSim();
>> 496 MouseSim();
>> 497 test_thread();
>> 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 !");
298 } 514 }