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 <hwcore/swintr.h> <<
031 #include <sos/kmem_vmm.h> 030 #include <sos/kmem_vmm.h>
032 #include <sos/kmalloc.h> 031 #include <sos/kmalloc.h>
033 #include <sos/time.h> <<
034 #include <sos/thread.h> <<
035 #include <sos/process.h> <<
036 #include <sos/klibc.h> 032 #include <sos/klibc.h>
037 #include <sos/assert.h> 033 #include <sos/assert.h>
038 #include <drivers/x86_videomem.h> 034 #include <drivers/x86_videomem.h>
039 #include <drivers/bochs.h> 035 #include <drivers/bochs.h>
040 #include <sos/calcload.h> <<
041 036
042 037
043 038
044 039
045 void display_bits(unsigned char row, unsigned !! 040 static void display_bits(unsigned char row, unsigned char col,
046 unsigned char attribute, !! 041 unsigned char attribute,
047 sos_ui32_t integer) !! 042 sos_ui32_t integer)
048 { 043 {
049 int i; 044 int i;
050 045
051 for (i = 31 ; i >= 0 ; i--) 046 for (i = 31 ; i >= 0 ; i--)
052 { 047 {
053 048
054 int bit_i = (integer & (1 << i)); 049 int bit_i = (integer & (1 << i));
055 050
056 unsigned char ascii_code = bit_i?219:177 051 unsigned char ascii_code = bit_i?219:177;
057 sos_x86_videomem_putchar(row, col++, 052 sos_x86_videomem_putchar(row, col++,
058 attribute, 053 attribute,
059 ascii_code); 054 ascii_code);
060 } 055 }
061 } 056 }
062 057
063 058
064 059
065 static void clk_it(int intid) 060 static void clk_it(int intid)
066 { 061 {
067 static sos_ui32_t clock_count = 0; 062 static sos_ui32_t clock_count = 0;
068 063
069 display_bits(0, 48, 064 display_bits(0, 48,
070 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 065 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
071 clock_count); 066 clock_count);
072 clock_count++; 067 clock_count++;
073 068
074 !! 069 }
075 sos_time_do_tick(); !! 070 struct digit
>> 071 {
>> 072 struct digit *prev, *next;
>> 073 char value;
>> 074 };
076 075
077 !! 076
078 sos_sched_do_timer_tick(); !! 077
>> 078
>> 079 typedef struct digit * big_number_t;
>> 080
>> 081
>> 082
>> 083 void bn_push_lsd(big_number_t * bn, char value)
>> 084 {
>> 085 struct digit *d;
>> 086 d = (struct digit*) sos_kmalloc(sizeof(struct digit), 0);
>> 087 SOS_ASSERT_FATAL(d != NULL);
>> 088 d->value = value;
>> 089 list_add_tail(*bn, d);
079 } 090 }
080 091
081 092
082 !! 093
083 !! 094 void bn_push_msd(big_number_t * bn, char value)
084 !! 095 {
>> 096 struct digit *d;
>> 097 d = (struct digit*) sos_kmalloc(sizeof(struct digit), 0);
>> 098 SOS_ASSERT_FATAL(d != NULL);
>> 099 d->value = value;
>> 100 list_add_head(*bn, d);
>> 101 }
085 102
086 103
087 !! 104
088 static void pgflt_ex(int intid, struct sos_cpu !! 105 big_number_t bn_new(unsigned long int i)
089 { 106 {
090 static sos_ui32_t demand_paging_count = 0; !! 107 big_number_t retval;
091 sos_vaddr_t faulting_vaddr = sos_cpu_contex <<
092 sos_paddr_t ppage_paddr; <<
093 108
094 if (sos_cpu_context_is_in_user_mode(ctxt)) !! 109 list_init(retval);
>> 110 do
095 { 111 {
096 !! 112 bn_push_msd(&retval, i%10);
097 !! 113 i /= 10;
098 sos_bochs_printf("Unresolved USER page F <<
099 sos_cpu_context_get_PC( <<
100 (unsigned)faulting_vadd <<
101 (unsigned)sos_cpu_conte <<
102 sos_bochs_printf("Terminating User threa <<
103 sos_thread_exit(); <<
104 } 114 }
>> 115 while (i != 0);
>> 116
>> 117 return retval;
>> 118 }
>> 119
105 120
106 !! 121
107 if (! sos_kmem_vmm_is_valid_vaddr(faulting_v !! 122 big_number_t bn_copy(const big_number_t bn)
>> 123 {
>> 124 big_number_t retval;
>> 125 int nb_elts;
>> 126 struct digit *d;
>> 127
>> 128 list_init(retval);
>> 129 list_foreach(bn, d, nb_elts)
108 { 130 {
109 !! 131 bn_push_lsd(&retval, d->value);
110 <<
111 sos_display_fatal_error("Unresolved page <<
112 sos_cpu_context_ <<
113 (unsigned)faulti <<
114 (unsigned)sos_cp <<
115 SOS_ASSERT_FATAL(! "Got page fault (note <<
116 } 132 }
117 133
118 !! 134 return retval;
119 <<
120 <<
121 <<
122 <<
123 <<
124 demand_paging_count ++; <<
125 display_bits(0, 0, <<
126 SOS_X86_VIDEO_FG_LTRED | SOS_X8 <<
127 demand_paging_count); <<
128 <<
129 <<
130 ppage_paddr = sos_physmem_ref_physpage_new(F <<
131 if (! ppage_paddr) <<
132 SOS_ASSERT_FATAL(! "TODO: implement swap. <<
133 SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp <<
134 SO <<
135 FA <<
136 SO <<
137 | <<
138 | <<
139 sos_physmem_unref_physpage(ppage_paddr); <<
140 <<
141 <<
142 } 135 }
143 136
144 137
145 !! 138
146 !! 139 void bn_del(big_number_t * bn)
147 <<
148 <<
149 <<
150 <<
151 <<
152 struct thr_arg <<
153 { 140 {
154 char character; !! 141 struct digit *d;
155 int color; <<
156 142
157 int col; !! 143 list_collapse(*bn, d)
158 int row; !! 144 {
159 }; !! 145 sos_kfree((sos_vaddr_t)d);
>> 146 }
>> 147 }
160 148
161 149
162 static void demo_thread(void *arg) !! 150
>> 151 void bn_shift(big_number_t *bn, int shift)
163 { 152 {
164 struct thr_arg *thr_arg = (struct thr_arg*)a !! 153 for ( ; shift > 0 ; shift --)
165 int progress = 0; <<
166 <<
167 sos_bochs_printf("start %c", thr_arg->charac <<
168 while (1) <<
169 { 154 {
170 progress ++; !! 155 bn_push_lsd(bn, 0);
171 display_bits(thr_arg->row, thr_arg->col+ !! 156 }
>> 157 }
172 158
173 sos_bochs_putchar(thr_arg->character); <<
174 159
175 !! 160
176 if ((random() % 100) == 0) !! 161 void bn_print_bochs(const big_number_t bn)
177 { !! 162 {
178 sos_bochs_printf("[37myield(%c)[m\ !! 163 int nb_elts;
179 sos_x86_videomem_putchar(thr_arg->ro !! 164 const struct digit *d;
180 SOS_ASSERT_FATAL(SOS_OK == sos_threa <<
181 sos_x86_videomem_putchar(thr_arg->ro <<
182 } <<
183 165
184 !! 166 if (list_is_empty(bn))
185 else if ((random() % 200) == 0) !! 167 sos_bochs_printf("0");
186 { !! 168 else
187 struct sos_time t = (struct sos_time !! 169 list_foreach(bn, d, nb_elts)
188 sos_bochs_printf("[37msleep1(%c)[m !! 170 sos_bochs_printf("%d", d->value);
189 sos_x86_videomem_putchar(thr_arg->ro !! 171 }
190 SOS_ASSERT_FATAL(SOS_OK == sos_threa !! 172
191 SOS_ASSERT_FATAL(sos_time_is_zero(& !! 173
192 sos_x86_videomem_putchar(thr_arg->ro !! 174 void bn_print_console(unsigned char row, unsigned char col,
193 } !! 175 unsigned char attribute,
>> 176 const big_number_t bn,
>> 177 int nb_decimals)
>> 178 {
>> 179 if (list_is_empty(bn))
>> 180 sos_x86_videomem_printf(row, col, attribute, "0");
>> 181 else
>> 182 {
>> 183 int nb_elts;
>> 184 const struct digit *d;
>> 185 unsigned char x = col;
194 186
195 !! 187 list_foreach(bn, d, nb_elts)
196 else if ((random() % 300) == 0) <<
197 { 188 {
198 struct sos_time t = (struct sos_time !! 189 if (nb_elts == 0)
199 sos_bochs_printf("[37msleep2(%c)[m !! 190 {
200 sos_x86_videomem_putchar(thr_arg->ro !! 191 sos_x86_videomem_printf(row, x, attribute, "%d.", d->value);
201 SOS_ASSERT_FATAL(SOS_OK == sos_threa !! 192 x += 2;
202 SOS_ASSERT_FATAL(sos_time_is_zero(& !! 193 }
203 sos_x86_videomem_putchar(thr_arg->ro !! 194 else if (nb_elts < nb_decimals)
>> 195 {
>> 196 sos_x86_videomem_printf(row, x, attribute, "%d", d->value);
>> 197 x ++;
>> 198 }
204 } 199 }
205 200
206 !! 201 sos_x86_videomem_printf(row, x, attribute, " . 10^{%d} ", nb_elts-1);
207 } 202 }
208 } 203 }
209 204
210 205
211 static void test_thread() !! 206
>> 207 big_number_t bn_add (const big_number_t bn1, const big_number_t bn2)
212 { 208 {
213 !! 209 big_number_t retval;
214 !! 210 const struct digit *d1, *d2;
215 static struct thr_arg arg_b, arg_c, arg_d, a !! 211 sos_bool_t bn1_end = FALSE, bn2_end = FALSE;
216 sos_ui32_t flags; !! 212 char carry = 0;
217 !! 213
218 sos_disable_IRQs(flags); !! 214 list_init(retval);
>> 215 d1 = list_get_tail(bn1);
>> 216 bn1_end = list_is_empty(bn1);
>> 217 d2 = list_get_tail(bn2);
>> 218 bn2_end = list_is_empty(bn2);
>> 219 do
>> 220 {
>> 221 if (! bn1_end)
>> 222 carry += d1->value;
>> 223 if (! bn2_end)
>> 224 carry += d2->value;
>> 225
>> 226 bn_push_msd(&retval, carry % 10);
>> 227 carry /= 10;
>> 228
>> 229 if (! bn1_end)
>> 230 d1 = d1->prev;
>> 231 if (! bn2_end)
>> 232 d2 = d2->prev;
>> 233 if (d1 == list_get_tail(bn1))
>> 234 bn1_end = TRUE;
>> 235 if (d2 == list_get_tail(bn2))
>> 236 bn2_end = TRUE;
>> 237 }
>> 238 while (!bn1_end || !bn2_end);
219 239
220 arg_b = (struct thr_arg) { .character='b', . !! 240 if (carry > 0)
221 sos_create_kernel_thread("YO[b]", demo_threa !! 241 {
>> 242 bn_push_msd(&retval, carry);
>> 243 }
222 244
223 arg_c = (struct thr_arg) { .character='c', . !! 245 return retval;
224 sos_create_kernel_thread("YO[c]", demo_threa !! 246 }
225 247
226 arg_d = (struct thr_arg) { .character='d', . <<
227 sos_create_kernel_thread("YO[d]", demo_threa <<
228 248
229 arg_e = (struct thr_arg) { .character='e', . !! 249
230 sos_create_kernel_thread("YO[e]", demo_threa !! 250 big_number_t bn_muli (const big_number_t bn, char digit)
>> 251 {
>> 252 big_number_t retval;
>> 253 int nb_elts;
>> 254 char carry = 0;
>> 255 const struct digit *d;
231 256
232 arg_R = (struct thr_arg) { .character='R', . !! 257 list_init(retval);
233 sos_create_kernel_thread("YO[R]", demo_threa !! 258 list_foreach_backward(bn, d, nb_elts)
>> 259 {
>> 260 carry += d->value * digit;
>> 261 bn_push_msd(&retval, carry % 10);
>> 262 carry /= 10;
>> 263 }
234 264
235 arg_S = (struct thr_arg) { .character='S', . !! 265 if (carry > 0)
236 sos_create_kernel_thread("YO[S]", demo_threa !! 266 {
>> 267 bn_push_msd(&retval, carry);
>> 268 }
237 269
238 sos_restore_IRQs(flags); !! 270 return retval;
239 } 271 }
240 272
241 273
242 !! 274
243 !! 275 big_number_t bn_mult(const big_number_t bn1, const big_number_t bn2)
244 <<
245 <<
246 static void idle_thread() <<
247 { 276 {
248 sos_ui32_t idle_twiddle = 0; !! 277 int shift = 0;
>> 278 big_number_t retval;
>> 279 int nb_elts;
>> 280 struct digit *d;
249 281
250 while (1) !! 282 list_init(retval);
>> 283 list_foreach_backward(bn2, d, nb_elts)
251 { 284 {
252 !! 285 big_number_t retmult = bn_muli(bn1, d->value);
253 !! 286 big_number_t old_retval = retval;
254 asm("hlt\n"); !! 287 bn_shift(& retmult, shift);
255 !! 288 retval = bn_add(old_retval, retmult);
256 idle_twiddle ++; !! 289 bn_del(& retmult);
257 display_bits(0, 0, SOS_X86_VIDEO_FG_GREE !! 290 bn_del(& old_retval);
258 idle_twiddle); !! 291 shift ++;
259 <<
260 <<
261 sos_thread_yield(); <<
262 } 292 }
>> 293
>> 294 return retval;
263 } 295 }
264 296
265 297
266 !! 298
267 !! 299 big_number_t bn_fact(unsigned long int v)
268 <<
269 static void stat_thread() <<
270 { 300 {
271 while (1) !! 301 unsigned long int i;
>> 302 big_number_t retval = bn_new(1);
>> 303 for (i = 1 ; i <= v ; i++)
272 { 304 {
273 sos_ui32_t flags; !! 305 big_number_t I = bn_new(i);
274 sos_ui32_t load1, load5, load15; !! 306 big_number_t tmp = bn_mult(retval, I);
275 char str1[11], str5[11], str15[11]; !! 307 sos_x86_videomem_printf(4, 0,
276 struct sos_time t; !! 308 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
277 t.sec = 1; !! 309 "%d! = ", (int)i);
278 t.nanosec = 0; !! 310 bn_print_console(4, 8, SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_WHITE,
279 !! 311 tmp, 55);
280 sos_thread_sleep(& t); !! 312 bn_del(& I);
281 !! 313 bn_del(& retval);
282 sos_disable_IRQs(flags); !! 314 retval = tmp;
283 !! 315 }
284 <<
285 sos_load_get_sload(&load1, &load5, &load <<
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, <<
290 SOS_X86_VIDEO_FG <<
291 "Kernel (- Idle) <<
292 str1, str5, str1 <<
293 316
294 sos_load_get_uload(&load1, &load5, &load !! 317 return retval;
295 sos_load_to_string(str1, load1); !! 318 }
296 sos_load_to_string(str5, load5); <<
297 sos_load_to_string(str15, load15); <<
298 sos_x86_videomem_printf(17, 34, <<
299 SOS_X86_VIDEO_FG <<
300 "User: %s %s %s <<
301 str1, str5, str1 <<
302 319
303 sos_load_get_uratio(&load1, &load5, &loa <<
304 sos_load_to_string(str1, load1); <<
305 sos_load_to_string(str5, load5); <<
306 sos_load_to_string(str15, load15); <<
307 sos_x86_videomem_printf(18, 34, <<
308 SOS_X86_VIDEO_FG <<
309 "User CPU %%: %s <<
310 str1, str5, str1 <<
311 320
312 !! 321 void bn_test()
313 sos_load_get_sratio(&load1, &load5, &loa !! 322 {
314 sos_load_to_string(str1, load1); !! 323 big_number_t bn = bn_fact(1000);
315 sos_load_to_string(str5, load5); !! 324 sos_bochs_printf("1000! = ");
316 sos_load_to_string(str15, load15); !! 325 bn_print_bochs(bn);
317 sos_x86_videomem_printf(19, 34, !! 326 sos_bochs_printf("\n");
318 SOS_X86_VIDEO_FG !! 327
319 "Kernel CPU %% ( <<
320 str1, str5, str1 <<
321 sos_restore_IRQs(flags); <<
322 } <<
323 } 328 }
324 329
325 330
326 !! 331
327 <<
328 <<
329 void sos_main(unsigned long magic, unsigned lo 332 void sos_main(unsigned long magic, unsigned long addr)
330 { 333 {
331 unsigned i; 334 unsigned i;
332 sos_paddr_t sos_kernel_core_base_paddr, sos_ 335 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
333 struct sos_time tick_resolution; <<
334 336
335 337
336 338
337 339
338 multiboot_info_t *mbi; 340 multiboot_info_t *mbi;
339 mbi = (multiboot_info_t *) addr; 341 mbi = (multiboot_info_t *) addr;
340 342
341 343
342 sos_bochs_setup(); 344 sos_bochs_setup();
343 345
344 sos_x86_videomem_setup(); 346 sos_x86_videomem_setup();
345 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 347 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
346 348
347 349
348 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 350 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
349 351
350 sos_x86_videomem_printf(1, 0, 352 sos_x86_videomem_printf(1, 0,
351 SOS_X86_VIDEO_FG_Y 353 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
352 "Welcome From GRUB 354 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
353 "SOS article 7", ' !! 355 "SOS", ',',
354 (unsigned)(mbi->me 356 (unsigned)(mbi->mem_upper >> 10) + 1,
355 (unsigned)mbi->mem 357 (unsigned)mbi->mem_upper);
356 else 358 else
357 359
358 sos_x86_videomem_printf(1, 0, 360 sos_x86_videomem_printf(1, 0,
359 SOS_X86_VIDEO_FG_Y 361 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
360 "Welcome to SOS ar !! 362 "Welcome to SOS");
361 363
362 sos_bochs_putstring("Message in a bochs: Thi !! 364 sos_bochs_putstring("Message in a bochs\n");
363 365
364 366
365 sos_gdt_subsystem_setup(); !! 367 sos_gdt_setup();
366 sos_idt_subsystem_setup(); !! 368 sos_idt_setup();
367 369
368 370
369 sos_exception_subsystem_setup(); !! 371 sos_exceptions_setup();
370 sos_irq_subsystem_setup(); !! 372 sos_irq_setup();
371 373
372 374
373 sos_i8254_set_frequency(100); 375 sos_i8254_set_frequency(100);
374 376
375 <<
376 <<
377 tick_resolution = (struct sos_time) { .sec=0 <<
378 sos_time_subsysem_setup(& tick_resolution); <<
379 377
380 378
381 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 379 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
382 { 380 {
383 sos_x86_videomem_putstring(20, 0, 381 sos_x86_videomem_putstring(20, 0,
384 SOS_X86_VIDEO 382 SOS_X86_VIDEO_FG_LTRED
385 | SOS_X86_V 383 | SOS_X86_VIDEO_BG_BLUE
386 | SOS_X86_V 384 | SOS_X86_VIDEO_FG_BLINKING,
387 "I'm not load 385 "I'm not loaded with Grub !");
388 386
389 for (;;) 387 for (;;)
390 continue; 388 continue;
391 } 389 }
392 390
393 <<
394 <<
395 <<
396 <<
397 391
398 sos_irq_set_routine(SOS_IRQ_TIMER, 392 sos_irq_set_routine(SOS_IRQ_TIMER,
399 clk_it); !! 393 clk_it);
400 !! 394
401 !! 395
402 !! 396 asm volatile ("sti\n");
403 <<
404 <<
405 397
406 398
407 399
408 sos_physmem_subsystem_setup((mbi->mem_upper< !! 400 sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
409 & sos_kernel_cor !! 401 & sos_kernel_core_base_paddr,
410 & sos_kernel_cor !! 402 & sos_kernel_core_top_paddr);
411 403
412 404
413 405
414 406
415 407
416 408
417 409
418 SOS_ASSERT_FATAL(SOS_OK == !! 410 if (sos_paging_setup(sos_kernel_core_base_paddr,
419 sos_paging_subsystem_setup( !! 411 sos_kernel_core_top_paddr))
420 !! 412 sos_bochs_printf("Could not setup paged memory mode\n");
421 !! 413 sos_x86_videomem_printf(2, 0,
422 !! 414 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
423 sos_exception_set_routine(SOS_EXCEPT_PAGE_FA !! 415 "Paged-memory mode is activated");
424 pgflt_ex); <<
425 416
426 <<
427 <<
428 <<
429 417
430 if (sos_kmem_vmm_subsystem_setup(sos_kernel_ !! 418 if (sos_kmem_vmm_setup(sos_kernel_core_base_paddr,
431 sos_kernel_ !! 419 sos_kernel_core_top_paddr))
432 bootstrap_s <<
433 bootstrap_s <<
434 + bootstrap <<
435 sos_bochs_printf("Could not setup the Kern 420 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
436 421
437 if (sos_kmalloc_subsystem_setup()) !! 422 if (sos_kmalloc_setup())
438 sos_bochs_printf("Could not setup the Kmal 423 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
439 424
440 !! 425
441 !! 426 bn_test();
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_b <<
462 bootstrap_stack_s <<
463 <<
464 <<
465 sos_sched_subsystem_setup(); <<
466 <<
467 <<
468 SOS_ASSERT_FATAL(sos_create_kernel_thread("i <<
469 SO <<
470 <<
471 <<
472 sos_load_subsystem_setup(); <<
473 <<
474 <<
475 SOS_ASSERT_FATAL(sos_create_kernel_thread("s <<
476 NU <<
477 SO <<
478 <<
479 <<
480 <<
481 <<
482 <<
483 sos_process_subsystem_setup(); <<
484 427
>> 428
>> 429 for (;;)
>> 430 continue;
485 431
486 !! 432 return;
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 !\ <<
512 sos_thread_exit(); <<
513 SOS_FATAL_ERROR("No trespassing !"); <<
514 } 433 }