001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021 #include <bootstrap/multiboot.h>
022 #include <hwcore/idt.h>
023 #include <hwcore/gdt.h>
024 #include <hwcore/irq.h>
025 #include <hwcore/exception.h>
026 #include <hwcore/i8254.h>
027 #include <sos/list.h>
028 #include <sos/physmem.h>
029 #include <hwcore/paging.h>
030 #include <sos/kmem_vmm.h>
031 #include <sos/kmalloc.h>
032 #include <sos/klibc.h>
033 #include <sos/assert.h>
034 #include <drivers/x86_videomem.h>
035 #include <drivers/bochs.h>
036
037
038
039
040 static void display_bits(unsigned char row, unsigned char col,
041 unsigned char attribute,
042 sos_ui32_t integer)
043 {
044 int i;
045
046 for (i = 31 ; i >= 0 ; i--)
047 {
048
049 int bit_i = (integer & (1 << i));
050
051 unsigned char ascii_code = bit_i?219:177;
052 sos_x86_videomem_putchar(row, col++,
053 attribute,
054 ascii_code);
055 }
056 }
057
058
059
060 static void clk_it(int intid)
061 {
062 static sos_ui32_t clock_count = 0;
063
064 display_bits(0, 48,
065 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
066 clock_count);
067 clock_count++;
068
069 }
070 struct digit
071 {
072 struct digit *prev, *next;
073 char value;
074 };
075
076
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);
090 }
091
092
093
094 void bn_push_msd(big_number_t * bn, char value)
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 }
102
103
104
105 big_number_t bn_new(unsigned long int i)
106 {
107 big_number_t retval;
108
109 list_init(retval);
110 do
111 {
112 bn_push_msd(&retval, i%10);
113 i /= 10;
114 }
115 while (i != 0);
116
117 return retval;
118 }
119
120
121
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)
130 {
131 bn_push_lsd(&retval, d->value);
132 }
133
134 return retval;
135 }
136
137
138
139 void bn_del(big_number_t * bn)
140 {
141 struct digit *d;
142
143 list_collapse(*bn, d)
144 {
145 sos_kfree((sos_vaddr_t)d);
146 }
147 }
148
149
150
151 void bn_shift(big_number_t *bn, int shift)
152 {
153 for ( ; shift > 0 ; shift --)
154 {
155 bn_push_lsd(bn, 0);
156 }
157 }
158
159
160
161 void bn_print_bochs(const big_number_t bn)
162 {
163 int nb_elts;
164 const struct digit *d;
165
166 if (list_is_empty(bn))
167 sos_bochs_printf("0");
168 else
169 list_foreach(bn, d, nb_elts)
170 sos_bochs_printf("%d", d->value);
171 }
172
173
174 void bn_print_console(unsigned char row, unsigned char col,
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;
186
187 list_foreach(bn, d, nb_elts)
188 {
189 if (nb_elts == 0)
190 {
191 sos_x86_videomem_printf(row, x, attribute, "%d.", d->value);
192 x += 2;
193 }
194 else if (nb_elts < nb_decimals)
195 {
196 sos_x86_videomem_printf(row, x, attribute, "%d", d->value);
197 x ++;
198 }
199 }
200
201 sos_x86_videomem_printf(row, x, attribute, " . 10^{%d} ", nb_elts-1);
202 }
203 }
204
205
206
207 big_number_t bn_add (const big_number_t bn1, const big_number_t bn2)
208 {
209 big_number_t retval;
210 const struct digit *d1, *d2;
211 sos_bool_t bn1_end = FALSE, bn2_end = FALSE;
212 char carry = 0;
213
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);
239
240 if (carry > 0)
241 {
242 bn_push_msd(&retval, carry);
243 }
244
245 return retval;
246 }
247
248
249
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;
256
257 list_init(retval);
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 }
264
265 if (carry > 0)
266 {
267 bn_push_msd(&retval, carry);
268 }
269
270 return retval;
271 }
272
273
274
275 big_number_t bn_mult(const big_number_t bn1, const big_number_t bn2)
276 {
277 int shift = 0;
278 big_number_t retval;
279 int nb_elts;
280 struct digit *d;
281
282 list_init(retval);
283 list_foreach_backward(bn2, d, nb_elts)
284 {
285 big_number_t retmult = bn_muli(bn1, d->value);
286 big_number_t old_retval = retval;
287 bn_shift(& retmult, shift);
288 retval = bn_add(old_retval, retmult);
289 bn_del(& retmult);
290 bn_del(& old_retval);
291 shift ++;
292 }
293
294 return retval;
295 }
296
297
298
299 big_number_t bn_fact(unsigned long int v)
300 {
301 unsigned long int i;
302 big_number_t retval = bn_new(1);
303 for (i = 1 ; i <= v ; i++)
304 {
305 big_number_t I = bn_new(i);
306 big_number_t tmp = bn_mult(retval, I);
307 sos_x86_videomem_printf(4, 0,
308 SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
309 "%d! = ", (int)i);
310 bn_print_console(4, 8, SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_WHITE,
311 tmp, 55);
312 bn_del(& I);
313 bn_del(& retval);
314 retval = tmp;
315 }
316
317 return retval;
318 }
319
320
321 void bn_test()
322 {
323 big_number_t bn = bn_fact(1000);
324 sos_bochs_printf("1000! = ");
325 bn_print_bochs(bn);
326 sos_bochs_printf("\n");
327
328 }
329
330
331
332 void sos_main(unsigned long magic, unsigned long addr)
333 {
334 unsigned i;
335 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
336
337
338
339
340 multiboot_info_t *mbi;
341 mbi = (multiboot_info_t *) addr;
342
343
344 sos_bochs_setup();
345
346 sos_x86_videomem_setup();
347 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
348
349
350 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
351
352 sos_x86_videomem_printf(1, 0,
353 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
354 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
355 "SOS", ',',
356 (unsigned)(mbi->mem_upper >> 10) + 1,
357 (unsigned)mbi->mem_upper);
358 else
359
360 sos_x86_videomem_printf(1, 0,
361 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
362 "Welcome to SOS");
363
364 sos_bochs_putstring("Message in a bochs\n");
365
366
367 sos_gdt_setup();
368 sos_idt_setup();
369
370
371 sos_exceptions_setup();
372 sos_irq_setup();
373
374
375 sos_i8254_set_frequency(100);
376
377
378
379 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
380 {
381 sos_x86_videomem_putstring(20, 0,
382 SOS_X86_VIDEO_FG_LTRED
383 | SOS_X86_VIDEO_BG_BLUE
384 | SOS_X86_VIDEO_FG_BLINKING,
385 "I'm not loaded with Grub !");
386
387 for (;;)
388 continue;
389 }
390
391
392 sos_irq_set_routine(SOS_IRQ_TIMER,
393 clk_it);
394
395
396 asm volatile ("sti\n");
397
398
399
400 sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
401 & sos_kernel_core_base_paddr,
402 & sos_kernel_core_top_paddr);
403
404
405
406
407
408
409
410 if (sos_paging_setup(sos_kernel_core_base_paddr,
411 sos_kernel_core_top_paddr))
412 sos_bochs_printf("Could not setup paged memory mode\n");
413 sos_x86_videomem_printf(2, 0,
414 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
415 "Paged-memory mode is activated");
416
417
418 if (sos_kmem_vmm_setup(sos_kernel_core_base_paddr,
419 sos_kernel_core_top_paddr))
420 sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
421
422 if (sos_kmalloc_setup())
423 sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
424
425
426 bn_test();
427
428
429 for (;;)
430 continue;
431
432 return;
433 }