public static void Message(uint message) { BeginMessage(); Screen.Write(" Number: 0x"); Screen.Write(message, "X"); Halt(); }
private static void CompressedWriteMemory() { uint id = GetID(); uint address = GetDataUInt32(0); uint length = GetDataUInt32(4); uint size = GetDataUInt32(8); //uint uncompresscrc = GetDataUInt32(12); LZF.Decompress(new IntPtr(Address.DebuggerBuffer + HeaderSize), length, new IntPtr(address), size); Screen.Goto(15, 0); Screen.ClearRow(); Screen.Write("[CompressedWriteMemory]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write(id, 10, 5); Screen.Write(" Address: "); Screen.Write(address, 16, 8); Screen.Write(" Len: "); Screen.Write(length, 10, 5); Screen.Write(" Size: "); Screen.Write(size, 10, 5); Screen.Write(" CRC: "); //Screen.Write(uncompresscrc, 16, 8); //if (uncompresscrc == computedcrc) // Screen.Write(" OK"); //else // Screen.Write(" BAD"); SendResponse(id, DebugCode.CompressedWriteMemory); }
/// <summary> /// Dumps multiboot info. /// </summary> public static void Dump(uint row, uint col) { uint location = MultibootStructure; Screen.Row = row; Screen.Column = col; Screen.Color = 0x0A; Screen.Write('M'); Screen.Write('e'); Screen.Write('m'); Screen.Write('o'); Screen.Write('r'); Screen.Write('y'); Screen.Write('d'); Screen.Write('u'); Screen.Write('m'); Screen.Write('p'); Screen.NextLine(); Screen.NextLine(); for (uint i = 0; i < 80; i = i + 8) { Screen.Column = col; Screen.Color = 0x0F; Screen.Write(i, 10, 2); Screen.Write(':'); Screen.Write(' '); Screen.Color = 0x07; Screen.Write(Native.Get32(location + i), 16, 16); Screen.NextLine(); } }
public static void DumpRegisters() { Screen.Write("EIP: "); Screen.Write(EIP, 16, 8); Screen.Write(" ESP: "); Screen.Write(ESP, 16, 8); Screen.Write(" EBP: "); Screen.Write(EBP, 16, 8); Screen.Write(" EFLAGS: "); Screen.Write(EFLAGS, 16, 8); Screen.Write(" CR2: "); Screen.Write(CR2, 16, 8); Screen.NextLine(); Screen.Write("EAX: "); Screen.Write(EAX, 16, 8); Screen.Write(" EBX: "); Screen.Write(EBX, 16, 8); Screen.Write(" ECX: "); Screen.Write(ECX, 16, 8); Screen.Write(" CS: "); Screen.Write(CS, 16, 8); Screen.NextLine(); Screen.Write("EDX: "); Screen.Write(EDX, 16, 8); Screen.Write(" EDI: "); Screen.Write(EDI, 16, 8); Screen.Write(" EDX: "); Screen.Write(EDX, 16, 8); Screen.Write(" ERROR: "); Screen.Write(ErrorCode, 16, 2); Screen.Write(" IRQ: "); Screen.Write(Interrupt, 16, 2); Screen.NextLine(); }
/// <summary> /// Dump multiboot info. /// </summary> public void Dump(uint row, uint col) { Screen.Row = row; Screen.Column = col; Screen.Color = 0x0A; Screen.Write('C'); Screen.Write('M'); Screen.Write('O'); Screen.Write('S'); Screen.Write(':'); Screen.NextLine(); for (byte i = 0; i < 19; i++) { Screen.Column = col; Screen.Color = 0x0F; Screen.Write(i, 16, 2); Screen.Write(':'); Screen.Write(' '); Screen.Write(Get(i), 16, 2); Screen.Write(' '); Screen.Color = 0x07; Screen.Write(Get(i), 10, 3); Screen.NextLine(); } }
public static void ProcessQueue() { if (queueNext == queueCurrent) { return; } if (!UnitTestRunner.IsReady()) { return; } uint marker = Native.Get32(queueCurrent); if (marker == uint.MaxValue) { queueCurrent = Address.UnitTestQueue; } uint len = Native.Get32(queueCurrent); uint id = Native.Get32(queueCurrent + 4); uint address = Native.Get32(queueCurrent + 8); uint type = Native.Get32(queueCurrent + 12); uint paramcnt = Native.Get32(queueCurrent + 16); UnitTestRunner.SetUnitTestMethodAddress(address); UnitTestRunner.SetUnitTestResultType(type); UnitTestRunner.SetUnitTestMethodParameterCount(paramcnt); for (uint index = 0; index < paramcnt; index++) { uint value = Native.Get32(queueCurrent + 20 + (index * 4)); UnitTestRunner.SetUnitTestMethodParameter(index, value); } queueCurrent = queueCurrent + len + 4; --count; Screen.Goto(17, 0); Screen.ClearRow(); Screen.Write("[Unit Test]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write(id, 10, 5); Screen.Write(" Address: "); Screen.Write(address, 16, 8); Screen.Write(" Param: "); Screen.Write(paramcnt, 10, 2); Screen.Write(" Len: "); Screen.Write(len, 10, 4); Screen.Write(" - Cnt: "); Screen.Write(count, 10, 4); UnitTestRunner.StartTest(id); }
/// <summary> /// Interrupts the handler. /// </summary> /// <param name="stackStatePointer">The stack state pointer.</param> private unsafe static void ProcessInterrupt(uint stackStatePointer) { //KernelMessage.WriteLine("Interrupt occured"); var stack = (IDTStack *)stackStatePointer; var irq = stack->Interrupt; var info = IDTManager.handlers[irq]; IDTManager.RaisedCount++; if (info.CountStatistcs) { IDTManager.RaisedCountCustom++; } if (info.Trace) { KernelMessage.WriteLine("Interrupt: {0}", irq); } var col = Screen.column; var row = Screen.row; Screen.column = 0; Screen.Goto(2, 35); Screen.Write("Interrupts: "); Screen.Write(IDTManager.RaisedCount); Screen.Goto(3, 35); Screen.Write("IntNoClock: "); Screen.Write(IDTManager.RaisedCountCustom); Screen.row = row; Screen.column = col; if (irq < 0 || irq > 255) { Panic.Error("Invalid Interrupt"); } if (info.Handler == null) { //Panic.Error("Handlr is null"); } else { } info.Handler(stack); PIC.SendEndOfInterrupt(irq); }
/// <summary> /// Dumps this instance. /// </summary> public static void Dump2(uint row, uint col) { uint location = MemoryMapStart; Screen.Row = row; for (uint i = 0; i < 80; i = i + 4) { Screen.Column = col; Screen.Write(i, 10, 2); Screen.Write(':'); Screen.Write(' '); Screen.Write(Native.Get32(location + i), 16, 8); Screen.NextLine(); } }
/// <summary> /// Interrupts the handler. /// </summary> /// <param name="edi">The edi.</param> /// <param name="esi">The esi.</param> /// <param name="ebp">The ebp.</param> /// <param name="esp">The esp.</param> /// <param name="ebx">The ebx.</param> /// <param name="edx">The edx.</param> /// <param name="ecx">The ecx.</param> /// <param name="eax">The eax.</param> /// <param name="interrupt">The interrupt.</param> /// <param name="errorcode">The errorcode.</param> private static void InterruptHandler(uint edi, uint esi, uint ebp, uint esp, uint ebx, uint edx, uint ecx, uint eax, uint interrupt, uint errorCode) { uint c = Screen.Column; uint r = Screen.Row; byte col = Screen.Color; Screen.Column = 30; Screen.Row = 0; Screen.Color = 3; _counter++; Screen.Write(_counter, 10, 8); Screen.Write(':'); Screen.Write(interrupt, 16, 2); if (interrupt == 14) { // Page Fault! PageFaultHandler.Fault(errorCode); } if (interrupt == 0x20) { // Timer Interrupt! Switch Tasks! } else { Screen.Write(':'); Screen.Write(_counter, 10, 8); Screen.Write(':'); Screen.Write(interrupt, 16, 2); Screen.Write('-'); Screen.Write(errorCode, 16, 2); if (interrupt == 0x21) { byte scancode = Keyboard.ReadScanCode(); Screen.Write('-'); Screen.Write(scancode, 16, 2); } } Screen.Column = c; Screen.Row = r; Screen.Color = col; PIC.SendEndOfInterrupt((byte)interrupt); }
public static void Error(string message) { IDT.SetInterruptHandler(null); Screen.BackgroundColor = Color.Blue; Screen.Clear(); Screen.Goto(1, 0); Screen.Color = Color.White; Screen.Write("*** Kernel Panic ***"); if (firstError) { firstError = false; } else { Screen.Write(" (multiple)"); } Screen.NextLine(); Screen.NextLine(); Screen.Write(message); Screen.NextLine(); Screen.NextLine(); Screen.Write("REGISTERS:"); Screen.NextLine(); Screen.NextLine(); DumpRegisters(); Screen.NextLine(); Screen.Write("STACK TRACE:"); Screen.NextLine(); Screen.NextLine(); DumpStackTrace(); while (true) { // keep debugger running unsafe { Debugger.Process(null); } //Native.Hlt(); } }
private static void ProcessCommand() { // [0]![1]ID[5]CODE[6]LEN[10]DATA[LEN] int code = GetCode(); uint id = GetID(); uint len = GetLength(); Screen.Goto(13, 0); Screen.ClearRow(); Screen.Write("[Data]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write(id, 10, 5); Screen.Write(" Code: "); Screen.Write((uint)code, 10, 4); Screen.Write(" Len: "); Screen.Write(len, 10, 5); switch (code) { case DebugCode.Ping: SendResponse(GetID(), DebugCode.Ping); return; case DebugCode.ReadMemory: ReadMemory(); return; case DebugCode.ReadCR3: SendResponse(GetID(), DebugCode.ReadCR3, (int)Native.GetCR3()); return; case DebugCode.Scattered32BitReadMemory: Scattered32BitReadMemory(); return; case DebugCode.WriteMemory: WriteMemory(); return; case DebugCode.CompressedWriteMemory: CompressedWriteMemory(); return; case DebugCode.ClearMemory: ClearMemory(); return; case DebugCode.HardJump: HardJump(); return; case DebugCode.ExecuteUnitTest: QueueUnitTest(); return; case DebugCode.GetMemoryCRC: GetMemoryCRC(); return; default: return; } }
private unsafe static void HardJump() { uint id = GetID(); uint address = GetUInt32(16); SendResponse(id, DebugCode.HardJump); idt_stack->EIP = address; Screen.Goto(15, 0); Screen.ClearRow(); Screen.Write("[HardJump]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write((uint)id, 10, 5); Screen.Write(" Address: "); Screen.Write(address, 16, 8); }
/// <summary> /// Nows the specified error code. /// </summary> /// <param name="errorCode">The error code.</param> public static void Now(uint errorCode) { Screen.Column = 0; Screen.Row = 0; Screen.Color = 0x0C; Screen.Write('P'); Screen.Write('A'); Screen.Write('N'); Screen.Write('I'); Screen.Write('C'); Screen.Write('!'); Screen.Write(' '); Screen.Write(errorCode, 8, 8); while (true) { Native.Hlt(); } }
public unsafe static void DumpStackTrace(uint depth) { while (true) { var entry = Runtime.GetStackTraceEntry(depth, ebp, eip); if (!entry.Valid) { return; } if (!entry.Skip) { Screen.Write(entry.ToStringBuffer()); Screen.Row++; Screen.Column = 0; } depth++; } }
private static void WriteHexChar(byte num) { if (num >= 32 && num < 128) { Screen.Color = Colors.LightGray; Screen.Write((char)num); } else { if (num == 0) { Screen.Color = Colors.DarkGray; } else { Screen.Color = Colors.LightGray; } Screen.Write('.'); } }
private static void DumpStackTrace(uint depth) { while (true) { var entry = Internal.GetStackTraceEntry(depth, EBP, EIP); if (!entry.Valid) { return; } if (!entry.Skip) { Screen.Write(entry.ToStringBuffer()); Screen.Row++; Screen.Column = 0; } depth++; } }
private static void WriteHex(uint num, byte digits, byte color) { var oldColor = Screen.Color; Screen.Color = color; if (num == 0) { Screen.Color = Colors.LightGray; } var hex = new StringBuffer(num, "X"); for (var i = 0; i < digits - hex.Length; i++) { Screen.Write('0'); } Screen.Write(hex); Screen.Color = oldColor; }
private static void WriteMemory() { uint id = GetID(); uint address = GetUInt32(16); uint length = GetUInt32(20); SendResponse(id, DebugCode.WriteMemory); uint at = 0; while (at + 4 < length) { uint value = GetUInt32(24 + at); Native.Set32(address + at, value); at = at + 4; } while (at < length) { byte value = GetByte(24 + at); Native.Set8(address + at, value); at = at + 1; } Screen.Goto(15, 0); Screen.ClearRow(); Screen.Write("[WriteMemory]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write((uint)id, 10, 5); Screen.Write(" Address: "); Screen.Write(address, 16, 8); Screen.Write(" Len: "); Screen.Write(length, 10, 5); }
private static void WriteMemory() { uint id = GetID(); var address = GetDataPointer(0); uint length = GetDataUInt32(4); SendResponse(id, DebugCode.WriteMemory); uint at = 0; while (at + 4 < length) { uint value = GetDataUInt32(8 + at); Intrinsic.Store32(address, at, value); at += 4; } while (at < length) { byte value = GetDataByte(8 + at); Intrinsic.Store8(address, at, value); at++; } Screen.Goto(15, 0); Screen.ClearRow(); Screen.Write("[WriteMemory]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write(id, 10, 5); Screen.Write(" Address: "); Screen.Write((uint)address.ToInt32(), 16, 8); Screen.Write(" Len: "); Screen.Write(length, 10, 5); }
private static void PrepareScreen(string title) { IDT.SetInterruptHandler(null); Screen.BackgroundColor = Colors.Black; Screen.Clear(); Screen.Goto(1, 1); Screen.Color = Colors.LightGray; Screen.Write("*** "); Screen.Write(title); if (firstError) { firstError = false; } else { Screen.Write(" (multiple)"); } Screen.Write(" ***"); Screen.Goto(3, 1); }
private static void CompressedWriteMemory() { uint id = GetID(); uint address = GetUInt32(16); uint length = GetUInt32(20); uint size = GetUInt32(24); uint uncompresscrc = GetUInt32(28); LZF.Decompress(Address.DebuggerBuffer + 32, length, address, size); uint computedcrc = ComputeMemoryCRC(address, size); Screen.Goto(15, 0); Screen.ClearRow(); Screen.Write("[CompressedWriteMemory]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write((uint)id, 10, 5); Screen.Write(" Address: "); Screen.Write(address, 16, 8); Screen.Write(" Len: "); Screen.Write(length, 10, 5); Screen.Write(" Size: "); Screen.Write(size, 10, 5); Screen.Write(" CRC: "); Screen.Write(uncompresscrc, 16, 8); if (uncompresscrc == computedcrc) { Screen.Write(" OK"); } else { Screen.Write(" BAD"); } SendResponse(id, DebugCode.CompressedWriteMemory); }
public static void Setup() { SmbiosManager.Setup(); Screen.Clear(); Screen.Color = 0x0E; Screen.Goto(24, 0); Screen.Write('1'); Multiboot.Setup(); Screen.Goto(24, 1); Screen.Write('2'); PIC.Setup(); Screen.Goto(24, 2); Screen.Write('3'); GDT.Setup(); Screen.Goto(24, 3); Screen.Write('4'); IDT.Setup(); Screen.Goto(24, 4); Screen.Write('5'); PageFrameAllocator.Setup(); Screen.Goto(24, 5); Screen.Write('6'); PageTable.Setup(); Screen.Goto(24, 6); Screen.Write('7'); VirtualPageAllocator.Setup(); Screen.Goto(24, 7); Screen.Write('8'); Screen.Goto(24, 8); ProcessManager.Setup(); Screen.Write('9'); Screen.Goto(24, 9); TaskManager.Setup(); Screen.Write('A'); Screen.Goto(24, 10); SmbiosManager.Setup(); }
public static void DumpMemory(uint address) { PrepareScreen("Memory Dump"); Screen.Column = 0; Screen.Write("ADDRESS "); Screen.Color = Colors.Brown; Screen.Write("03 02 01 00 07 06 05 04 11 10 09 08 15 14 13 12 ASCII"); var word = address; var rowAddress = address; uint rows = 21; for (uint y = 0; y < rows; y++) { Screen.Row++; Screen.Column = 0; WriteHex(word, 8, Colors.Brown); Screen.Write(" "); const uint dwordsPerRow = 4; for (uint x = 0; x < dwordsPerRow; x++) { for (uint x2 = 0; x2 < 4; x2++) { var number = Native.Get8(word + ((4 - 1) - x2)); WriteHex(number, 2, Colors.LightGray); Screen.Write(' '); } if (x == 1 || x == 3) { Screen.Write(' '); } Screen.Write(' '); word += 4; } for (uint x = 0; x < dwordsPerRow * 4; x++) { var num = Native.Get8(rowAddress + x); if (num == 0) { Screen.Color = Colors.DarkGray; } else { Screen.Color = Colors.LightGray; } if (num >= 32 && num < 128) { Screen.Color = Colors.LightGray; Screen.Write((char)num); } else { if (num == 0) { Screen.Color = Colors.DarkGray; } else { Screen.Color = Colors.LightGray; } Screen.Write('.'); } } Screen.Color = Colors.LightGray; //avoid empty line, when line before was fully filled if (Screen.Column == 0) { Screen.Row--; } rowAddress += (dwordsPerRow * 4); } Halt(); }
private static void ProcessCommand() { // [0]MAGIC[4]ID[8]CODE[12]LEN[16]DATA[LEN]CHECKSUM int code = GetCode(); uint id = GetID(); uint len = GetLength(); uint receivedCRC = GetCRC(); uint computedCRC = ComputeCRC(); Screen.Goto(13, 0); Screen.ClearRow(); Screen.Write("[Data]"); Screen.NextLine(); Screen.ClearRow(); Screen.Write("ID: "); Screen.Write((uint)id, 10, 5); Screen.Write(" Code: "); Screen.Write((uint)code, 10, 4); Screen.Write(" Len: "); Screen.Write(len, 10, 5); Screen.Write(" CRC: "); Screen.Write(receivedCRC, 16, 8); if (receivedCRC == computedCRC) { Screen.Write(" OK"); } else { Screen.Write(" BAD"); } // TODO: if crc is invalid switch (code) { case DebugCode.Ping: SendResponse(GetID(), DebugCode.Ping); return; case DebugCode.ReadMemory: ReadMemory(); return; case DebugCode.ReadCR3: SendResponse(GetID(), DebugCode.ReadCR3, (int)Native.GetCR3()); return; case DebugCode.Scattered32BitReadMemory: Scattered32BitReadMemory(); return; case DebugCode.WriteMemory: WriteMemory(); return; case DebugCode.CompressedWriteMemory: CompressedWriteMemory(); return; case DebugCode.ClearMemory: ClearMemory(); return; case DebugCode.HardJump: HardJump(); return; case DebugCode.ExecuteUnitTest: QueueUnitTest(); return; case DebugCode.GetMemoryCRC: GetMemoryCRC(); return; default: return; } }
private static bool ProcessSerial() { if (!Serial.IsDataReady(com)) { return(false); } byte b = Serial.Read(com); bool bad = false; if (index == 0 && b != (byte)'M') { bad = true; } else if (index == 1 && b != (byte)'O') { bad = true; } else if (index == 2 && b != (byte)'S') { bad = true; } else if (index == 3 && b != (byte)'A') { bad = true; } if (bad) { BadDataAbort(); return(true); } Native.Set8(Address.DebuggerBuffer + index, b); index++; uint length = 0; if (index >= 16) { length = GetLength(); if (length > MaxBuffer || index > MaxBuffer) { BadDataAbort(); return(true); } if (length + 20 == index) { ProcessCommand(); ResetBuffer(); } } Screen.Goto(24, 0); Screen.Write("INDEX: "); Screen.Write(index, 10, 5); Screen.Write(" LENGTH: "); Screen.Write((uint)length, 10, 5); unsafe { Screen.Write(" EIP: "); Screen.Write((uint)idt_stack->EIP, 16, 8); } return(true); }
public static void Message(char message) { BeginMessage(); Screen.Write(message); Halt(); }
public static void Error(string message) { BeginError(); Screen.Write(message); EndError(); }
public static void Error(StringBuffer message) { BeginError(); Screen.Write(message); EndError(); }
public static void EnterTestReadyLoop() { uint testCount = 0; Debugger.Ready(); Screen.Write("Waiting for unit tests..."); Screen.NextLine(); Screen.NextLine(); // allocate space on stack for parameters uint esp = Native.AllocateStackSpace(MaxParameters * 4); Screen.Write("Stack @ "); Screen.Write((uint)esp, 16, 8); Screen.NextLine(); Screen.NextLine(); uint row = Screen.Row; while (true) { if (testReady == 1) { Screen.Goto(row, 0); Screen.ClearRow(); Screen.Write("Test #: "); Screen.Write(++testCount, 10, 7); testResult = 0; testResultReady = 0; testResultReported = 0; testReady = 0; // copy parameters into stack for (uint index = 0; index < testParameters; index++) { uint value = new Pointer(Address.UnitTestStack).Load32(index * 4); new Pointer(esp).Store32(index * 4, value); } switch (testResultType) { case 0: Native.FrameCall(testMethodAddress); break; case 1: testResult = Native.FrameCallRetU4(testMethodAddress); break; case 2: testResult = Native.FrameCallRetU8(testMethodAddress); break; case 3: testResult = Native.FrameCallRetR8(testMethodAddress); break; default: break; } testResultReady = 1; Native.Int(255); } } }
/// <summary> /// Interrupts the handler. /// </summary> /// <param name="stack">The stack.</param> private unsafe static void ProcessInterrupt(IDTStack *stack) { Debugger.Process(stack); switch (stack->Interrupt) { case 0: Error(stack, "Divide Error"); break; case 4: Error(stack, "Arithmetic Overflow Exception"); break; case 5: Error(stack, "Bound Check Error"); break; case 6: Error(stack, "Invalid Opcode"); break; case 7: Error(stack, "Co-processor Not Available"); break; case 8: //TODO: Analyze the double fault Error(stack, "Double Fault"); break; case 9: Error(stack, "Co-processor Segment Overrun"); break; case 10: Error(stack, "Invalid TSS"); break; case 11: Error(stack, "Segment Not Present"); break; case 12: Error(stack, "Stack Exception"); break; case 13: Error(stack, "General Protection Exception"); break; case 14: // Check if Null Pointer Exception // Otherwise handle as Page Fault var cr2 = Native.GetCR2(); if ((cr2 >> 5) < 0x1000) { Error(stack, "Null Pointer Exception"); } uint r = Screen.Row; uint c = Screen.Column; Screen.Goto(10, 0); Screen.Write(stack->EIP, 16, 8); Screen.Write(' '); Screen.Write(cr2, 16, 8); if (cr2 >= 0xF0000000u) { Error(stack, "Invalid Access Above 0xF0000000"); break; } uint physicalpage = PageFrameAllocator.Allocate(); Screen.Write(' '); Screen.Write(physicalpage, 16, 8); if (physicalpage == 0x0) { Error(stack, "Out of Memory"); break; } PageTable.MapVirtualAddressToPhysical(cr2, physicalpage); uint pp = PageTable.GetPhysicalAddressFromVirtual(cr2); Screen.Write(' '); Screen.Write(pp, 16, 8); Screen.Goto(r, c); break; case 16: Error(stack, "Co-processor Error"); break; case 19: Error(stack, "SIMD Floating-Point Exception"); break; default: interruptHandler?.Invoke(stack->Interrupt, stack->ErrorCode); break; } PIC.SendEndOfInterrupt(stack->Interrupt); }