public void Add(KernelMemoryMap map) { Assert.True(HasCapacity); Items[Count] = map; Count++; }
/// <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; } } }
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(); }
public bool Contains(KernelMemoryMap map) { for (var i = 0; i < Count; i++) { if (Items[i].ContainsMap(map)) { return(true); } } return(false); }
public bool Intersects(KernelMemoryMap map) { for (var i = 0; i < Count; i++) { if (Items[i].Intersects(map)) { return(true); } } return(false); }
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); }
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); }
public bool Intersects(KernelMemoryMap map) { return(ContainsAddr(map.Start) || ContainsAddr(map.Start + map.Size)); }
public bool ContainsMap(KernelMemoryMap map) { return(Start <= map.Start && map.Start + map.Size < Start + Size); }