예제 #1
0
        public void Add(KernelMemoryMap map)
        {
            Assert.True(HasCapacity);

            Items[Count] = map;
            Count++;
        }
예제 #2
0
        /// <summary>
        /// Setup the physical page manager
        /// </summary>
        public void Setup()
        {
            uint physMem = BootInfo.Header->InstalledPhysicalMemory;

            PageCount         = physMem / PageSize;
            kmap              = KernelMemoryMapManager.Allocate(PageCount * (uint)sizeof(Page), BootInfoMemoryType.PageFrameAllocator);
            PageArray         = (Page *)kmap.Start;
            lastAllocatedPage = PageArray;

            Memory.InitialKernelProtect_MakeWritable_BySize(kmap.Start, kmap.Size);
            MemoryOperation.Clear4(kmap.Start, kmap.Size);

            for (uint i = 0; i < PageCount; i++)
            {
                PageArray[i].PhysicalAddress = i * PageSize;
                if (i != 0)
                {
                    PageArray[i - 1].Next = &PageArray[i];
                }
            }

            SetupFreeMemory();

            for (uint i = 0; i < PageCount; i++)
            {
                if (!PageArray[i].Used)
                {
                    PageArray[i].Status = PageStatus.Free;
                }
            }
        }
예제 #3
0
        public static void Setup()
        {
            var addr = Initial_FindIFreePage();

            KernelMessage.Path("KernelMemoryMapManager", "Initial Page: {0:X}", addr);

            // 80KB should be enough
            // TODO: Check if really 80KB are available after this address.
            InitialMap = new KernelMemoryMap(addr, 0x1000 * 20, BootInfoMemoryType.KernelMemoryMap);
            Memory.InitialKernelProtect_MakeWritable_BySize(InitialMap.Start, InitialMap.Size);

            Header = (KernelMemoryMapHeader *)InitialMap.Start;

            var arrayOffset1 = 0x1000;
            var arrayOffset2 = 0x3000;

            Header->SystemUsable = new KernelMemoryMapArray((KernelMemoryMap *)(InitialMap.Start + arrayOffset1), 50);
            Header->Used         = new KernelMemoryMapArray((KernelMemoryMap *)(InitialMap.Start + arrayOffset2), 100);

            for (uint i = 0; i < BootInfo.Header->MemoryMapLength; i++)
            {
                var map  = BootInfo.Header->MemoryMapArray[i];
                var kmap = new KernelMemoryMap(map.Start, map.Size, map.Type);
                if (kmap.Type == BootInfoMemoryType.SystemUsable)
                {
                    Header->SystemUsable.Add(kmap);
                }
                else
                {
                    Header->Used.Add(kmap);
                }
            }
            Header->Used.Add(InitialMap);
            //Debug_FillAvailableMemory();
        }
예제 #4
0
 public bool Contains(KernelMemoryMap map)
 {
     for (var i = 0; i < Count; i++)
     {
         if (Items[i].ContainsMap(map))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #5
0
 public bool Intersects(KernelMemoryMap map)
 {
     for (var i = 0; i < Count; i++)
     {
         if (Items[i].Intersects(map))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #6
0
        static bool CheckPageIsUsableAfterMap(KernelMemoryMap map, USize size)
        {
            var tryMap = new KernelMemoryMap(map.Start + map.Size, size, BootInfoMemoryType.Unknown);

            if (Header->Used.Intersects(tryMap))
            {
                return(false);
            }

            if (!Header->SystemUsable.Contains(tryMap))
            {
                return(false);
            }

            return(true);
        }
예제 #7
0
        public static KernelMemoryMap Allocate(USize size, BootInfoMemoryType type)
        {
            var cnt = Header->Used.Count;

            for (uint i = 0; i < cnt; i++)
            {
                var map = Header->Used.Items[i];
                if (CheckPageIsUsableAfterMap(map, size))
                {
                    var newMap = new KernelMemoryMap(map.Start + map.Size, size, type);
                    Header->Used.Add(newMap);
                    KernelMessage.Path("KernelMemoryMapManager", "Allocated: at {0:X8}, size {1:X8}, type {2}", newMap.Start, size, (uint)type);
                    return(newMap);
                }
            }
            return(KernelMemoryMap.Empty);
        }
예제 #8
0
 public bool Intersects(KernelMemoryMap map)
 {
     return(ContainsAddr(map.Start) || ContainsAddr(map.Start + map.Size));
 }
예제 #9
0
 public bool ContainsMap(KernelMemoryMap map)
 {
     return(Start <= map.Start && map.Start + map.Size < Start + Size);
 }