public static void DumpStats() { KernelMessage.WriteLine("Threads, Can scheduled:"); Dump(true); KernelMessage.WriteLine("Non-Schedulable Threads:"); Dump(false); }
public unsafe Page *AllocatePages(uint pages, AllocatePageOptions options = default) { if (pages > _FreePages) { Panic.Error("Out of Memory"); return(null); } Page *page; if (AddressSpaceKind == AddressSpaceKind.Virtual || options.Continuous) { page = AllocatePagesContinuous(pages, options); } else { page = AllocatePagesNormal(pages, options); } if (page == null) { KernelMessage.WriteLine("DebugName: {0}", DebugName); KernelMessage.WriteLine("Free pages: {0:X8}, Requested: {1:X8}", FreePages, pages); Panic.Error("Out of Memory"); } KernelMessage.Path(DebugName, "SimpleAlloc: Request {0} Pages, Addr {1:X8}", pages, GetAddress(page)); return(page); }
private static void MapKernelImage() { var phys = Address.KernelElfSectionPhys; var diff = Address.KernelBaseVirt - Address.KernelBasePhys; var endPhys = phys + OriginalKernelElf.TotalFileSize; var addr = phys; KernelMessage.WriteLine("Mapping Kernel Image from physical {0:X8} to virtual {1:X8}", phys, phys + diff); while (addr < endPhys) { PageTable.KernelTable.MapVirtualAddressToPhysical(addr + diff, addr); addr += 0x1000; } PageTable.KernelTable.Flush(); var map = new BootInfoMemory { Start = phys + diff, Size = OriginalKernelElf.TotalFileSize, Type = BootInfoMemoryType.KernelElfVirt, AddressSpaceKind = AddressSpaceKind.Virtual, }; BootInfo_.AddMap(map); }
public static unsafe void SaveThreadState(uint threadID, IntPtr stackState) { //Assert.True(threadID < MaxThreads, "SaveThreadState(): invalid thread id > max"); var thread = Threads[threadID]; if (thread.Status != ThreadStatus.Running) { return; // New threads doesn't have a stack in use. Take the initial one. } //Assert.True(thread != null, "SaveThreadState(): thread id = null"); if (thread.User) { Assert.IsSet(thread.StackState, "thread.StackState is null"); *thread.StackState = *(IDTTaskStack *)stackState; } else { thread.StackState = (IDTTaskStack *)stackState; } if (KConfig.Log.TaskSwitch) { KernelMessage.Write("Task {0}: Stored ThreadState from {1:X8} stored at {2:X8}, EIP={3:X8}", threadID, (uint)stackState, (uint)thread.StackState, thread.StackState->Stack.EIP); if (thread.User) { KernelMessage.WriteLine(" ESP={0:X8}", thread.StackState->TASK_ESP); } else { KernelMessage.WriteLine(); } } }
/// <summary> /// Enable the IDTManager /// </summary> public static void Start() { KernelMessage.Write("Enabling interrupts..."); Enabled = true; Flush(); KernelMessage.WriteLine("done"); }
private void PrintAddress() { KernelMessage.WriteLine("PageDirectoryPTPhys: {0:X8}", this.GetPageTablePhysAddr()); KernelMessage.WriteLine("PageDirectoryPT: {0:X8}", AddrPageDirectoryPT); KernelMessage.WriteLine("PageDirectory: {0:X8}", AddrPageDirectory); KernelMessage.WriteLine("PageTable: {0:X8}", (uint)PageTableEntries); }
public virtual void Setup(MemoryRegion region, AddressSpaceKind addressSpaceKind) { AddressSpaceKind = addressSpaceKind; region.Size = KMath.FloorToPowerOfTwo(region.Size); _Region = region; var totalPages = region.Size >> BuddyAllocatorImplementation.BUDDY_PAGE_SHIFT; KernelMessage.WriteLine("Init Allocator: StartAddr: {0}, {1} Pages", region.Start, totalPages); // init global memory block // all pages area var pages_size = totalPages * (uint)sizeof(Page); KernelMessage.WriteLine("Page Array Size in bytes: {0}", pages_size); Pages = (Page *)AllocRawMemory(pages_size).Start; KernelMessage.WriteLine("Page Array Addr: {0:X8}", (uint)Pages); var start_addr = region.Start; Zone.free_area = (BuddyAllocatorImplementation.free_area *)AllocRawMemory(BuddyAllocatorImplementation.BUDDY_MAX_ORDER * (uint)sizeof(BuddyAllocatorImplementation.free_area)).Start; fixed(BuddyAllocatorImplementation.mem_zone *zone = &Zone) ZonePtr = zone; BuddyAllocatorImplementation.buddy_system_init( ZonePtr, Pages, start_addr, totalPages); }
private static void AssertError(string message, uint arg1 = 0, uint arg2 = 0, uint arg3 = 0) { KernelMessage.WriteLine("ASSERT ERROR! "); var sb = new StringBuffer(); sb.Append(message, arg1, arg2, arg3); KernelMessage.WriteLine(sb); }
/// <summary> /// Dump the statistics of interest /// </summary> public static unsafe void DumpStats() { for (var i = 0; i < ProcessList.Count; i++) { var proc = ProcessList[i]; KernelMessage.WriteLine("PID {1} Name {0} State {2}", proc.Path, (uint)proc.ProcessID, (uint)proc.RunState); } }
internal static unsafe uint WriteDebugMessage(ref SysCallContext context, ref SystemMessage args) { var msg = (NullTerminatedString *)args.Arg1; KernelMessage.WriteLine(msg); return(0); }
private static uint Cmd_WriteDebugMessage(SysCallContext *context, SystemMessage *args) { var msg = (NullTerminatedString *)args->Arg1; KernelMessage.WriteLine(msg); return(0); }
public void EnablePaging() { KernelMessage.Write("Enable Paging... "); // Set CR0 register on processor - turns on virtual memory Native.SetCR0(Native.GetCR0() | 0x80000000); KernelMessage.WriteLine("Done"); }
private static void PrintMapArray(string name, KernelMemoryMapArray *mapArray) { KernelMessage.WriteLine("Items of MemoryMap Array [{0}]", name); for (var i = 0; i < mapArray->Count; i++) { var mm = &mapArray->Items[i]; KernelMessage.WriteLine("Map {0:X8}-{1:X8}, Size={2:X8}, Type={3}, AddrKind={4}", mm->Start, mm->Start + mm->Size - 1, mm->Size, (uint)mm->Type, (uint)mm->AddressSpaceKind); } }
public static void Setup() { KernelMessage.WriteLine("Setup ELF Headers"); //KernelMessage.WriteLine("Image Header:"); //KernelMemory.DumpToConsoleLine(Address.KernelElfSection, 124); Main = FromAddress(Address.KernelElfSectionVirt); Native = FromSectionName("native"); }
/// <summary> /// Releases a page to the free list /// </summary> public void Free(Page *page) { var oldFree = _FreePages; string debugName = null; if (page->DebugTag != null) { debugName = (string)Intrinsic.GetObjectFromAddress((Pointer)(uint)page->DebugTag); } UninterruptableMonitor.Enter(this); try { var debugCount = list_head.list_count((list_head *)page); // DEBUG SelfCheck("SCF1", debugCount); Page *temp = page; uint result = 0; do { result++; if (temp->Status == PageStatus.Free) { //Panic.Error("Double Free"); SelfCheck("SCF3", debugCount); KernelMessage.WriteLine("Double Free. Pages {0} Iteration {1}", debugCount, result); Debug.Break(); } temp->Status = PageStatus.Free; var oldTemp = temp; temp = (Page *)temp->Lru.next; Native.Nop(); _FreePages++; list_head.list_move_tail((list_head *)oldTemp, FreeList); }while (temp != page && result != debugCount); //list_head.list_headless_splice_tail((list_head*)page, FreeList); SelfCheck("SCF2", debugCount); } finally { UninterruptableMonitor.Exit(this); } var freedPages = _FreePages - oldFree; if (KConfig.Log.PageAllocation && TraceOptions.Enabled && freedPages >= TraceOptions.MinPages) { KernelMessage.Path(DebugName, "Freed Pages: {1}. Addr: {2:X8}. Now available: {3} --> {4}. Allocations={5} DebugName={0}.", debugName, freedPages, GetAddress(page), oldFree, _FreePages, (uint)Requests); } _Releases++; }
internal static void Undefined(ref IDTStack stack) { var handler = IDTManager.Handlers[stack.Interrupt]; if (handler.NotifyUnhandled) { handler.NotifyUnhandled = false; KernelMessage.WriteLine("Unhandled Interrupt {0}", stack.Interrupt); } }
public void Setup(MemoryRegion region, AddressSpaceKind addrKind) { TraceOptions = new PageFrameAllocatorTraceOptions(); _AddressSpaceKind = addrKind; _Region = region; FistPageNum = region.Start / PageSize; _TotalPages = region.Size / PageSize; kmap = AllocRawMemory(_TotalPages * (uint)sizeof(Page)); PageArray = (Page *)kmap.Start; var firstSelfPageNum = KMath.DivFloor(kmap.Start, 4096); var selfPages = KMath.DivFloor(kmap.Size, 4096); KernelMessage.WriteLine("Page Frame Array allocated {0} pages, beginning with page {1} at {2:X8}", selfPages, firstSelfPageNum, (uint)PageArray); PageTable.KernelTable.SetWritable(kmap.Start, kmap.Size); kmap.Clear(); var addr = FistPageNum * 4096; for (uint i = 0; i < _TotalPages; i++) { //KernelMessage.WriteLine(i); PageArray[i].Address = addr; //if (i != 0) // PageArray[i - 1].Next = &PageArray[i]; addr += 4096; } KernelMessage.WriteLine("Setup free memory"); SetupFreeMemory(); KernelMessage.WriteLine("Build linked lists"); BuildLinkedLists(); KernelMessage.WriteLine("Build linked lists done"); _FreePages = 0; for (uint i = 0; i < _TotalPages; i++) { if (PageArray[i].Status == PageStatus.Free) { _FreePages++; } } //Assert.True(list_head.list_count(FreeList) == _FreePages, "list_head.list_count(FreeList) == _FreePages"); var debugCheckCount = list_head.list_count(FreeList); if (debugCheckCount != _FreePages) { KernelMessage.WriteLine("debugCheckCount {0} != {1}", debugCheckCount, _FreePages); Debug.Break(); } KernelMessage.Path(DebugName, "Pages Free: {0}", FreePages); }
public static void TerminateCurrentThread() { KernelMessage.WriteLine("Terminating Thread"); var threadID = GetCurrentThreadID(); if (threadID != 0) { TerminateThread(threadID); } }
/// <summary> /// Switch to a specific thread. /// This method will not return! /// </summary> public static unsafe void SwitchToThread(int threadID) { var thread = Threads[threadID]; var proc = thread.Process; if (KConfig.Log.TaskSwitch) { KernelMessage.WriteLine("Switching to Thread {0}. StackState: {1:X8}", threadID, (uint)thread.StackState); } //Assert.True(thread != null, "invalid thread id"); thread.Ticks++; SetThreadID(threadID); PIC.SendEndOfInterrupt((int)KnownInterrupt.ClockTimer); thread.Status = ThreadStatus.Running; if (thread.StackState == null) { DumpStats(); KernelMessage.WriteLine("threadID: {0}", threadID); Debug.Break(); } thread.StackState->Stack.EFLAGS |= X86_EFlags.InterruptEnableFlag; if (proc.PageTable != PageTable.KernelTable) { Debug.Nop(); } uint pageDirAddr = proc.PageTable.GetPageTablePhysAddr(); //KernelMessage.WriteLine("PageDirAddr: {0:X8}", pageDirAddr); uint stackStateAddr = (uint)thread.StackState; uint dataSelector = thread.DataSelector; if (!thread.User) { thread.StackState = null; // just to be sure } GDT.Tss->ESP0 = thread.KernelStackBottom; if (thread.Debug) { Native.Nop(); } GDT.SetThreadStorageSegmentBase(thread.ThreadLocalStorageBaseAddr); InterruptReturn(stackStateAddr, pageDirAddr, dataSelector, KnownSegments.UserThreadStorage); }
public static void StartProcessByID(int processID) { KernelMessage.WriteLine("Starting process ID {0}", processID); var proc = GetProcessByID(processID); if (proc == null) { return; } proc.Start(); }
/// <summary> /// Prints the error and halts the system /// </summary> public static void Error(string message) { Native.Cli(); KernelMessage.WriteLine("Kernel Panic: {0}", message); //Screen.Goto(0, 0); //Screen.Color = 11; //Screen.Write(message); //while(true){ Native.Nop(); }; //return; Screen.BackgroundColor = ScreenColor.Green; Screen.Clear(); Screen.Goto(1, 0); Screen.Color = ScreenColor.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 uint Cmd_GetProcessIDForCommand(SysCallContext *context, SystemMessage *args) { var cmdNum = GetCommandNum((SysCallTarget)args->Arg1); var proc = Commands[cmdNum].Process; if (proc == null) { proc = ProcessManager.System; } KernelMessage.WriteLine("Return ProcessID {0} for Command {1}", proc.ProcessID, cmdNum); return((uint)proc.ProcessID); }
private static uint Cmd_GetPhysicalMemory(SysCallContext *context, SystemMessage *args) { var physAddr = args->Arg1; var pages = KMath.DivCeil(args->Arg2, 4096); KernelMessage.WriteLine("Got Request for {0:X8} pages at Physical Addr {1:X8}", pages, physAddr); var proc = Scheduler.GetCurrentThread().Process; var virtAddr = proc.UserPageAllocator.AllocatePagesAddr(pages); proc.PageTable.Map(virtAddr, physAddr, pages * 4096); return(virtAddr); }
public static unsafe Process CreateProcessFromBuffer(MemoryRegion region, uint argumentBufferSize = 0) { KernelMessage.WriteLine("StartProcessFromBuffer at {0:X8} size {1:X8}", region.Start, region.Size); var cs = region.Checksum(); KernelMessage.WriteLine("CheckSum: {0:X8}", cs); // TODO: Copy Buffer!! var elf = KernelElf.FromAddress(region.Start); return(CreateProcessFromElf(elf, "memory", argumentBufferSize)); }
public static void Setup() { KernelMessage.WriteLine("Setup Native Calls"); // TODO: VirtAddr! // TODO: SetExecutable! //PageTable.SetExecutableForRegion(...); prog1Addr = KernelElf.Native.GetPhysAddrOfSymbol("test_proc1"); prog2Addr = KernelElf.Native.GetPhysAddrOfSymbol("test_proc2"); bochsDebugAddr = KernelElf.Native.GetPhysAddrOfSymbol("bochs_debug"); }
/// <summary> /// Sets up the PageTable /// </summary> public override void Setup(Addr entriesAddr) { SetupBasicStructure(entriesAddr); // Set CR3 register on processor - sets page directory KernelMessage.WriteLine("Set CR3 to {0:X8}", (uint)PageDirectoryEntries); Flush(); if (KConfig.UseKernelMemoryProtection) { EnableKernelWriteProtection(); } }
public static void DumpStats(this IPageFrameAllocator allocator) { KernelMessage.WriteLine("Stats for {0}", allocator.DebugName); KernelMessage.WriteLine("TotalPages {0}, FreePages {1}, Requests {2}, Releases {3}, Allocations {4}", allocator.TotalPages, allocator.FreePages, (uint)allocator.Requests, (uint)allocator.Releases, (uint)(allocator.Requests - allocator.Releases)); if (allocator is MultiAllocator) { var multi = (MultiAllocator)allocator; for (var i = 0; i < multi.Allocators.Length; i++) { multi.Allocators[i].DumpStats(); } } }
public static void Setup() { KernelMessage.WriteLine("Initialize SysCall Manager"); IDTManager.SetInterruptHandler(FunctionIRQ, FunctionInterruptHandler); IDTManager.SetPrivilegeLevel(FunctionIRQ, 0x03); IDTManager.SetInterruptHandler(ActionIRQ, ActionInterruptHandler); IDTManager.SetPrivilegeLevel(ActionIRQ, 0x03); IDTManager.Flush(); Commands = new SysCallHandlerInfo[256]; SetCommands(); }
public static unsafe void Start() { SetThreadID(0); Enabled = true; KernelMessage.WriteLine("Enable Scheduler"); IDTManager.SetPrivilegeLevel((uint)KnownInterrupt.TerminateCurrentThread, 0x03); GDT.Tss->ESP0 = Threads[0].KernelStackBottom; GDT.LoadTaskRegister(); TriggerScheduler(); // Normally, you should never get here Panic.Error("Main-Thread still alive"); }
/// <summary> /// Syscall interrupt handler. Dispatcher for every SysCall. /// </summary> private static void InterruptHandler(ref IDTStack stack, SysCallCallingType callingMethod) { var args = new SystemMessage { Target = (SysCallTarget)stack.EAX, Arg1 = stack.EBX, Arg2 = stack.ECX, Arg3 = stack.EDX, Arg4 = stack.ESI, Arg5 = stack.EDI, Arg6 = stack.EBP, }; var commandNum = GetCommandNum(args.Target); if (KConfig.Log.SysCall) { KernelMessage.WriteLine("Got SysCall cmd={0} arg1={1:X8} arg2={2:X8} arg3={3:X8} arg4={4:X8} arg5={5:X8} arg6={6:X8}", (uint)args.Target, args.Arg1, args.Arg2, args.Arg3, args.Arg4, args.Arg5, args.Arg6); } Scheduler.SaveThreadState(Scheduler.GetCurrentThread().ThreadID, ref stack); var info = Commands[commandNum]; if (info == null) { Panic.Error("Undefined SysCall"); } var ctx = new SysCallContext { CallingType = callingMethod, Debug = info.Debug, }; if (info.Debug) { KDebug.DumpStats(); Debug.Nop(); } var result = info.Handler(ref ctx, ref args); if (KConfig.Log.SysCall) { KernelMessage.WriteLine("Result of Syscall cmd={0}: {1:X8}", (uint)args.Target, result); } stack.EAX = result; }