internal static uint WriteDebugChar(ref SysCallContext context, ref SystemMessage args) { var c = (char)args.Arg1; KernelMessage.Write(c); return(0); }
internal static uint ThreadSleep(ref SysCallContext context, ref SystemMessage args) { var time = args.Arg1; Scheduler.Sleep(time); return(0); }
internal static unsafe uint WriteDebugMessage(ref SysCallContext context, ref SystemMessage args) { var msg = (NullTerminatedString *)args.Arg1; KernelMessage.WriteLine(msg); return(0); }
internal static uint StartProcess(ref SysCallContext context, ref SystemMessage args) { var procId = (int)args.Arg1; ProcessManager.StartProcessByID(procId); return(0); }
internal static uint SetThreadStorageSegmentBase(ref SysCallContext context, ref SystemMessage args) { var addr = args.Arg1; Scheduler.GetCurrentThread().ThreadLocalStorageBaseAddr = addr; GDT.SetThreadStorageSegmentBase(addr); return(0); }
internal static uint RegisterService(ref SysCallContext context, ref SystemMessage args) { var proc = Scheduler.GetCurrentThread().Process; if (proc.Service != null) { SysCallManager.SetCommand((SysCallTarget)args.Arg1, RegisteredService, proc); } return(0); }
internal static uint RegisterInterrupt(ref SysCallContext context, ref SystemMessage args) { var proc = Scheduler.GetCurrentThread().Process; if (proc.Service != null) { IDTManager.SetInterruptHandler(args.Arg1, InterruptHandlers.Service, proc.Service); } return(0); }
internal static unsafe uint GetFramebufferInfo(ref SysCallContext context, ref SystemMessage args) { var virtAddr = args.Arg1; var virtPresent = (int *)virtAddr; * virtPresent = Boot.BootInfo.Header->FBPresent ? 1 : 0; var virtInfo = (BootInfoFramebufferInfo *)(virtAddr + 4); *virtInfo = Boot.BootInfo.Header->FbInfo; return(0); }
internal static uint SetServiceStatus(ref SysCallContext context, ref SystemMessage args) { var proc = Scheduler.GetCurrentThread().Process; if (proc.Service != null) { proc.Service.Status = (ServiceStatus)args.Arg1; } return(0); }
internal static uint GetRemoteThreadID(ref SysCallContext context, ref SystemMessage args) { var pThread = Scheduler.GetCurrentThread().ParentThread; if (pThread == null) { return(unchecked ((uint)-1)); } return((uint)pThread.ThreadID); }
internal static uint CreateMemoryProcess(ref SysCallContext context, ref SystemMessage args) { var addr = args.Arg1; var size = args.Arg2; #pragma warning disable CA2000 // Dispose objects before losing scope var proc = ProcessManager.CreateProcessFromBuffer(new MemoryRegion(addr, size)); #pragma warning restore CA2000 // Dispose objects before losing scope //ProcessManager.StartProcess("App.Shell"); return((uint)proc.ProcessID); }
internal static uint GetPhysicalMemory(ref SysCallContext context, ref 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); }
internal static uint RequestMemory(ref SysCallContext context, ref SystemMessage args) { var size = args.Arg1; size = KMath.AlignValueCeil(size, 4096); var proc = Scheduler.GetCurrentThread().Process; var map = PhysicalPageManager.AllocateRegion(size); var virtAddr = proc.UserPageAllocator.AllocatePagesAddr(size / 4096); Scheduler.GetCurrentThread().Process.PageTable.Map(virtAddr, map.Start, PhysicalPageManager.GetAllocatorByAddr(map.Start)); return(virtAddr); }
/// <summary> /// Command is handled by another Service (up call) /// </summary> internal static uint RegisteredService(ref SysCallContext context, ref SystemMessage args) { var handler = SysCallManager.GetHandler(args.Target); var targetProcess = handler.Process; if (targetProcess.Service != null) { targetProcess.Service.SwitchToThreadMethod(ref context, ref args); } // Will reach only, if callingMethod==Action return(0); }
internal static unsafe uint GetProcessByName(ref SysCallContext context, ref SystemMessage args) { var name = (NullTerminatedString *)args.Arg1; var proc = ProcessManager.GetProcessByName(name); if (proc != null) { return((uint)proc.ProcessID); } return(unchecked ((uint)-1)); }
internal static uint KillProcess(ref SysCallContext context, ref SystemMessage args) { var procId = (int)args.Arg1; var currentProcId = Scheduler.GetCurrentThread().Process.ProcessID; ProcessManager.KillProcessByID(procId); if (procId == currentProcId) { Scheduler.ScheduleNextThread(); } return(0); }
internal static uint RequestMessageBuffer(ref SysCallContext context, ref SystemMessage args) { var size = args.Arg1; var targetProcessID = (int)args.Arg2; var pages = KMath.DivCeil(size, 4096); var currentProc = Scheduler.GetCurrentThread().Process; var tableCurrent = currentProc.PageTable; var targetProc = ProcessManager.System; if (targetProcessID > 0) { targetProc = ProcessManager.GetProcessByID(targetProcessID); } var tableTarget = targetProc.PageTable; var virtHead = VirtualPageManager.AllocatePages( pages, new AllocatePageOptions { Pool = PageAllocationPool.Global, }); var virtAddr = virtHead; for (var pageIdx = 0; pageIdx < pages; pageIdx++) { var physAddr = PageTable.KernelTable.GetPhysicalAddressFromVirtual(virtAddr); if (tableCurrent != PageTable.KernelTable) { tableCurrent.Map(virtAddr, physAddr, flush: true); } if (tableTarget != PageTable.KernelTable) { tableTarget.Map(virtAddr, physAddr, flush: true); } virtAddr += 4096; } // TODO: implement TargetProcess.RegisterMessageBuffer, because of individual VirtAddr currentProc.GlobalAllocations.Add(new GlobalAllocation { Addr = virtHead, TargetProcID = targetProcessID }); return(virtHead); }
/// <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; }
internal static uint Sbrk(ref SysCallContext context, ref SystemMessage args) { var size = args.Arg1; //size = KMath.AlignValueCeil(size, 4096); var proc = Scheduler.GetCurrentThread().Process; if (proc.CurrentBrk == 0) { proc.CurrentBrk = proc.BrkBase; //size -= proc.BrkBase; //size -= 0x70000000; } KernelMessage.WriteLine("sbrk({0:X8}). Current={1:X8} New={2:X8}", size, proc.CurrentBrk, proc.CurrentBrk + size); var procTable = Scheduler.GetCurrentThread().Process.PageTable; var region = MemoryRegion.FromLocation(proc.CurrentBrk, proc.CurrentBrk + size); region = region.FitToPageFloor(); var pages = region.Size / 4096; var virtAddr = region.Start; for (var i = 0; i < pages; i++) { if (!procTable.IsMapped(virtAddr)) { KernelMessage.WriteLine("sbrk: Map {0:X8}", virtAddr); var p = PhysicalPageManager.AllocatePageAddr(); procTable.Map(virtAddr, p); } else { KernelMessage.WriteLine("sbrk: Map {0:X8}: Already mapped", virtAddr); } virtAddr += 4096; } proc.CurrentBrk += size; KernelMessage.WriteLine("new brk: {0:X8}", proc.CurrentBrk); return(proc.CurrentBrk - size); }
internal static uint GetProcessIDForCommand(ref SysCallContext context, ref SystemMessage args) { var handler = SysCallManager.GetHandler((SysCallTarget)args.Arg1); if (handler == null) { KernelMessage.WriteLine("GetProcessIDForCommand {0}: UNKNOWN", args.Arg1); return(unchecked ((uint)-1)); } var proc = handler.Process; if (proc == null) { proc = ProcessManager.System; } KernelMessage.WriteLine("Return ProcessID {0} for Command {1}", proc.ProcessID, (uint)handler.CommandID); return((uint)proc.ProcessID); }
internal static unsafe uint ServiceReturn(ref SysCallContext context, ref SystemMessage args) { var servThread = Scheduler.GetCurrentThread(); servThread.Status = ThreadStatus.Terminated; if (servThread.ParentThread != null) { var parent = servThread.ParentThread; servThread.ParentThread = null; parent.ChildThread = null; if (parent.StackState != null) { parent.StackState->Stack.EAX = args.Arg1; } Scheduler.SwitchToThread(parent.ThreadID); } Scheduler.ScheduleNextThread(); return(0); }
private static void InterruptHandler(IDTStack *stack, CallingType 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} arg2={2} arg3={3} arg4={4} arg5={5} arg6={6}", (uint)args.Target, args.Arg1, args.Arg2, args.Arg3, args.Arg4, args.Arg5, args.Arg6); } Scheduler.SaveThreadState(Scheduler.GetCurrentThread().ThreadID, (IntPtr)stack); var info = Commands[commandNum]; if (info == null) { Panic.Error("Undefined SysCall"); } var ctx = new SysCallContext { CallingType = callingMethod, }; stack->EAX = info.Handler(&ctx, &args); }
internal static uint GetElfSectionsAddress(ref SysCallContext context, ref SystemMessage args) { var proc = Scheduler.GetCurrentThread().Process; return(proc.UserElfSectionsAddr); }
internal static uint GetCurrentThreadID(ref SysCallContext context, ref SystemMessage args) { return((uint)Scheduler.GetCurrentThread().ThreadID); }
internal static uint SetThreadPriority(ref SysCallContext context, ref SystemMessage args) { Scheduler.SetThreadPriority((int)args.Arg1); return(0); }
internal static uint TranslateVirtualToPhysicalAddress(ref SysCallContext context, ref SystemMessage args) { var virtAddr = args.Arg1; return(Scheduler.GetCurrentThread().Process.PageTable.GetPhysicalAddressFromVirtual(virtAddr)); }