]> pd.if.org Git - zos/blobdiff - kernel.c
kernel startup and linker script
[zos] / kernel.c
diff --git a/kernel.c b/kernel.c
new file mode 100644 (file)
index 0000000..aed3d72
--- /dev/null
+++ b/kernel.c
@@ -0,0 +1,130 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <time.h>
+
+#include "multiboot.h"
+#include "kernel.h"
+#include "interrupt.h"
+#include "timer.h"
+#include "mem.h"
+#include "process.h"
+
+#include "tty.h"
+#include "kbd.h"
+#include "pci/pci.h"
+
+#include <smp.h>
+#include <syscall.h>
+
+#include <string.h>
+
+int global_errno;
+
+extern uint64_t _asm_physmap;
+
+/* Check if the compiler thinks if we are targeting the wrong operating system. */
+#if defined(__linux__)
+#error "compiling for linux, not target os"
+#endif
+#define STACK_SIZE  65536
+__attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_t)];
+static void check_mbmagic(uint64_t magic) {
+       if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
+               printk("Invalid magic number: 0x%x\n", (unsigned) magic);
+               allstop();
+       }
+}
+
+void kernel_main(struct multiboot_info *mbinfo, uint64_t mbmagic) {
+
+       /* we do this first so we can print debug messages */
+       terminal_initialize();
+
+       terminal.writestring("ZOS 64 bit booting...\n");
+       check_mbmagic(mbmagic);
+       
+       printk("kernel_vma       = 0x%llx\n", (uint64_t)_kernel_vma);
+       printk("kernel_end       = 0x%llx\n", (uint64_t)_kernel_end);
+       printk("kernel_phys_end  = 0x%llx\n", (uint64_t)_kernel_phys_end);
+       printk("kernel_size      = %llu KB\n", (uint64_t)_kernel_size/1024);
+       printk("_asm_physmap    = %llx\n", _asm_physmap);
+
+#define MBADDR(x) (PHY2VIRTP((paddr_t)(x)))
+
+       /* get modules */
+       if (mbinfo->mods_count > 0) {
+               void *mod;
+               struct multiboot_mod_list *modlist;
+               char *start;
+               int n;
+
+               mod = MBADDR(mbinfo->mods_addr);
+               modlist = mod;
+               for (n=0;n<mbinfo->mods_count;n++) {
+                       char line[80];
+                       printk("Module: %s\n", MBADDR(modlist[n].cmdline));
+                       start = MBADDR(modlist[n].mod_start);
+                       memcpy(line, start,80);
+                       line[79] = 0;
+                       printk("%s\n", line);
+               }
+       }
+
+       mem_init(mbinfo);
+
+       printk("mem.kend    = 0x%llx\n", (uint64_t)memory.kend);
+
+       vmem_test();
+
+       pci_init();
+       init_smp();
+       init_interrupts();
+       init_timer(200); /* arg is timer tick interrupt Hz */
+       /* klog isn't really useful before here */
+       init_syscalls();
+       init_tasking();
+
+       /* from here on out, we may be interrupted */
+       init_keyboard();
+
+       while (1) {
+               schedule();
+               /* since we're the current task when we call schedule,
+                * we won't get back on the runqueue.  The 0 task
+                * will still be allocated.  That's ok, it's a static
+                * structure in process.c anyway.
+                * If it changes to dynamic alloc, would want to
+                * clean it up
+                */
+               printk("shouldn't happen\n");
+               halt();
+       }
+
+       return;
+}
+
+void klog(int level, const char *fmt, ...) {
+        va_list ap;
+
+       printk("[%u.%u] ", system_time.tv_sec, system_time.tv_nsec/1000000);
+
+        va_start(ap, fmt);
+        printkv(fmt, ap);
+        va_end(ap);
+}
+
+void panic(const char *fmt, ...) {
+        va_list ap;
+
+        va_start(ap, fmt);
+        printkv(fmt, ap);
+        va_end(ap);
+
+       while (1) {
+               allstop();
+               halt();
+       }
+}