/// lcrash entry point /// super awesome... #include #include #include #include #include #include #include #include #include #include #include "types.h" #include "lnxboot.h" #include "efi/efi.h" struct SysbusDevice* TryFindScreen(struct SysbusDevice* Device) { if (SysbusGetCapability(Device, TextModeDisplayCapabilityGetCapability()) != NULL) { return Device; } for (int i = 0; i < Device->ChildCount; i++) { struct SysbusDevice* ChildDevice = TryFindScreen(Device->Children[i]); if (ChildDevice != NULL) return ChildDevice; } return NULL; } /** * Fill a screen range with a character. * Positions are 1-indexed */ void FillScreenCharRange(struct SysbusDevice* Device, struct TextModeDisplayCapability* TMDC, u32 R0, u32 C0, u32 R1, u32 C1, c8 Char, u32 FG, u32 BG) { R0 -= 1; R1 -= 1; C0 -= 1; C1 -= 1; for (int r = R0; r <= R1; r++) { for (int c = C0; c <= C1; c++) { TMDC->SetCharacter(Device, r, c, Char, FG, BG); } } } /** * Draw text at a location * Positions are 1-indexed */ void DrawTextBox(struct SysbusDevice* Device, struct TextModeDisplayCapability* TMDC, u32 R0, u32 C0, u32 R1, u32 C1, u32 FG, u32 BG, c8* Text) { R0 -= 1; R1 -= 1; C0 -= 1; C1 -= 1; bool InText = true; int Row = R0; int Col = 0; for (Row = R0; Row <= R1; Row++) { for (Col = C0; Col <= C1;) { if (*Text == 0) InText = false; if (InText) { c8 Char = *Text; if (Char >= 'a' && Char <= 'z') Char = Char - 'a' + 'A'; if (Char == '\r') { Col = C0; } else if (Char == '\n') { Row += 1; } else { TMDC->SetCharacter(Device, Row, Col, Char, FG, BG); Col += 1; } Text += 1; } else { TMDC->SetCharacter(Device, Row, Col, ' ', FG, BG); Col += 1; } } } return; } [[noreturn]] void entry64(struct boot_params* BootParams) { BootBootParams = BootParams; BootSetupInfo = (void*)BootParams + 0x1f1; // Notify the debugger that we're ready struct GdbDataBlock* GdbDataBlock = (struct GdbDataBlock*)0x100000; GdbDataBlock->KernelLoaded = true; GdbDataBlock->KernelBase = (void*)BootSetupInfo->code32_start; GdbDataBlock->Update++; // Parse the kernel command line CmdlineParse((c8*)( ((uptr)BootSetupInfo->cmd_line_ptr) |((uptr)BootBootParams->ext_cmd_line_ptr << 32))); // Initialize the physical memory manager if (PmemInitialize()) while (1) {} // Initialize the kernel heap if (KernelHeapInitialize()) while (1) {} // Initialize the IRQ handler if (IrqHandlerInitialize()) while (1) {} // Enable interrupts IrqHandlerEnableInterrupts(); // Initialize the extended debugging information block if (DebugInitialize()) while (1) {} // Initialize the virtual memory manager VmemInitialize(); // Initialize the system bus SysbusInitialize(); // Initialize EFI code if we had EFI EfiInitialize(); // Initialize ACPI code if we have ACPI AcpiInitialize(); // Initialize PCI code.. PciInitialize(); // Try to find a screen and write some crap to it. // TODO: REMOVE WHEN DONE WITH DISPLAY DRIVERS if (!TextModeDisplayCapabilityIsInitialized()) TextModeDisplayCapabilityInitialize(); struct SysbusDevice* Screen = TryFindScreen(SysbusGetRootDevice()); if (Screen == 0) Panic("No screen found"); struct TextModeDisplayCapability* ScreenTMDC = SysbusGetCapability(Screen, TextModeDisplayCapabilityGetCapability()); if (ScreenTMDC->Reset(Screen)) Panic("Failed to reset screen"); if (ScreenTMDC->Enable(Screen)) Panic("Failed to enable screen"); // Set color palette ScreenTMDC->SetPaletteColor(Screen, 0, 0, 0, 0 ); ScreenTMDC->SetPaletteColor(Screen, 1, 200, 0, 0 ); ScreenTMDC->SetPaletteColor(Screen, 2, 200, 200, 200); // Clear screen FillScreenCharRange(Screen, ScreenTMDC, 1, 1, 25, 80, ' ', 1, 1); // Draw header DrawTextBox(Screen, ScreenTMDC, 4, 32, 4, 47, 2, 1, " YOU FUCKED UP! "); // Draw body DrawTextBox(Screen, ScreenTMDC, 6, 5, 8, 75, 1, 2, "A fatal error has occurred and Lindows has shut down to prevent damage to your device."); DrawTextBox(Screen, ScreenTMDC, 10, 5, 13, 75, 1, 2, "If this error occurs again after a reboot, check the logs in `C:/Windows/Logs/`. If you are unable to correct the error, try dumping the system and analyzing it in GDB or submitting a bug report with the dump and logs included."); DrawTextBox(Screen, ScreenTMDC, 21, 5, 22, 75, 1, 2, "Press any key to reboot.\r\nPress ESC to dump the system state to `C:/Windows/SystemDump/`."); // Hang :) while (1) {} }