예제 #1
0
        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;
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }