Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }