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
021 #include <bootstrap/multiboot.h> 021 #include <bootstrap/multiboot.h>
022 #include <hwcore/idt.h> 022 #include <hwcore/idt.h>
023 #include <hwcore/gdt.h> 023 #include <hwcore/gdt.h>
024 #include <hwcore/irq.h> 024 #include <hwcore/irq.h>
025 #include <hwcore/exception.h> 025 #include <hwcore/exception.h>
026 #include <hwcore/i8254.h> 026 #include <hwcore/i8254.h>
027 #include <sos/list.h> 027 #include <sos/list.h>
028 #include <sos/physmem.h> 028 #include <sos/physmem.h>
029 #include <hwcore/paging.h> 029 #include <hwcore/paging.h>
030 #include <sos/kmem_vmm.h> !! 030 #include <sos/list.h>
031 #include <sos/kmalloc.h> <<
032 #include <sos/klibc.h> 031 #include <sos/klibc.h>
033 #include <sos/assert.h> 032 #include <sos/assert.h>
034 #include <drivers/x86_videomem.h> 033 #include <drivers/x86_videomem.h>
035 #include <drivers/bochs.h> 034 #include <drivers/bochs.h>
036 035
037 036
038 037
039 038
040 static void display_bits(unsigned char row, un 039 static void display_bits(unsigned char row, unsigned char col,
041 unsigned char attribu 040 unsigned char attribute,
042 sos_ui32_t integer) 041 sos_ui32_t integer)
043 { 042 {
044 int i; 043 int i;
045 044
046 for (i = 31 ; i >= 0 ; i--) 045 for (i = 31 ; i >= 0 ; i--)
047 { 046 {
048 047
049 int bit_i = (integer & (1 << i)); 048 int bit_i = (integer & (1 << i));
050 049
051 unsigned char ascii_code = bit_i?219:177 050 unsigned char ascii_code = bit_i?219:177;
052 sos_x86_videomem_putchar(row, col++, 051 sos_x86_videomem_putchar(row, col++,
053 attribute, 052 attribute,
054 ascii_code); 053 ascii_code);
055 } 054 }
056 } 055 }
057 056
058 057
059 058
060 static void clk_it(int intid) 059 static void clk_it(int intid)
061 { 060 {
062 static sos_ui32_t clock_count = 0; 061 static sos_ui32_t clock_count = 0;
063 062
064 display_bits(0, 48, 063 display_bits(0, 48,
065 SOS_X86_VIDEO_FG_LTGREEN | SOS_ 064 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
066 clock_count); 065 clock_count);
067 clock_count++; 066 clock_count++;
068 067
069 } 068 }
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(struc <<
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(struc <<
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 069
173 !! 070
174 void bn_print_console(unsigned char row, unsig !! 071 static void pgflt_ex(int exid)
175 unsigned char attribute, <<
176 const big_number_t bn, <<
177 int nb_decimals) <<
178 { 072 {
179 if (list_is_empty(bn)) !! 073 sos_bochs_printf("Got page fault\n");
180 sos_x86_videomem_printf(row, col, attribut !! 074 sos_x86_videomem_printf(10, 30,
181 else !! 075 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
182 { !! 076 "Got EXPECTED (?) Page fault ! But where ???");
183 int nb_elts; !! 077 for (;;) ;
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, <<
192 x += 2; <<
193 } <<
194 else if (nb_elts < nb_decimals) <<
195 { <<
196 sos_x86_videomem_printf(row, x, <<
197 x ++; <<
198 } <<
199 } <<
200 <<
201 sos_x86_videomem_printf(row, x, attribut <<
202 } <<
203 } 078 }
204 079
205 !! 080 static void test_paging(sos_vaddr_t sos_kernel_core_top_vaddr)
206 <<
207 big_number_t bn_add (const big_number_t bn1, c <<
208 { 081 {
209 big_number_t retval; !! 082
210 const struct digit *d1, *d2; !! 083
211 sos_bool_t bn1_end = FALSE, bn2_end = FALSE !! 084 sos_vaddr_t vpage_code = SOS_PAGE_ALIGN_INF(test_paging);
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 085
245 return retval; !! 086
246 } !! 087 sos_paddr_t ppage_new;
247 <<
248 <<
249 <<
250 big_number_t bn_muli (const big_number_t bn, c <<
251 { <<
252 big_number_t retval; <<
253 int nb_elts; <<
254 char carry = 0; <<
255 const struct digit *d; <<
256 088
257 list_init(retval); !! 089
258 list_foreach_backward(bn, d, nb_elts) !! 090
259 { !! 091 sos_vaddr_t vpage_tmp = sos_kernel_core_top_vaddr;
260 carry += d->value * digit; <<
261 bn_push_msd(&retval, carry % 10); <<
262 carry /= 10; <<
263 } <<
264 092
265 if (carry > 0) !! 093 unsigned i;
266 { <<
267 bn_push_msd(&retval, carry); <<
268 } <<
269 094
270 return retval; !! 095
271 } !! 096 sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
>> 097 pgflt_ex);
272 098
>> 099
>> 100
>> 101
>> 102
>> 103 sos_x86_videomem_printf(4, 0,
>> 104 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
>> 105 "Moving current code elsewhere in physical memory:");
273 106
274 <<
275 big_number_t bn_mult(const big_number_t bn1, c <<
276 { <<
277 int shift = 0; <<
278 big_number_t retval; <<
279 int nb_elts; <<
280 struct digit *d; <<
281 107
282 list_init(retval); !! 108
283 list_foreach_backward(bn2, d, nb_elts) !! 109 ppage_new = sos_physmem_ref_physpage_new(FALSE);
>> 110 if (! ppage_new)
284 { 111 {
285 big_number_t retmult = bn_muli(bn1, d->v !! 112
286 big_number_t old_retval = retval; !! 113 sos_x86_videomem_putstring(20, 0,
287 bn_shift(& retmult, shift); !! 114 SOS_X86_VIDEO_FG_LTRED
288 retval = bn_add(old_retval, retmult); !! 115 | SOS_X86_VIDEO_BG_BLUE,
289 bn_del(& retmult); !! 116 "test_paging : Cannot allocate page");
290 bn_del(& old_retval); !! 117 return;
291 shift ++; <<
292 } 118 }
293 119
294 return retval; !! 120 sos_x86_videomem_printf(5, 0,
295 } !! 121 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 122 "Hello from the address 0x%x in physical memory",
>> 123 sos_paging_get_paddr(vpage_code));
296 124
>> 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);
297 166
298 !! 167 sos_x86_videomem_printf(7, 0,
299 big_number_t bn_fact(unsigned long int v) !! 168 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
300 { !! 169 "Hello from the address 0x%x in physical memory",
301 unsigned long int i; !! 170 sos_paging_get_paddr(vpage_code));
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 <<
309 "%d! = ", (int)i <<
310 bn_print_console(4, 8, SOS_X86_VIDEO_BG_ <<
311 tmp, 55); <<
312 bn_del(& I); <<
313 bn_del(& retval); <<
314 retval = tmp; <<
315 } <<
316 171
317 return retval; !! 172 sos_x86_videomem_printf(9, 0,
318 } !! 173 SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
>> 174 "Provoking a page fault:");
319 175
>> 176
>> 177
>> 178
320 179
321 void bn_test() !! 180
322 { !! 181
323 big_number_t bn = bn_fact(1000); !! 182
324 sos_bochs_printf("1000! = "); !! 183
325 bn_print_bochs(bn); !! 184 for (i = vpage_code ; ; i += SOS_PAGE_SIZE)
326 sos_bochs_printf("\n"); !! 185 {
327 !! 186 unsigned *pint = (unsigned *)SOS_PAGE_ALIGN_INF(i);
>> 187 sos_bochs_printf("Test vaddr 0x%x : val=", (unsigned)pint);
>> 188 sos_x86_videomem_printf(10, 0,
>> 189 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 190 "Test vaddr 0x%x : val= ",
>> 191 (unsigned)pint);
>> 192 sos_bochs_printf("0x%x\n", *pint);
>> 193 sos_x86_videomem_printf(10, 30,
>> 194 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
>> 195 "0x%x ", *pint);
>> 196 }
>> 197
>> 198
>> 199 sos_x86_videomem_printf(20, 0,
>> 200 SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
>> 201 "We should have had a #PF at vaddr 0x%x !",
>> 202 vpage_tmp);
328 } 203 }
329 204
330 <<
331 205
332 void sos_main(unsigned long magic, unsigned lo 206 void sos_main(unsigned long magic, unsigned long addr)
333 { 207 {
334 unsigned i; 208 unsigned i;
335 sos_paddr_t sos_kernel_core_base_paddr, sos_ 209 sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
336 210
337 211
338 212
339 213
340 multiboot_info_t *mbi; 214 multiboot_info_t *mbi;
341 mbi = (multiboot_info_t *) addr; 215 mbi = (multiboot_info_t *) addr;
342 216
343 217
344 sos_bochs_setup(); 218 sos_bochs_setup();
345 219
346 sos_x86_videomem_setup(); 220 sos_x86_videomem_setup();
347 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); 221 sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
348 222
349 223
350 if (magic == MULTIBOOT_BOOTLOADER_MAGIC) 224 if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
351 225
352 sos_x86_videomem_printf(1, 0, 226 sos_x86_videomem_printf(1, 0,
353 SOS_X86_VIDEO_FG_Y 227 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
354 "Welcome From GRUB 228 "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
355 "SOS", ',', 229 "SOS", ',',
356 (unsigned)(mbi->me 230 (unsigned)(mbi->mem_upper >> 10) + 1,
357 (unsigned)mbi->mem 231 (unsigned)mbi->mem_upper);
358 else 232 else
359 233
360 sos_x86_videomem_printf(1, 0, 234 sos_x86_videomem_printf(1, 0,
361 SOS_X86_VIDEO_FG_Y 235 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
362 "Welcome to SOS"); 236 "Welcome to SOS");
363 237
364 sos_bochs_putstring("Message in a bochs\n"); 238 sos_bochs_putstring("Message in a bochs\n");
365 239
366 240
367 sos_gdt_setup(); 241 sos_gdt_setup();
368 sos_idt_setup(); 242 sos_idt_setup();
369 243
370 244
371 sos_exceptions_setup(); 245 sos_exceptions_setup();
372 sos_irq_setup(); 246 sos_irq_setup();
373 247
374 248
375 sos_i8254_set_frequency(100); 249 sos_i8254_set_frequency(100);
376 250
377 251
378 252
379 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 253 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
380 { 254 {
381 sos_x86_videomem_putstring(20, 0, 255 sos_x86_videomem_putstring(20, 0,
382 SOS_X86_VIDEO 256 SOS_X86_VIDEO_FG_LTRED
383 | SOS_X86_V 257 | SOS_X86_VIDEO_BG_BLUE
384 | SOS_X86_V 258 | SOS_X86_VIDEO_FG_BLINKING,
385 "I'm not load 259 "I'm not loaded with Grub !");
386 260
387 for (;;) 261 for (;;)
388 continue; 262 continue;
389 } 263 }
390 264
391 265
392 sos_irq_set_routine(SOS_IRQ_TIMER, 266 sos_irq_set_routine(SOS_IRQ_TIMER,
393 clk_it); 267 clk_it);
394 268
395 269
396 asm volatile ("sti\n"); 270 asm volatile ("sti\n");
397 271
398 272
399 273
400 sos_physmem_setup((mbi->mem_upper<<10) + (1< 274 sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
401 & sos_kernel_core_base_pad 275 & sos_kernel_core_base_paddr,
402 & sos_kernel_core_top_padd 276 & sos_kernel_core_top_paddr);
403 277
404 278
405 279
406 280
407 281
408 282
409 283
410 if (sos_paging_setup(sos_kernel_core_base_pa 284 if (sos_paging_setup(sos_kernel_core_base_paddr,
411 sos_kernel_core_top_pad 285 sos_kernel_core_top_paddr))
412 sos_bochs_printf("Could not setup paged me 286 sos_bochs_printf("Could not setup paged memory mode\n");
413 sos_x86_videomem_printf(2, 0, 287 sos_x86_videomem_printf(2, 0,
414 SOS_X86_VIDEO_FG_YEL 288 SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
415 "Paged-memory mode i 289 "Paged-memory mode is activated");
416 290
417 !! 291 test_paging(sos_kernel_core_top_paddr);
418 if (sos_kmem_vmm_setup(sos_kernel_core_base_ <<
419 sos_kernel_core_top_p <<
420 sos_bochs_printf("Could not setup the Kern <<
421 <<
422 if (sos_kmalloc_setup()) <<
423 sos_bochs_printf("Could not setup the Kmal <<
424 <<
425 <<
426 bn_test(); <<
427 292
428 293
429 for (;;) 294 for (;;)
430 continue; 295 continue;
431 296
432 return; 297 return;
433 } 298 }