Friendly with GCC > 4.1
[akaros.git] / kern / init.c
1 /* See COPYRIGHT for copyright information. */
2
3 #include <inc/stdio.h>
4 #include <inc/string.h>
5 #include <inc/assert.h>
6 #include <inc/multiboot.h>
7 #include <inc/stab.h>
8
9 #include <kern/monitor.h>
10 #include <kern/console.h>
11 #include <kern/pmap.h>
12 #include <kern/kclock.h>
13 #include <kern/env.h>
14 #include <kern/trap.h>
15
16 void print_cpuinfo(void);
17
18 void kernel_init(multiboot_info_t *mboot_info)
19 {
20         extern char (BND(__this, end) edata)[], (SNT end)[];
21
22         // Before doing anything else, complete the ELF loading process.
23         // Clear the uninitialized global data (BSS) section of our program.
24         // This ensures that all static/global variables start out zero.
25         memset(edata, 0, end - edata);
26
27         // Initialize the console.
28         // Can't call cprintf until after we do this!
29         cons_init();
30
31         print_cpuinfo();
32
33         // Lab 2 memory management initialization functions
34         i386_detect_memory();
35         i386_vm_init();
36         page_init();
37         page_check();
38
39         // Lab 3 user environment initialization functions
40         env_init();
41         idt_init();
42
43         // Temporary test code specific to LAB 3
44 #if defined(TEST)
45         // Don't touch -- used by grading script!
46         ENV_CREATE2(TEST, TESTSIZE);
47 #else
48         // Touch all you want.
49         //ENV_CREATE(user_faultread);
50         //ENV_CREATE(user_faultreadkernel);
51         //ENV_CREATE(user_faultwrite);
52         //ENV_CREATE(user_faultwritekernel);
53         //ENV_CREATE(user_breakpoint);
54         //ENV_CREATE(user_badsegment);
55         //ENV_CREATE(user_divzero);
56         ENV_CREATE(user_hello);
57         ENV_CREATE(user_buggyhello);
58         ENV_CREATE(user_evilhello);
59 #endif // TEST*
60
61         // We only have one user environment for now, so just run it.
62         env_run(&envs[0]);
63 }
64
65
66 /*
67  * Variable panicstr contains argument to first call to panic; used as flag
68  * to indicate that the kernel has already called panic.
69  */
70 static const char *NTS panicstr;
71
72 /*
73  * Panic is called on unresolvable fatal errors.
74  * It prints "panic: mesg", and then enters the kernel monitor.
75  */
76 void _panic(const char *file, int line, const char *fmt,...)
77 {
78         va_list ap;
79
80         if (panicstr)
81                 goto dead;
82         panicstr = fmt;
83
84         va_start(ap, fmt);
85         cprintf("kernel panic at %s:%d: ", file, line);
86         vcprintf(fmt, ap);
87         cprintf("\n");
88         va_end(ap);
89
90 dead:
91         /* break into the kernel monitor */
92         while (1)
93                 monitor(NULL);
94 }
95
96 /* like panic, but don't */
97 void _warn(const char *file, int line, const char *fmt,...) 
98 {
99         va_list ap;
100
101         va_start(ap, fmt);
102         cprintf("kernel warning at %s:%d: ", file, line);
103         vcprintf(fmt, ap);
104         cprintf("\n");
105         va_end(ap);
106 }
107
108 void print_cpuinfo(void) {
109         int func_num;
110         char vendor_id[13];
111
112         asm volatile ("subl    %0, %0;"
113                   "cpuid;"
114                   "movl    %%ebx, (%1);"
115                   "movl    %%edx, 4(%1);"
116                   "movl    %%ecx, 8(%1);"
117                       : "=a"(func_num) 
118                                   : "D"(vendor_id)
119                       : "%ebx", "%ecx", "%edx");
120
121         vendor_id[12] = '\0';
122         cprintf("Largest Standard Function Number Supported: %d\n", func_num);
123         cprintf("Vendor ID: %s\n", vendor_id);
124 }
125
126
127         /* Backup of old shit that i hoard for no reason
128          *
129          * all of this was in kernel_init
130         cprintf("6828 decimal is %o octal!\n", 6828);
131         cprintf("Symtab section should begin at: 0x%x \n", stab);
132
133         // double check
134         mboot_info = (multiboot_info_t*)(0xc0000000 + (char*)mboot_info);
135         cprintf("Mboot info address: %p\n", mboot_info);
136         elf_section_header_table_t *elf_head= &(mboot_info->u.elf_sec);
137         cprintf("elf sec info address: %p\n", elf_head);
138     cprintf ("elf_sec: num = %u, size = 0x%x, addr = 0x%x, shndx = 0x%x\n",
139             elf_head->num, elf_head->size,
140             elf_head->addr, elf_head->shndx);
141         
142         struct Secthdr *elf_sym = (struct Secthdr*)(0xc0000000 + elf_head->addr + elf_head->size * 3);
143
144         cprintf("Symtab multiboot struct address: %p\n", elf_sym);
145         cprintf("Symtab multiboot address: %p\n", elf_sym->sh_addr);
146
147         // this walks a symtable, but we don't have one...
148         Elf32_Sym* symtab = (Elf32_Sym*)stab;
149         Elf32_Sym* oldsymtab = symtab;
150         for (; symtab < oldsymtab + 10 ; symtab++) {
151                 cprintf("Symbol name index = 0x%x\n", symtab->st_name);
152                 //cprintf("Symbol name = %s\n", stabstr + symtab->st_name);
153                 cprintf("Symbol vale = 0x%x\n", symtab->st_value);
154         }
155         */
156         /*
157         extern stab_t stab[], estab[];
158         extern char stabstr[];
159         stab_t* symtab;
160         // Spits out the stabs for functions
161         for (symtab = stab; symtab < estab; symtab++) {
162                 // gives us only functions.  not really needed if we scan by address
163                 if (symtab->n_type != 36)
164                         continue;
165                 cprintf("Symbol name = %s\n", stabstr + symtab->n_strx);
166                 cprintf("Symbol type = %d\n", symtab->n_type);
167                 cprintf("Symbol value = 0x%x\n", symtab->n_value);
168                 cprintf("\n");
169         }
170         */
171
172