kconfig: use pkg-config for ncurses detection
[akaros.git] / kern / src / init.c
1 /* See COPYRIGHT for copyright information. */
2
3 #ifdef CONFIG_BSD_ON_CORE0
4 #error "Yeah, it's not possible to build ROS with BSD on Core 0, sorry......"
5 #else
6
7 #include <arch/arch.h>
8 #include <arch/topology.h>
9 #include <arch/console.h>
10 #include <multiboot.h>
11 #include <smp.h>
12
13 #include <time.h>
14 #include <atomic.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <assert.h>
18 #include <monitor.h>
19 #include <pmap.h>
20 #include <process.h>
21 #include <trap.h>
22 #include <syscall.h>
23 #include <manager.h>
24 #include <testing.h>
25 #include <kmalloc.h>
26 #include <hashtable.h>
27 #include <radix.h>
28 #include <mm.h>
29 #include <ex_table.h>
30 #include <percpu.h>
31
32 #include <arch/init.h>
33 #include <bitmask.h>
34 #include <slab.h>
35 #include <kthread.h>
36 #include <linker_func.h>
37 #include <net/ip.h>
38 #include <acpi.h>
39 #include <coreboot_tables.h>
40 #include <rcu.h>
41 #include <dma.h>
42
43 #define MAX_BOOT_CMDLINE_SIZE 4096
44
45 #define ASSIGN_PTRVAL(prm, top, val)                                    \
46 do {                                                                    \
47         if (prm && (prm < top)) {                                       \
48                 *prm = val;                                             \
49                 prm++;                                                  \
50         }                                                               \
51 } while (0)
52
53 bool booting = TRUE;
54 struct proc_global_info __proc_global_info;
55 struct sysinfo_t sysinfo;
56 static char boot_cmdline[MAX_BOOT_CMDLINE_SIZE];
57
58 static void run_linker_funcs(void);
59 static int run_init_script(void);
60
61 const char *get_boot_option(const char *base, const char *option, char *param,
62                             size_t max_param)
63 {
64         size_t optlen = strlen(option);
65         char *ptop = param + max_param - 1;
66         const char *opt, *arg;
67
68         if (!base)
69                 base = boot_cmdline;
70         for (;;) {
71                 opt = strstr(base, option);
72                 if (!opt)
73                         return NULL;
74                 if (((opt == base) || (opt[-1] == ' ')) &&
75                         ((opt[optlen] == 0) || (opt[optlen] == '=') ||
76                          (opt[optlen] == ' ')))
77                         break;
78                 base = opt + optlen;
79         }
80         arg = opt + optlen;
81         if (*arg == '=') {
82                 arg++;
83                 if (*arg == '\'') {
84                         arg++;
85                         for (; *arg; arg++) {
86                                 if (*arg == '\\')
87                                         arg++;
88                                 else if (*arg == '\'')
89                                         break;
90                                 ASSIGN_PTRVAL(param, ptop, *arg);
91                         }
92                 } else {
93                         for (; *arg && (*arg != ' '); arg++)
94                                 ASSIGN_PTRVAL(param, ptop, *arg);
95                 }
96         }
97         ASSIGN_PTRVAL(param, ptop, 0);
98
99         return arg;
100 }
101
102 static void extract_multiboot_cmdline(struct multiboot_info *mbi)
103 {
104         if (mbi && (mbi->flags & MULTIBOOT_INFO_CMDLINE) && mbi->cmdline) {
105                 const char *cmdln = (const char *) KADDR(mbi->cmdline);
106
107                 /* We need to copy the command line in a permanent buffer, since
108                  * the multiboot memory where it is currently residing will be
109                  * part of the free boot memory later on in the boot process. */
110                 strlcpy(boot_cmdline, cmdln, sizeof(boot_cmdline));
111         }
112 }
113
114 static void __kernel_init_part_deux(void *arg);
115
116 void kernel_init(multiboot_info_t *mboot_info)
117 {
118         extern char __start_bss[], __stop_bss[];
119
120         memset(__start_bss, 0, __stop_bss - __start_bss);
121         /* mboot_info is a physical address.  while some arches currently have
122          * the lower memory mapped, everyone should have it mapped at kernbase
123          * by now.  also, it might be in 'free' memory, so once we start
124          * dynamically using memory, we may clobber it. */
125         multiboot_kaddr = (struct multiboot_info*)((physaddr_t)mboot_info
126                                                + KERNBASE);
127         extract_multiboot_cmdline(multiboot_kaddr);
128
129         cons_init();
130         print_cpuinfo();
131
132         printk("Boot Command Line: '%s'\n", boot_cmdline);
133
134         exception_table_init();
135         num_cores = get_early_num_cores();
136         pmem_init(multiboot_kaddr);
137         kmalloc_init();
138         vmap_init();
139         hashtable_init();
140         radix_init();
141         dma_arena_init();
142         acpiinit();
143         topology_init();
144         percpu_init();
145         kthread_init();         /* might need to tweak when this happens */
146         vmr_init();
147         page_check();
148         idt_init();
149         /* After kthread_init and idt_init, we can use a real kstack. */
150         __use_real_kstack(__kernel_init_part_deux);
151 }
152
153 static void __kernel_init_part_deux(void *arg)
154 {
155         kernel_msg_init();
156         timer_init();
157         time_init();
158         arch_init();
159         rcu_init();
160         enable_irq();
161         run_linker_funcs();
162         /* reset/init devtab after linker funcs 3 and 4.  these run NIC and
163          * medium pre-inits, which need to happen before devether.  Note
164          * tmpfs_reset.
165          *
166          * Reset vs init - who the fuck knows.  Both are called during init
167          * time.  It might be that init is a one-time ever per boot thing, and
168          * resets are paired with shutdowns.  So init, reset, shutdown reset. */
169         devtabreset();
170         devtabinit();
171
172 #ifdef CONFIG_ETH_AUDIO
173         eth_audio_init();
174 #endif /* CONFIG_ETH_AUDIO */
175         get_coreboot_info(&sysinfo);
176         booting = FALSE;
177
178 #ifdef CONFIG_RUN_INIT_SCRIPT
179         if (run_init_script()) {
180                 printk("Told to run init script, but no script specified\n");
181                 manager();
182         }
183 #else
184         manager();
185 #endif
186 }
187
188 #ifdef CONFIG_RUN_INIT_SCRIPT
189 static int run_init_script(void)
190 {
191         /* If we have an init script path specified */
192         if (strlen(CONFIG_INIT_SCRIPT_PATH_AND_ARGS) != 0) {
193                 int vargs = 0;
194                 char *sptr = &CONFIG_INIT_SCRIPT_PATH_AND_ARGS[0];
195
196                 /* Figure out how many arguments there are, by finding the
197                  * spaces */
198                 /* TODO: consider rewriting this stuff with parsecmd */
199                 while (*sptr != '\0') {
200                         if (*(sptr++) != ' ') {
201                                 vargs++;
202                                 while ((*sptr != ' ') && (*sptr != '\0'))
203                                         sptr++;
204                         }
205                 }
206
207                 /* Initialize l_argv with its first three arguments, but
208                  * allocate space for all arguments as calculated above */
209                 int static_args = 2;
210                 int total_args = vargs + static_args;
211                 char *l_argv[total_args];
212                 l_argv[0] = "/bin/bash";
213                 l_argv[1] = "bash";
214
215                 /* Initialize l_argv with the rest of the arguments */
216                 int i = static_args;
217
218                 sptr = &CONFIG_INIT_SCRIPT_PATH_AND_ARGS[0];
219                 while (*sptr != '\0') {
220                         if (*sptr != ' ') {
221                                 l_argv[i++] = sptr;
222                                 while ((*sptr != ' ') && (*sptr != '\0'))
223                                         sptr++;
224                                 if (*sptr == '\0')
225                                         break;
226                                 *sptr = '\0';
227                         }
228                         sptr++;
229                 }
230
231                 /* Run the script with its arguments */
232                 mon_bin_run(total_args, l_argv, NULL);
233         }
234         return -1;
235 }
236 #endif
237
238 /* Multiple cores can panic concurrently.  We could also panic recursively,
239  * which could deadlock.  We also only want to automatically backtrace the first
240  * time through, since BTs are often the source of panics.  Finally, we want to
241  * know when the other panicking cores are done (or likely to be done) before
242  * entering the monitor.
243  *
244  * We'll use the print_lock(), which is recursive, to protect panic_printing. */
245 static bool panic_printing;
246 static DEFINE_PERCPU(int, panic_depth);
247
248 /*
249  * Panic is called on unresolvable fatal errors.
250  * It prints "panic: mesg", and then enters the kernel monitor.
251  */
252 void _panic(struct hw_trapframe *hw_tf, const char *file, int line,
253             const char *fmt, ...)
254 {
255         struct per_cpu_info *pcpui = &per_cpu_info[core_id_early()];
256         va_list ap;
257
258         print_lock();
259         panic_printing = true;
260         PERCPU_VAR(panic_depth)++;
261
262         va_start(ap, fmt);
263         printk("\nkernel panic at %s:%d, from core %d: ", file, line,
264                core_id_early());
265         vcprintf(fmt, ap);
266         printk("\n");
267         va_end(ap);
268         /* Recursive panics are usually backtrace problems.  Possibly printk.
269          * Locking panics might recurse forever. */
270         if (PERCPU_VAR(panic_depth) == 1) {
271                 if (hw_tf) {
272                         print_trapframe(hw_tf);
273                         backtrace_hwtf(hw_tf);
274                 } else {
275                         backtrace();
276                 }
277         } else {
278                 printk("\tRecursive kernel panic on core %d (depth %d)\n",
279                        core_id_early(), PERCPU_VAR(panic_depth));
280         }
281         printk("\n");
282
283         /* If we're here, we panicked and currently hold the print_lock.  We
284          * might have panicked recursively.  We must unlock unconditionally,
285          * since the initial panic (which grabbed the lock) will never run
286          * again. */
287         panic_printing = false;
288         print_unlock_force();
289         /* And we have to clear the depth, so that we lock again next time in.
290          * Otherwise, we'd be unlocking without locking (which is another
291          * panic). */
292         PERCPU_VAR(panic_depth) = 0;
293
294         /* Let's wait long enough for other printers to finish before entering
295          * the monitor. */
296         do {
297                 udelay(500000);
298                 cmb();
299         } while (panic_printing);
300
301         /* Yikes!  We're claiming to be not in IRQ/trap ctx and not holding any
302          * locks.  Obviously we could be wrong, and could easily deadlock.  We
303          * could be in an IRQ handler, an unhandled kernel fault, or just a
304          * 'normal' panic in a syscall - any of which can involve unrestore
305          * invariants. */
306         pcpui->__ctx_depth = 0;
307         pcpui->lock_depth = 0;
308         /* And keep this off, for good measure. */
309         pcpui->__lock_checking_enabled--;
310
311         monitor(NULL);
312
313         if (pcpui->cur_proc) {
314                 printk("panic killing proc %d\n", pcpui->cur_proc->pid);
315                 proc_destroy(pcpui->cur_proc);
316         }
317         if (pcpui->cur_kthread)
318                 kth_panic_sysc(pcpui->cur_kthread);
319         smp_idle();
320 }
321
322 void _warn(const char *file, int line, const char *fmt,...)
323 {
324         va_list ap;
325
326         print_lock();
327         va_start(ap, fmt);
328         printk("\nkernel warning at %s:%d, from core %d: ", file, line,
329                core_id_early());
330         vcprintf(fmt, ap);
331         printk("\n");
332         va_end(ap);
333         backtrace();
334         printk("\n");
335         print_unlock();
336 }
337
338 static void run_links(linker_func_t *linkstart, linker_func_t *linkend)
339 {
340         /* Unlike with devtab, our linker sections for the function pointers are
341          * 8 byte aligned (4 on 32 bit) (done by the linker/compiler), so we
342          * don't have to worry about that.  */
343         printd("linkstart %p, linkend %p\n", linkstart, linkend);
344         for (int i = 0; &linkstart[i] < linkend; i++) {
345                 printd("i %d, linkfunc %p\n", i, linkstart[i]);
346                 linkstart[i]();
347         }
348 }
349
350 static void run_linker_funcs(void)
351 {
352         run_links(__linkerfunc1start, __linkerfunc1end);
353         run_links(__linkerfunc2start, __linkerfunc2end);
354         run_links(__linkerfunc3start, __linkerfunc3end);
355         run_links(__linkerfunc4start, __linkerfunc4end);
356 }
357
358 /* You need to reference PROVIDE symbols somewhere, or they won't be included.
359  * Only really a problem for debugging. */
360 void debug_linker_tables(void)
361 {
362         extern struct dev __devtabstart[];
363         extern struct dev __devtabend[];
364         printk("devtab %p %p\nlink1 %p %p\nlink2 %p %p\nlink3 %p %p\nlink4 %p %p\n",
365                __devtabstart,
366                __devtabend,
367                    __linkerfunc1start,
368                    __linkerfunc1end,
369                    __linkerfunc2start,
370                    __linkerfunc2end,
371                    __linkerfunc3start,
372                    __linkerfunc3end,
373                    __linkerfunc4start,
374                    __linkerfunc4end);
375 }
376
377 #endif //Everything For Free