protected static MemoryRegion AllocRawMemoryVirt(uint size) { var kmap = VirtualPageManager.AllocateRegion(size); kmap.Clear(); return(kmap); }
public void Dispose() { //Memory.FreeObject(StdIn); VirtualPageManager.FreeAddr(PageTableAllocAddr); Threads.Dispose(); GlobalAllocations.Dispose(); }
public void FreeMemory() { VirtualPageManager.FreeAddr(StackTop); if (User) { VirtualPageManager.FreeAddr(StackState); } VirtualPageManager.FreeAddr(KernelStack); }
private static uint Cmd_RequestMessageBuffer(SysCallContext *context, 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.GetProcess(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); }
private static unsafe void InitializeUserMode() { if (!KConfig.UseUserMode) { return; } if (KConfig.UseTaskStateSegment) { TssAddr = VirtualPageManager.AllocatePages(1); PageTable.KernelTable.SetWritable(TssAddr, 4096); KernelMemoryMapManager.Header->Used.Add(new KernelMemoryMap(TssAddr, 4096, BootInfoMemoryType.TSS, AddressSpaceKind.Virtual)); } // Disabling Interrupts here is very important, otherwise we will get randomly an Invalid TSS Exception. Uninterruptible.Execute(() => { GDT.SetupUserMode(TssAddr); }); }
/// <summary> /// Used for app, so it can access it's own sections /// </summary> private static unsafe ElfSectionHeader *SetupElfHeader(Process proc, ElfSections elf) { var kernelAddr = VirtualPageManager.AllocatePages(1); var userAddr = proc.UserPageAllocator.AllocatePagesAddr(1); KernelMessage.WriteLine("Store User KernelSectionsInfo at {0:X8}", userAddr); proc.PageTable.MapCopy(PageTable.KernelTable, kernelAddr, userAddr, 4096); var kernelHelper = (ElfSections *)kernelAddr; *kernelHelper = elf; kernelHelper->PhyOffset = 0; var kernelSectionHeaderArray = (ElfSectionHeader *)(kernelAddr + sizeof(ElfSections)); for (var i = 0; i < elf.SectionHeaderCount; i++) { kernelSectionHeaderArray[i] = elf.SectionHeaderArray[i]; } kernelHelper->SectionHeaderArray = (ElfSectionHeader *)(userAddr + sizeof(ElfSections)); proc.UserElfSectionsAddr = userAddr; return(kernelSectionHeaderArray); }
public static unsafe void Main() { try { ManagedMemoy.InitializeGCMemory(); StartUp.InitializeAssembly(); KMath.Init(); //Mosa.Runtime.StartUp.InitializeRuntimeMetadata(); BootInfo.SetupStage1(); Memory.InitialKernelProtect(); ApiContext.Current = new ApiHost(); Assert.Setup(AssertError); // Setup some pseudo devices DeviceManager.InitStage1(); //Setup Output and Debug devices DeviceManager.InitStage2(); // Write first output KernelMessage.WriteLine("<KERNEL:CONSOLE:BEGIN>"); PerformanceCounter.Setup(BootInfo.Header->KernelBootStartCycles); KernelMessage.WriteLine("Starting Abanu Kernel..."); KernelMessage.WriteLine("KConfig.UseKernelMemoryProtection: {0}", KConfig.UseKernelMemoryProtection); KernelMessage.WriteLine("KConfig.UsePAE: {0}", KConfig.UsePAE); KernelMessage.WriteLine("Apply PageTableType: {0}", (uint)BootInfo.Header->PageTableType); KernelMessage.WriteLine("GCInitialMemory: {0:X8}-{1:X8}", Address.GCInitialMemory, Address.GCInitialMemory + Address.GCInitialMemorySize - 1); Ulongtest1(); Ulongtest2(); InlineTest(); // Detect environment (Memory Maps, Video Mode, etc.) BootInfo.SetupStage2(); KernelMemoryMapManager.Setup(); //KernelMemoryMapManager.Allocate(0x1000 * 1000, BootInfoMemoryType.PageDirectory); // Read own ELF-Headers and Sections KernelElf.Setup(); // Initialize the embedded code (actually only a little proof of concept code) NativeCalls.Setup(); //InitialKernelProtect(); PhysicalPageManager.Setup(); KernelMessage.WriteLine("Phys free: {0}", PhysicalPageManager.FreePages); PhysicalPageManager.AllocatePages(10); KernelMessage.WriteLine("Phys free: {0}", PhysicalPageManager.FreePages); VirtualPageManager.Setup(); Memory.Setup(); // Now Memory Sub System is working. At this point it's valid // to allocate memory dynamically DeviceManager.InitFrameBuffer(); // Setup Programmable Interrupt Table PIC.Setup(); // Setup Interrupt Descriptor Table // Important Note: IDT depends on GDT. Never setup IDT before GDT. IDTManager.Setup(); InitializeUserMode(); SysCallManager.Setup(); KernelMessage.WriteLine("Initialize Runtime Metadata"); StartUp.InitializeRuntimeMetadata(); KernelMessage.WriteLine("Performing some Non-Thread Tests"); Tests(); } catch (Exception ex) { Panic.Error(ex.Message); } if (KConfig.SingleThread) { StartupStage2(); } else { ProcessManager.Setup(StartupStage2); } }
public static unsafe void StartupStage2() { try { if (!KConfig.SingleThread) { Scheduler.CreateThread(ProcessManager.System, new ThreadStartOptions(BackgroundWorker.ThreadMain) { DebugName = "BackgroundWorker", Priority = -5 }).Start(); Scheduler.CreateThread(ProcessManager.System, new ThreadStartOptions(Thread0) { DebugName = "KernelThread0", Priority = -5 }).Start(); var userProc = ProcessManager.CreateEmptyProcess(new ProcessCreateOptions { User = false }); userProc.Path = "/buildin/testproc"; Scheduler.CreateThread(userProc, new ThreadStartOptions(Thread1) { AllowUserModeIOPort = true, DebugName = "UserThread1", Priority = -5 }); Scheduler.CreateThread(userProc, new ThreadStartOptions(Thread2) { AllowUserModeIOPort = true, DebugName = "UserThread2", Priority = -5 }); userProc.Start(); var fileProc = ProcessManager.StartProcess("Service.Basic"); FileServ = fileProc.Service; KernelMessage.WriteLine("Waiting for Service"); while (FileServ.Status != ServiceStatus.Ready) { Scheduler.Sleep(0); } KernelMessage.WriteLine("Service Ready"); //var buf = Abanu.Runtime.SysCalls.RequestMessageBuffer(4096, FileServ.Process.ProcessID); //var kb = Abanu.Runtime.SysCalls.OpenFile(buf, "/dev/keyboard"); //KernelMessage.Write("kb Handle: {0:X8}", kb); //buf.Size = 4; //Abanu.Runtime.SysCalls.WriteFile(kb, buf); //Abanu.Runtime.SysCalls.ReadFile(kb, buf); //var procHostCommunication = ProcessManager.StartProcess("Service.HostCommunication"); //ServHostCommunication = new Service(procHostCommunication); //// TODO: Optimize Registration //SysCallManager.SetCommandProcess(SysCallTarget.HostCommunication_CreateProcess, procHostCommunication); var proc = ProcessManager.StartProcess("App.HelloService"); Serv = proc.Service; var p2 = ProcessManager.StartProcess("App.HelloKernel"); //p2.Threads[0].SetArgument(0, 0x90); //p2.Threads[0].SetArgument(4, 0x94); //p2.Threads[0].SetArgument(8, 0x98); p2.Threads[0].Debug = true; var p3 = ProcessManager.StartProcess("App.Shell"); ProcessManager.System.Threads[0].Status = ThreadStatus.Terminated; } VirtualPageManager.SetTraceOptions(new PageFrameAllocatorTraceOptions { Enabled = true, MinPages = 1 }); KernelMessage.WriteLine("Enter Main Loop"); AppMain(); } catch (Exception ex) { Panic.Error(ex.Message); } }
public static unsafe void Setup() { KernelMessage.WriteLine("Setup IDT"); Enabled = false; InitControlBlock(); // Allocate memory for the IDT IDTAddr = VirtualPageManager.AllocatePages(1); KernelMemoryMapManager.Header->Used.Add(new KernelMemoryMap(IDTAddr, 4096, BootInfoMemoryType.IDT, AddressSpaceKind.Virtual)); PageTable.KernelTable.SetWritable(IDTAddr, 4096); KernelMessage.WriteLine("Address of IDT: {0:X8}", IDTAddr); // Setup IDT table Mosa.Runtime.Internal.MemoryClear(new Pointer((uint)IDTAddr), 6); Intrinsic.Store16(new Pointer((uint)IDTAddr), (Offset.TotalSize * 256) - 1); Intrinsic.Store32(new Pointer((uint)IDTAddr), 2, IDTAddr + 6); KernelMessage.Write("Set IDT table entries..."); SetTableEntries(); KernelMessage.WriteLine("done"); Handlers = new InterruptInfo[256]; for (var i = 0; i <= 255; i++) { var info = new InterruptInfo { Interrupt = i, CountStatistcs = true, Trace = true, Handler = InterruptHandlers.Undefined, }; if (i == (int)KnownInterrupt.ClockTimer) { info.Trace = false; info.CountStatistcs = false; } Handlers[i] = info; } // Set basic Interrupt handlers SetInterruptHandler(KnownInterrupt.DivideError, InterruptHandlers.DivideError); SetInterruptHandler(KnownInterrupt.ArithmeticOverflowException, InterruptHandlers.ArithmeticOverflowException); SetInterruptHandler(KnownInterrupt.BoundCheckError, InterruptHandlers.BoundCheckError); SetInterruptHandler(KnownInterrupt.InvalidOpcode, InterruptHandlers.InvalidOpcode); SetInterruptHandler(KnownInterrupt.CoProcessorNotAvailable, InterruptHandlers.CoProcessorNotAvailable); SetInterruptHandler(KnownInterrupt.DoubleFault, InterruptHandlers.DoubleFault); SetInterruptHandler(KnownInterrupt.CoProcessorSegmentOverrun, InterruptHandlers.CoProcessorSegmentOverrun); SetInterruptHandler(KnownInterrupt.InvalidTSS, InterruptHandlers.InvalidTSS); SetInterruptHandler(KnownInterrupt.SegmentNotPresent, InterruptHandlers.SegmentNotPresent); SetInterruptHandler(KnownInterrupt.StackException, InterruptHandlers.StackException); SetInterruptHandler(KnownInterrupt.GeneralProtectionException, InterruptHandlers.GeneralProtectionException); SetInterruptHandler(KnownInterrupt.PageFault, InterruptHandlers.PageFault); SetInterruptHandler(KnownInterrupt.CoProcessorError, InterruptHandlers.CoProcessorError); SetInterruptHandler(KnownInterrupt.SIMDFloatinPointException, InterruptHandlers.SIMDFloatinPointException); SetInterruptHandler(KnownInterrupt.ClockTimer, InterruptHandlers.ClockTimer); SetInterruptHandler(KnownInterrupt.TerminateCurrentThread, InterruptHandlers.TermindateCurrentThread); SetInterruptPreHandler(KnownInterrupt.Keyboard, InterruptHandlers.Keyboard); // apply IDT Start(); }
public static unsafe Thread CreateThread(Process proc, ThreadStartOptions options) { Thread thread; uint threadID; lock (SyncRoot) { threadID = FindEmptyThreadSlot(); if (threadID == 0) { ResetTerminatedThreads(); threadID = FindEmptyThreadSlot(); Assert.False(threadID == 0 && Enabled, "No more free Thread-Slots!"); } thread = Threads[threadID]; thread.Status = ThreadStatus.Creating; } // Debug: //options.User = false; thread.User = proc.User; thread.Debug = options.Debug; thread.DebugName = options.DebugName; thread.Priority = options.Priority; var stackSize = options.StackSize; var argBufSize = options.ArgumentBufferSize; thread.ArgumentBufferSize = options.ArgumentBufferSize; var stackPages = KMath.DivCeil(stackSize, PhysicalPageManager.PageSize); if (KConfig.Log.Threads >= KLogLevel.Trace) { KernelMessage.WriteLine("Requesting {0} stack pages", stackPages); } var debugPadding = 8u; stackSize = stackPages * PhysicalPageManager.PageSize; var stack = new Pointer((void *)VirtualPageManager.AllocatePages(stackPages, new AllocatePageOptions { DebugName = "ThreadStack" })); PageTable.KernelTable.SetWritable((uint)stack, stackSize); if (thread.User && proc.PageTable != PageTable.KernelTable) { proc.PageTable.MapCopy(PageTable.KernelTable, (uint)stack, stackSize); } stackSize -= debugPadding; var stackBottom = stack + (int)stackSize; if (KConfig.Log.Threads >= KLogLevel.Trace) { KernelMessage.Write("Create Thread {0}. EntryPoint: {1:X8} Stack: {2:X8}-{3:X8} Type: ", threadID, options.MethodAddr, (uint)stack, (uint)stackBottom - 1); } if (KConfig.Log.Threads >= KLogLevel.Trace) { if (thread.User) { KernelMessage.Write("User"); } else { KernelMessage.Write("Kernel"); } } if (KConfig.Log.Threads >= KLogLevel.Trace) { if (thread.DebugName != null) { KernelMessage.Write(" Thread DebugName: {0}", thread.DebugName); } if (thread.Process != null) { KernelMessage.WriteLine(" Process: {0}", thread.Process.Path); } } // -- kernel stack thread.KernelStackSize = 4 * 4096; //thhread.tssAddr = RawVirtualFrameAllocator.RequestRawVirtalMemoryPages(1); PageTable.KernelTable.SetWritable(KernelStart.TssAddr, 4096); thread.KernelStack = VirtualPageManager.AllocatePages( KMath.DivCeil(thread.KernelStackSize, 4096), new AllocatePageOptions { DebugName = "ThreadKernelStack" }); // TODO: Decrease Kernel Stack, because Stack have to be changed directly because of multi-threading. thread.KernelStackBottom = thread.KernelStack + thread.KernelStackSize; if (KConfig.Log.Threads >= KLogLevel.Trace) { KernelMessage.WriteLine("tssEntry: {0:X8}, tssKernelStack: {1:X8}-{2:X8}", KernelStart.TssAddr, thread.KernelStack, thread.KernelStackBottom - 1); } PageTable.KernelTable.SetWritable(thread.KernelStack, 256 * 4096); // --- uint stackStateOffset = 8; stackStateOffset += argBufSize; uint cS = 0x08; if (thread.User) { cS = 0x1B; } var stateSize = thread.User ? IDTTaskStack.Size : IDTStack.Size; thread.StackTop = (uint)stack; thread.StackBottom = (uint)stackBottom; Intrinsic.Store32(stackBottom, 4, 0xFF00001); // Debug Marker Intrinsic.Store32(stackBottom, 0, 0xFF00002); // Debug Marker Intrinsic.Store32(stackBottom, -4, (uint)stackBottom); Intrinsic.Store32(stackBottom, -(8 + (int)argBufSize), SignalThreadTerminationMethodAddress.ToInt32()); // Address of method that will raise a interrupt signal to terminate thread uint argAddr = (uint)stackBottom - argBufSize; IDTTaskStack *stackState = null; if (thread.User) { stackState = (IDTTaskStack *)VirtualPageManager.AllocatePages(1, new AllocatePageOptions { DebugName = "ThreadStackState" }); if (proc.PageTable != PageTable.KernelTable) { proc.PageTable.MapCopy(PageTable.KernelTable, (uint)stackState, IDTTaskStack.Size); } } else { stackState = (IDTTaskStack *)(stackBottom - 8 - IDTStack.Size); // IDTStackSize is correct - we don't need the Task-Members. } thread.StackState = stackState; if (thread.User && KConfig.Log.Threads >= KLogLevel.Trace) { KernelMessage.WriteLine("StackState at {0:X8}", (uint)stackState); } stackState->Stack.EFLAGS = X86_EFlags.Reserved1; if (thread.User) { // Never set this values for Non-User, otherwise you will override stack informations. stackState->TASK_SS = 0x23; stackState->TASK_ESP = (uint)stackBottom - (uint)stackStateOffset; proc.PageTable.MapCopy(PageTable.KernelTable, thread.KernelStack, thread.KernelStackSize); proc.PageTable.MapCopy(PageTable.KernelTable, KernelStart.TssAddr, 4096); } if (thread.User && options.AllowUserModeIOPort) { byte IOPL = 3; stackState->Stack.EFLAGS = (X86_EFlags)((uint)stackState->Stack.EFLAGS).SetBits(12, 2, IOPL); } stackState->Stack.CS = cS; stackState->Stack.EIP = options.MethodAddr; stackState->Stack.EBP = (uint)(stackBottom - (int)stackStateOffset).ToInt32(); thread.DataSelector = thread.User ? 0x23u : 0x10u; UninterruptableMonitor.Enter(proc.Threads); try { thread.Process = proc; proc.Threads.Add(thread); } finally { UninterruptableMonitor.Exit(proc.Threads); } ThreadsAllocated++; if (ThreadsAllocated > ThreadsMaxAllocated) { ThreadsMaxAllocated = ThreadsAllocated; if (KConfig.Log.Threads >= KLogLevel.Trace) { KernelMessage.WriteLine("Threads Max Allocated: {0}. Allocated {0} Active: {1}", ThreadsMaxAllocated, ThreadsAllocated, GetActiveThreadCount()); } if (KConfig.Log.Threads >= KLogLevel.Trace) { DumpStats(); } } else if (KConfig.Log.Threads >= KLogLevel.Debug) { KernelMessage.WriteLine("Threads Allocated {0} Active: {1}", ThreadsAllocated, GetActiveThreadCount()); } return(thread); }
private static void KeyF3() { //PhysicalPageManager.DumpPages(); PhysicalPageManager.DumpStats(); VirtualPageManager.DumpStats(); }
private static unsafe Process CreateProcessFromElf(ElfSections elf, string path, uint argumentBufferSize = 0) { var proc = CreateEmptyProcess(new ProcessCreateOptions() { User = true }); KernelMessage.WriteLine("Create proc: {0}, PID: {1}", path, proc.ProcessID); proc.Path = path; proc.PageTable = PageTable.CreateInstance(); var allocator = new UserInitialPageAllocator() { DebugName = "UserInitial" }; allocator.Setup(new MemoryRegion(500 * 1024 * 1024, 60 * 1024 * 1014), AddressSpaceKind.Virtual); proc.UserPageAllocator = allocator; // Setup User PageTable proc.PageTableAllocAddr = VirtualPageManager.AllocatePages( KMath.DivCeil(proc.PageTable.InitalMemoryAllocationSize, 4096), new AllocatePageOptions { Pool = PageAllocationPool.Identity }); PageTable.KernelTable.SetWritable(proc.PageTableAllocAddr, proc.PageTable.InitalMemoryAllocationSize); proc.PageTable.UserProcSetup(proc.PageTableAllocAddr); proc.PageTable.Map(proc.PageTableAllocAddr, proc.PageTableAllocAddr, proc.PageTable.InitalMemoryAllocationSize); proc.PageTable.MapCopy(PageTable.KernelTable, BootInfoMemoryType.KernelTextSegment); proc.PageTable.SetExecutable(BootInfoMemoryType.KernelTextSegment); proc.PageTable.MapCopy(PageTable.KernelTable, Address.InterruptControlBlock, 4096); proc.PageTable.MapCopy(PageTable.KernelTable, KernelMemoryMapManager.Header->Used.GetMap(BootInfoMemoryType.GDT)); proc.PageTable.MapCopy(PageTable.KernelTable, KernelMemoryMapManager.Header->Used.GetMap(BootInfoMemoryType.IDT)); proc.PageTable.MapCopy(PageTable.KernelTable, KernelMemoryMapManager.Header->Used.GetMap(BootInfoMemoryType.TSS)); var tmpKernelElfHeaders = SetupElfHeader(proc, elf); // Setup ELF Sections for (uint i = 0; i < elf.ProgramHeaderCount; i++) { var section = elf.GetProgramHeader(i); var memSize = section->MemSz; var fileSize = section->FileSz; var virtAddr = section->VAddr; var srcAddr = elf.GetProgramPhysAddr(section); if (memSize == 0) { continue; } KernelMessage.WriteLine("Setup Program Section VAddr {0:X8} SrcAddr {1:X8} Size {2:X8}", virtAddr, srcAddr, memSize); if (virtAddr == Addr.Zero) { var mem = allocator.AllocatePagesAddr(KMath.DivCeil(memSize, 4096)); tmpKernelElfHeaders[i].Addr = mem; virtAddr = mem; } // Map the Sections proc.PageTable.MapCopy(PageTable.KernelTable, srcAddr, virtAddr, memSize); if (i == 0) // TODO: Flags { proc.PageTable.SetReadonly(virtAddr, memSize); } if (memSize > fileSize) { MemoryOperation.Clear(srcAddr + fileSize, memSize - fileSize); } //if (name->Equals(".text")) // proc.PageTable.SetExecutable(virtAddr, size); } KernelMessage.WriteLine("proc sections are ready"); for (uint i = 0; i < elf.SectionHeaderCount; i++) { var section = elf.GetSectionHeader(i); var size = section->Size; var virtAddr = section->Addr; var srcAddr = elf.GetSectionPhysAddr(section); if (size == 0) { continue; } var name = elf.GetSectionName(section); if (virtAddr == Addr.Zero) { } else { if (name->Equals(".bss")) { MemoryOperation.Clear(srcAddr, size); proc.BrkBase = virtAddr + size; KernelMessage.WriteLine("sbrk_base: {0:X8}", proc.BrkBase); } } } // Detect Thread-Main var entryPoint = GetMainEntryPointFromElf(elf); KernelMessage.WriteLine("EntryPoint: {0:X8}", entryPoint); var defaultDispatchEntryPoint = GetDispatchEntryPointFromElf(elf); if (defaultDispatchEntryPoint != Addr.Zero) { KernelMessage.WriteLine("DispatchEntryPoint: {0:X8}", defaultDispatchEntryPoint); proc.Service.Init(defaultDispatchEntryPoint); } var mainThread = Scheduler.CreateThread(proc, new ThreadStartOptions(entryPoint) { ArgumentBufferSize = argumentBufferSize, AllowUserModeIOPort = true, DebugName = "UserProcMainThread", }); KernelMessage.WriteLine("Created Process {0} ProcessID={1}", path, proc.ProcessID); return(proc); }
private static void StartupStage2() { try { if (!KConfig.SingleThread) { Scheduler.CreateThread(ProcessManager.System, new ThreadStartOptions(BackgroundWorker.ThreadMain) { DebugName = "BackgroundWorker", Priority = -5 }).Start(); ThreadTests.StartTestThreads(); // Start some applications var fileProc = ProcessManager.CreateProcess("Service.Basic"); FileServ = fileProc.Service; fileProc.Start(); KernelMessage.WriteLine("Waiting for Service"); while (FileServ.Status != ServiceStatus.Ready) { Scheduler.Sleep(0); } KernelMessage.WriteLine("Service Ready"); var conProc = ProcessManager.CreateProcess("Service.ConsoleServer"); conProc.Start(); var conServ = conProc.Service; KernelMessage.WriteLine("Waiting for ConsoleServer"); while (conServ.Status != ServiceStatus.Ready) { Scheduler.Sleep(0); } KernelMessage.WriteLine("ConsoleServer Ready"); //var buf = Abanu.Runtime.SysCalls.RequestMessageBuffer(4096, FileServ.Process.ProcessID); //var kb = Abanu.Runtime.SysCalls.OpenFile(buf, "/dev/keyboard"); //KernelMessage.Write("kb Handle: {0:X8}", kb); //buf.Size = 4; //Abanu.Runtime.SysCalls.WriteFile(kb, buf); //Abanu.Runtime.SysCalls.ReadFile(kb, buf); //var procHostCommunication = ProcessManager.StartProcess("Service.HostCommunication"); //ServHostCommunication = new Service(procHostCommunication); //// TODO: Optimize Registration //SysCallManager.SetCommandProcess(SysCallTarget.HostCommunication_CreateProcess, procHostCommunication); var proc = ProcessManager.CreateProcess("App.HelloService"); Serv = proc.Service; proc.Start(); var p2 = ProcessManager.CreateProcess("App.HelloKernel"); p2.Start(); //p2.Threads[0].SetArgument(0, 0x90); //p2.Threads[0].SetArgument(4, 0x94); //p2.Threads[0].SetArgument(8, 0x98); p2.Threads[0].Debug = true; var p3 = ProcessManager.CreateProcess("App.Shell"); p3.Start(); ProcessManager.System.Threads[0].Status = ThreadStatus.Terminated; } VirtualPageManager.SetTraceOptions(new PageFrameAllocatorTraceOptions { Enabled = true, MinPages = 1 }); KernelMessage.WriteLine("Enter Main Loop"); AppMain(); } catch (Exception ex) { Panic.Error(ex.Message); } }
public static void DumpStats() { Scheduler.DumpStats(); ProcessManager.DumpStats(); VirtualPageManager.DumpStats(); }
private static unsafe Process StartProcessFromElf(ElfSections elf, string path, uint argumentBufferSize = 0) { var proc = CreateEmptyProcess(new ProcessCreateOptions() { User = true }); KernelMessage.WriteLine("Create proc: {0}, PID: {1}", path, proc.ProcessID); proc.Path = path; proc.PageTable = PageTable.CreateInstance(); var allocator = new UserInitialPageAllocator() { DebugName = "UserInitial" }; allocator.Setup(new MemoryRegion(500 * 1024 * 1024, 60 * 1024 * 1014), AddressSpaceKind.Virtual); proc.UserPageAllocator = allocator; // Setup User PageTable proc.PageTableAllocAddr = VirtualPageManager.AllocatePages( KMath.DivCeil(proc.PageTable.InitalMemoryAllocationSize, 4096), new AllocatePageOptions { Pool = PageAllocationPool.Identity }); PageTable.KernelTable.SetWritable(proc.PageTableAllocAddr, proc.PageTable.InitalMemoryAllocationSize); proc.PageTable.UserProcSetup(proc.PageTableAllocAddr); proc.PageTable.Map(proc.PageTableAllocAddr, proc.PageTableAllocAddr, proc.PageTable.InitalMemoryAllocationSize); proc.PageTable.MapCopy(PageTable.KernelTable, BootInfoMemoryType.KernelTextSegment); proc.PageTable.SetExecutable(BootInfoMemoryType.KernelTextSegment); proc.PageTable.MapCopy(PageTable.KernelTable, Address.InterruptControlBlock, 4096); proc.PageTable.MapCopy(PageTable.KernelTable, KernelMemoryMapManager.Header->Used.GetMap(BootInfoMemoryType.GDT)); proc.PageTable.MapCopy(PageTable.KernelTable, KernelMemoryMapManager.Header->Used.GetMap(BootInfoMemoryType.IDT)); proc.PageTable.MapCopy(PageTable.KernelTable, KernelMemoryMapManager.Header->Used.GetMap(BootInfoMemoryType.TSS)); var tmpKernelElfHeaders = SetupElfHeader(proc, elf); // Setup ELF Sections for (uint i = 0; i < elf.SectionHeaderCount; i++) { var section = elf.GetSectionHeader(i); var name = elf.GeSectionName(section); var size = section->Size; var virtAddr = section->Addr; var srcAddr = elf.GetSectionPhysAddr(section); if (size == 0) { continue; } if (virtAddr == Addr.Zero) { var mem = allocator.AllocatePagesAddr(KMath.DivCeil(size, 4096)); tmpKernelElfHeaders[i].Addr = mem; virtAddr = mem; } var sb = new StringBuffer(); sb.Append("Map section "); sb.Append(name); sb.Append(" virt={0:X8} src={1:X8} size={2:X8}", virtAddr, srcAddr, size); KernelMessage.WriteLine(sb); //MemoryOperation.Copy4(elf.GetSectionPhysAddr(section), section->Addr, section->Size); // Map the Sections proc.PageTable.MapCopy(PageTable.KernelTable, srcAddr, virtAddr, size); if (name->Equals(".text")) { proc.PageTable.SetExecutable(virtAddr, size); } } KernelMessage.WriteLine("proc sections are ready"); // Detect Thread-Main var entryPoint = GetEntryPointFromElf(elf); KernelMessage.WriteLine("EntryPoint: {0:X8}", entryPoint); var mainThread = Scheduler.CreateThread(proc, new ThreadStartOptions(entryPoint) { ArgumentBufferSize = argumentBufferSize, AllowUserModeIOPort = true, DebugName = "UserProcMainThread", }); KernelMessage.WriteLine("Starting {0} on Thread {1}", path, mainThread.ThreadID); proc.Start(); return(proc); }