#include "./arch/lapic.h" #include "./debug/copystream.h" #include "./debug/output.h" #include "./device/serialstream.h" #include "./types.h" // This is actually used #include "arch/core_interrupt.h" SerialStream sout; #include "./device/textstream.h" // Separate title window on first line (for simplicity at scrolling) static TextStream tout(0, CGA::COLUMNS, 0, 1); TextStream dout(0, 80, 17, 25); CopyStream copystream(&dout, &sout); OutputStream* copyout = ©stream; #include "./arch/core.h" #include "./arch/ioapic.h" #include "./device/ps2controller.h" #include "./interrupt/guard.h" #include "./sync/semaphore.h" #include "./thread/thread.h" Semaphore koutsem(1); TextStream kout(0, 80, 1, 17, true); // Applications #include "./user/app1/appl.h" #include "./user/app2/kappl.h" static const uint32_t NUM_APPS = 9; Application apps[NUM_APPS]; static KeyboardApplication kapp; // Main function extern "C" int main() { tout.reset(); tout.setPos(33, 0); tout << OS_NAME << " (2.x)" << flush; //// double faults correctly //volatile uint16_t test1 = 0; //volatile uint16_t test = 8/test1; // Initialize IOAPIC IOAPIC::init(); // Init timer (1000us = 1ms) LAPIC::Timer::setup(10000); // Activate Keyboard PS2Controller::init(); // Enter Level 1/2 Guarded g = Guard::enter(); for (uint32_t i = 0; i < NUM_APPS; ++i) { g.vault().scheduler.ready(&(apps[i])); } g.vault().scheduler.ready(&kapp); // Enable Interrupts Core::Interrupt::enable(); /* Activate timer * Be careful: * If enabled early and interrupts are enabled, it might start scheduling * (resume in epilogue) and dispatch the first app, never returning back to * main and finish initialization. * Therefore activate the LAPIC timer in level 1/2 after initialization * (just before schedule()) */ LAPIC::Timer::activate(); DBG_VERBOSE << "Schedule..." << endl; // Schedule first app g.vault().scheduler.schedule(); return 0; }