Example #1
0
        public KernelContext(
            Switch device,
            MemoryBlock memory,
            MemorySize memorySize,
            MemoryArrange memoryArrange)
        {
            Device = device;
            Memory = memory;

            Running = true;

            Syscall = new Syscall(this);

            SyscallHandler = new SyscallHandler(this);

            ResourceLimit = new KResourceLimit(this);

            KernelInit.InitializeResourceLimit(ResourceLimit, memorySize);

            MemoryRegions = KernelInit.GetMemoryRegions(memorySize, memoryArrange);

            LargeMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize * 2);
            SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize);

            UserSlabHeapPages = new KSlabHeap(
                KernelConstants.UserSlabHeapBase,
                KernelConstants.UserSlabHeapItemSize,
                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 <long, KProcess>();
            AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>();

            _kipId     = KernelConstants.InitialKipId;
            _processId = KernelConstants.InitialProcessId;
        }
Example #2
0
        public KernelContext(Switch device, MemoryBlock memory)
        {
            Device = device;
            Memory = memory;

            Syscall = new Syscall(device, this);

            SyscallHandler = new SyscallHandler(this);

            ThreadCounter = new CountdownEvent(1);

            ResourceLimit = new KResourceLimit(this);

            KernelInit.InitializeResourceLimit(ResourceLimit);

            MemoryRegions = KernelInit.GetMemoryRegions();

            LargeMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize * 2);
            SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize);

            UserSlabHeapPages = new KSlabHeap(
                KernelConstants.UserSlabHeapBase,
                KernelConstants.UserSlabHeapItemSize,
                KernelConstants.UserSlabHeapSize);

            CriticalSection  = new KCriticalSection(this);
            Scheduler        = new KScheduler(this);
            TimeManager      = new KTimeManager();
            Synchronization  = new KSynchronization(this);
            ContextIdManager = new KContextIdManager();

            Scheduler.StartAutoPreemptionThread();

            KernelInitialized = true;

            Processes       = new ConcurrentDictionary <long, KProcess>();
            AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>();

            _kipId     = KernelConstants.InitialKipId;
            _processId = KernelConstants.InitialProcessId;
        }
Example #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);
        }
Example #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);
        }
Example #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);
        }
Example #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);
        }