public KernelContext( ITickSource tickSource, Switch device, MemoryBlock memory, MemorySize memorySize, MemoryArrange memoryArrange) { TickSource = tickSource; Device = device; Memory = memory; Running = true; Syscall = new Syscall(this); SyscallHandler = new SyscallHandler(this); ResourceLimit = new KResourceLimit(this); KernelInit.InitializeResourceLimit(ResourceLimit, memorySize); MemoryManager = new KMemoryManager(memorySize, memoryArrange); LargeMemoryBlockSlabManager = new KMemoryBlockSlabManager(KernelConstants.MemoryBlockAllocatorSize * 2); SmallMemoryBlockSlabManager = new KMemoryBlockSlabManager(KernelConstants.MemoryBlockAllocatorSize); UserSlabHeapPages = new KSlabHeap( KernelConstants.UserSlabHeapBase, KernelConstants.UserSlabHeapItemSize, KernelConstants.UserSlabHeapSize); memory.Commit(KernelConstants.UserSlabHeapBase - DramMemoryMap.DramBase, KernelConstants.UserSlabHeapSize); CriticalSection = new KCriticalSection(this); Schedulers = new KScheduler[KScheduler.CpuCoresCount]; PriorityQueue = new KPriorityQueue(); TimeManager = new KTimeManager(this); Synchronization = new KSynchronization(this); ContextIdManager = new KContextIdManager(); for (int core = 0; core < KScheduler.CpuCoresCount; core++) { Schedulers[core] = new KScheduler(this, core); } StartPreemptionThread(); KernelInitialized = true; Processes = new ConcurrentDictionary <ulong, KProcess>(); AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>(); _kipId = KernelConstants.InitialKipId; _processId = KernelConstants.InitialProcessId; }
public KernelResult Initialize( ProcessCreationInfo creationInfo, ReadOnlySpan <int> capabilities, KResourceLimit resourceLimit, MemoryRegion memRegion, IProcessContextFactory contextFactory, ThreadStart customThreadStart = null) { ResourceLimit = resourceLimit; _memRegion = memRegion; _contextFactory = contextFactory ?? new ProcessContextFactory(); _customThreadStart = customThreadStart; ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.SystemResourcePagesCount, memRegion); ulong codePagesCount = (ulong)creationInfo.CodePagesCount; ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KPageTableBase.PageSize; if (neededSizeForProcess != 0 && resourceLimit != null) { if (!resourceLimit.Reserve(LimitableResource.Memory, neededSizeForProcess)) { return(KernelResult.ResLimitExceeded); } } void CleanUpForError() { if (neededSizeForProcess != 0 && resourceLimit != null) { resourceLimit.Release(LimitableResource.Memory, neededSizeForProcess); } } PersonalMmHeapPagesCount = (ulong)creationInfo.SystemResourcePagesCount; KMemoryBlockSlabManager slabManager; if (PersonalMmHeapPagesCount != 0) { slabManager = new KMemoryBlockSlabManager(PersonalMmHeapPagesCount * KPageTableBase.PageSize); } else { slabManager = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication) ? KernelContext.LargeMemoryBlockSlabManager : KernelContext.SmallMemoryBlockSlabManager; } AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift); Pid = KernelContext.NewProcessId(); if (Pid == -1 || (ulong)Pid < KernelConstants.InitialProcessId) { throw new InvalidOperationException($"Invalid Process Id {Pid}."); } InitializeMemoryManager(creationInfo.Flags); bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr); ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = codePagesCount * KPageTableBase.PageSize; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, slabManager); if (result != KernelResult.Success) { CleanUpForError(); return(result); } if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic)) { CleanUpForError(); return(KernelResult.InvalidMemRange); } result = MemoryManager.MapPages( codeAddress, codePagesCount, MemoryState.CodeStatic, KMemoryPermission.None); if (result != KernelResult.Success) { CleanUpForError(); return(result); } result = Capabilities.InitializeForUser(capabilities, MemoryManager); if (result != KernelResult.Success) { CleanUpForError(); return(result); } result = ParseProcessInfo(creationInfo); if (result != KernelResult.Success) { CleanUpForError(); } return(result); }
public KernelResult InitializeKip( ProcessCreationInfo creationInfo, ReadOnlySpan <int> capabilities, KPageList pageList, KResourceLimit resourceLimit, MemoryRegion memRegion, IProcessContextFactory contextFactory, ThreadStart customThreadStart = null) { ResourceLimit = resourceLimit; _memRegion = memRegion; _contextFactory = contextFactory ?? new ProcessContextFactory(); _customThreadStart = customThreadStart; AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift); Pid = KernelContext.NewKipId(); if (Pid == 0 || (ulong)Pid >= KernelConstants.InitialProcessId) { throw new InvalidOperationException($"Invalid KIP Id {Pid}."); } InitializeMemoryManager(creationInfo.Flags); bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr); ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = (ulong)creationInfo.CodePagesCount * KPageTableBase.PageSize; KMemoryBlockSlabManager slabManager = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication) ? KernelContext.LargeMemoryBlockSlabManager : KernelContext.SmallMemoryBlockSlabManager; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, slabManager); if (result != KernelResult.Success) { return(result); } if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic)) { return(KernelResult.InvalidMemRange); } result = MemoryManager.MapPages(codeAddress, pageList, MemoryState.CodeStatic, KMemoryPermission.None); if (result != KernelResult.Success) { return(result); } result = Capabilities.InitializeForKernel(capabilities, MemoryManager); if (result != KernelResult.Success) { return(result); } return(ParseProcessInfo(creationInfo)); }