#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DISABLE_INTERRUPTS() asm volatile("cli") #define ENABLE_INTERRUPTS() asm volatile("sti") extern "C" const char g_kernel_cmdline[]; using namespace BAN; struct ParsedCommandLine { bool force_pic = false; bool disable_serial = false; }; ParsedCommandLine ParseCommandLine() { ParsedCommandLine result; if (!(g_multiboot_info->flags & 0x02)) return result; const char* start = g_kernel_cmdline; const char* current = g_kernel_cmdline; while (true) { if (!*current || *current == ' ' || *current == '\t') { if (current - start == 6 && memcmp(start, "noapic", 6) == 0) result.force_pic = true; if (current - start == 8 && memcmp(start, "noserial", 8) == 0) result.disable_serial = true; if (!*current) break; start = current + 1; } current++; } return result; } extern "C" void kernel_main() { using namespace Kernel; DISABLE_INTERRUPTS(); auto cmdline = ParseCommandLine(); if (!cmdline.disable_serial) Serial::initialize(); if (g_multiboot_magic != 0x2BADB002) { dprintln("Invalid multiboot magic number"); return; } dprintln("Serial output initialized"); kmalloc_initialize(); dprintln("kmalloc initialized"); IDT::initialize(); dprintln("IDT initialized"); MMU::intialize(); dprintln("MMU initialized"); TerminalDriver* terminal_driver = VesaTerminalDriver::create(); ASSERT(terminal_driver); dprintln("VESA initialized"); TTY* tty1 = new TTY(terminal_driver); InterruptController::initialize(cmdline.force_pic); dprintln("Interrupt controller initialized"); PIT::initialize(); dprintln("PIT initialized"); if (!Input::initialize()) return; dprintln("8042 initialized"); Scheduler::initialize(); Scheduler& scheduler = Scheduler::get(); scheduler.add_thread(BAN::Function([tty1] { Shell(tty1).run(); })); scheduler.start(); ASSERT(false); }