]> pd.if.org Git - zos/blob - kernel.c
add a readme with a public domain note
[zos] / kernel.c
1 #include <stddef.h>
2 #include <stdint.h>
3  
4 #include <time.h>
5
6 #include "multiboot.h"
7 #include "kernel.h"
8 #include "interrupt.h"
9 #include "timer.h"
10 #include "mem.h"
11 #include "process.h"
12
13 #include "tty.h"
14 #include "kbd.h"
15 #include "pci/pci.h"
16
17 #include <smp.h>
18 #include <syscall.h>
19
20 #include <string.h>
21
22 int global_errno;
23
24 extern uint64_t _asm_physmap;
25
26 /* Check if the compiler thinks if we are targeting the wrong operating system. */
27 #if defined(__linux__)
28 #error "compiling for linux, not target os"
29 #endif
30  
31 #define STACK_SIZE  65536
32 __attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_t)];
33  
34 static void check_mbmagic(uint64_t magic) {
35         if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
36                 printk("Invalid magic number: 0x%x\n", (unsigned) magic);
37                 allstop();
38         }
39 }
40
41 void kernel_main(struct multiboot_info *mbinfo, uint64_t mbmagic) {
42
43         /* we do this first so we can print debug messages */
44         terminal_initialize();
45
46         terminal.writestring("ZOS 64 bit booting...\n");
47         check_mbmagic(mbmagic);
48         
49         printk("kernel_vma       = 0x%llx\n", (uint64_t)_kernel_vma);
50         printk("kernel_end       = 0x%llx\n", (uint64_t)_kernel_end);
51         printk("kernel_phys_end  = 0x%llx\n", (uint64_t)_kernel_phys_end);
52         printk("kernel_size      = %llu KB\n", (uint64_t)_kernel_size/1024);
53         printk("_asm_physmap    = %llx\n", _asm_physmap);
54
55 #define MBADDR(x) (PHY2VIRTP((paddr_t)(x)))
56
57         /* get modules */
58         if (mbinfo->mods_count > 0) {
59                 void *mod;
60                 struct multiboot_mod_list *modlist;
61                 char *start;
62                 int n;
63
64                 mod = MBADDR(mbinfo->mods_addr);
65                 modlist = mod;
66                 for (n=0;n<mbinfo->mods_count;n++) {
67                         char line[80];
68                         printk("Module: %s\n", MBADDR(modlist[n].cmdline));
69                         start = MBADDR(modlist[n].mod_start);
70                         memcpy(line, start,80);
71                         line[79] = 0;
72                         printk("%s\n", line);
73                 }
74         }
75
76         mem_init(mbinfo);
77
78         printk("mem.kend    = 0x%llx\n", (uint64_t)memory.kend);
79
80         vmem_test();
81
82         pci_init();
83         init_smp();
84         init_interrupts();
85         init_timer(200); /* arg is timer tick interrupt Hz */
86         /* klog isn't really useful before here */
87         init_syscalls();
88         init_tasking();
89
90         /* from here on out, we may be interrupted */
91         init_keyboard();
92
93         while (1) {
94                 schedule();
95                 /* since we're the current task when we call schedule,
96                  * we won't get back on the runqueue.  The 0 task
97                  * will still be allocated.  That's ok, it's a static
98                  * structure in process.c anyway.
99                  * If it changes to dynamic alloc, would want to
100                  * clean it up
101                  */
102                 printk("shouldn't happen\n");
103                 halt();
104         }
105
106         return;
107 }
108
109 void klog(int level, const char *fmt, ...) {
110         va_list ap;
111
112         printk("[%u.%u] ", system_time.tv_sec, system_time.tv_nsec/1000000);
113
114         va_start(ap, fmt);
115         printkv(fmt, ap);
116         va_end(ap);
117 }
118
119 void panic(const char *fmt, ...) {
120         va_list ap;
121
122         va_start(ap, fmt);
123         printkv(fmt, ap);
124         va_end(ap);
125
126         while (1) {
127                 allstop();
128                 halt();
129         }
130 }