public static KernelResult StartInitialProcess( KernelContext context, ProcessCreationInfo creationInfo, ReadOnlySpan <int> capabilities, int mainThreadPriority, ThreadStart customThreadStart) { KProcess process = new KProcess(context); KernelResult result = process.Initialize( creationInfo, capabilities, context.ResourceLimit, MemoryRegion.Service, null, customThreadStart); if (result != KernelResult.Success) { return(result); } process.DefaultCpuCore = 3; context.Processes.TryAdd(process.Pid, process); return(process.Start(mainThreadPriority, 0x1000UL)); }
private KernelResult ParseProcessInfo(ProcessCreationInfo creationInfo) { //Ensure that the current kernel version is equal or above to the minimum required. uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19; uint requiredKernelVersionMinor = ((uint)Capabilities.KernelReleaseVersion >> 15) & 0xf; if (System.EnableVersionChecks) { if (requiredKernelVersionMajor > KernelVersionMajor) { return(KernelResult.InvalidCombination); } if (requiredKernelVersionMajor != KernelVersionMajor && requiredKernelVersionMajor < 3) { return(KernelResult.InvalidCombination); } if (requiredKernelVersionMinor > KernelVersionMinor) { return(KernelResult.InvalidCombination); } } KernelResult result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress); if (result != KernelResult.Success) { return(result); } UserExceptionContextAddress = userExceptionContextAddress; MemoryHelper.FillWithZeros(CpuMemory, (long)userExceptionContextAddress, KTlsPageInfo.TlsEntrySize); Name = creationInfo.Name; _state = ProcessState.Created; _creationTimestamp = PerformanceCounter.ElapsedMilliseconds; MmuFlags = creationInfo.MmuFlags; _category = creationInfo.Category; TitleId = creationInfo.TitleId; _entrypoint = creationInfo.CodeAddress; _imageSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; _useSystemMemBlocks = ((MmuFlags >> 6) & 1) != 0; switch ((AddressSpaceType)((MmuFlags >> 1) & 7)) { case AddressSpaceType.Addr32Bits: case AddressSpaceType.Addr36Bits: case AddressSpaceType.Addr39Bits: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart; break; case AddressSpaceType.Addr32BitsNoMap: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart + MemoryManager.AliasRegionEnd - MemoryManager.AliasRegionStart; break; default: throw new InvalidOperationException($"Invalid MMU flags value 0x{MmuFlags:x2}."); } GenerateRandomEntropy(); return(KernelResult.Success); }
public KernelResult Initialize( ProcessCreationInfo creationInfo, int[] caps, KResourceLimit resourceLimit, MemoryRegion memRegion) { ResourceLimit = resourceLimit; _memRegion = memRegion; ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.PersonalMmHeapPagesCount, memRegion); ulong codePagesCount = (ulong)creationInfo.CodePagesCount; ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KMemoryManager.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.PersonalMmHeapPagesCount; KMemoryBlockAllocator memoryBlockAllocator; if (PersonalMmHeapPagesCount != 0) { memoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize); } else { memoryBlockAllocator = (MmuFlags & 0x40) != 0 ? System.LargeMemoryBlockAllocator : System.SmallMemoryBlockAllocator; } AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7); bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0; ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = codePagesCount * KMemoryManager.PageSize; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, memoryBlockAllocator); if (result != KernelResult.Success) { CleanUpForError(); return(result); } if (!ValidateCodeAddressAndSize(codeAddress, codeSize)) { CleanUpForError(); return(KernelResult.InvalidMemRange); } result = MemoryManager.MapNewProcessCode( codeAddress, codePagesCount, MemoryState.CodeStatic, MemoryPermission.None); if (result != KernelResult.Success) { CleanUpForError(); return(result); } result = Capabilities.InitializeForUser(caps, MemoryManager); if (result != KernelResult.Success) { CleanUpForError(); return(result); } Pid = System.GetProcessId(); if (Pid == -1 || (ulong)Pid < Horizon.InitialProcessId) { throw new InvalidOperationException($"Invalid Process Id {Pid}."); } result = ParseProcessInfo(creationInfo); if (result != KernelResult.Success) { CleanUpForError(); } return(result); }
public KernelResult InitializeKip( ProcessCreationInfo creationInfo, int[] caps, KPageList pageList, KResourceLimit resourceLimit, MemoryRegion memRegion) { ResourceLimit = resourceLimit; _memRegion = memRegion; AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7); bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0; ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; KMemoryBlockAllocator memoryBlockAllocator = (MmuFlags & 0x40) != 0 ? System.LargeMemoryBlockAllocator : System.SmallMemoryBlockAllocator; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, memoryBlockAllocator); if (result != KernelResult.Success) { return(result); } if (!ValidateCodeAddressAndSize(codeAddress, codeSize)) { return(KernelResult.InvalidMemRange); } result = MemoryManager.MapPages( codeAddress, pageList, MemoryState.CodeStatic, MemoryPermission.None); if (result != KernelResult.Success) { return(result); } result = Capabilities.InitializeForKernel(caps, MemoryManager); if (result != KernelResult.Success) { return(result); } Pid = System.GetKipId(); if (Pid == 0 || (ulong)Pid >= Horizon.InitialProcessId) { throw new InvalidOperationException($"Invalid KIP Id {Pid}."); } result = ParseProcessInfo(creationInfo); return(result); }
public KernelResult Initialize( ProcessCreationInfo CreationInfo, int[] Caps, KResourceLimit ResourceLimit, MemoryRegion MemRegion) { this.ResourceLimit = ResourceLimit; this.MemRegion = MemRegion; ulong PersonalMmHeapSize = GetPersonalMmHeapSize((ulong)CreationInfo.PersonalMmHeapPagesCount, MemRegion); ulong CodePagesCount = (ulong)CreationInfo.CodePagesCount; ulong NeededSizeForProcess = PersonalMmHeapSize + CodePagesCount * KMemoryManager.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.PersonalMmHeapPagesCount; KMemoryBlockAllocator MemoryBlockAllocator; if (PersonalMmHeapPagesCount != 0) { MemoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize); } else { MemoryBlockAllocator = (MmuFlags & 0x40) != 0 ? System.LargeMemoryBlockAllocator : System.SmallMemoryBlockAllocator; } AddressSpaceType AddrSpaceType = (AddressSpaceType)((CreationInfo.MmuFlags >> 1) & 7); bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0; ulong CodeAddress = CreationInfo.CodeAddress; ulong CodeSize = CodePagesCount * KMemoryManager.PageSize; KernelResult Result = MemoryManager.InitializeForProcess( AddrSpaceType, AslrEnabled, !AslrEnabled, MemRegion, CodeAddress, CodeSize, MemoryBlockAllocator); if (Result != KernelResult.Success) { CleanUpForError(); return(Result); } if (!ValidateCodeAddressAndSize(CodeAddress, CodeSize)) { CleanUpForError(); return(KernelResult.InvalidMemRange); } Result = MemoryManager.MapNewProcessCode( CodeAddress, CodePagesCount, MemoryState.CodeStatic, MemoryPermission.None); if (Result != KernelResult.Success) { CleanUpForError(); return(Result); } Result = Capabilities.InitializeForUser(Caps, MemoryManager); if (Result != KernelResult.Success) { CleanUpForError(); return(Result); } Pid = System.GetProcessId(); if (Pid == -1 || (ulong)Pid < Horizon.InitialProcessId) { throw new InvalidOperationException($"Invalid Process Id {Pid}."); } Result = ParseProcessInfo(CreationInfo); if (Result != KernelResult.Success) { CleanUpForError(); } return(Result); }
public KernelResult InitializeKip( ProcessCreationInfo CreationInfo, int[] Caps, KPageList PageList, KResourceLimit ResourceLimit, MemoryRegion MemRegion) { this.ResourceLimit = ResourceLimit; this.MemRegion = MemRegion; AddressSpaceType AddrSpaceType = (AddressSpaceType)((CreationInfo.MmuFlags >> 1) & 7); bool AslrEnabled = ((CreationInfo.MmuFlags >> 5) & 1) != 0; ulong CodeAddress = CreationInfo.CodeAddress; ulong CodeSize = (ulong)CreationInfo.CodePagesCount * KMemoryManager.PageSize; KMemoryBlockAllocator MemoryBlockAllocator = (MmuFlags & 0x40) != 0 ? System.LargeMemoryBlockAllocator : System.SmallMemoryBlockAllocator; KernelResult Result = MemoryManager.InitializeForProcess( AddrSpaceType, AslrEnabled, !AslrEnabled, MemRegion, CodeAddress, CodeSize, MemoryBlockAllocator); if (Result != KernelResult.Success) { return(Result); } if (!ValidateCodeAddressAndSize(CodeAddress, CodeSize)) { return(KernelResult.InvalidMemRange); } Result = MemoryManager.MapPages( CodeAddress, PageList, MemoryState.CodeStatic, MemoryPermission.None); if (Result != KernelResult.Success) { return(Result); } Result = Capabilities.InitializeForKernel(Caps, MemoryManager); if (Result != KernelResult.Success) { return(Result); } Pid = System.GetKipId(); if (Pid == 0 || (ulong)Pid >= Horizon.InitialProcessId) { throw new InvalidOperationException($"Invalid KIP Id {Pid}."); } Result = ParseProcessInfo(CreationInfo); return(Result); }