/// <summary> /// Returns a pointer size of largest continuous block of free ram /// DOES NOT ALLOCATE ANYTHING so it can be used before Memory Management is initalised /// </summary> /// <returns>The size of the largest block in bytes</returns> public static unsafe RawMemoryMapBlock *GetLargestMemoryBlock() { if (!Multiboot2.MemoryMapExists()) { return(null); } var baseMap = (RawMemoryMapBlock *)((uint *)Multiboot2.MemoryMap + (uint)16); var currentMap = baseMap; uint totalSize = Multiboot2.MemoryMap->Size - 16; uint entrySize = Multiboot2.MemoryMap->EntrySize; RawMemoryMapBlock *BestMap = null; int counter = 0; ulong bestSize = 0; while ((uint)currentMap < ((uint)baseMap + totalSize) && counter < 64) { currentMap = (RawMemoryMapBlock *)((uint)currentMap + entrySize); if (currentMap->Type == 1) { if (currentMap->Length > bestSize) { BestMap = currentMap; bestSize = currentMap->Length; } } } return(BestMap); }
/// Get the Memory Map Information from Multiboot /// </summary> /// <returns>Returns an array of MemoryMaps containing the Multiboot Memory Map information. The array may have empty values at the end.</returns> public static unsafe MemoryMapBlock[] GetMemoryMap() { if (!Multiboot2.MemoryMapExists()) { throw new Exception("No Memory Map was returned by Multiboot"); } var rawMap = new RawMemoryMapBlock[64]; var baseMap = (RawMemoryMapBlock *)((uint *)Multiboot2.MemoryMap + (uint)16); var currentMap = baseMap; uint totalSize = Multiboot2.MemoryMap->Size - 16; uint entrySize = Multiboot2.MemoryMap->EntrySize; int counter = 0; while ((uint)currentMap < ((uint)baseMap + totalSize) && counter < 64) { rawMap[counter++] = *currentMap; currentMap = (RawMemoryMapBlock *)((uint)currentMap + entrySize); } if (counter >= 64) { throw new Exception("Memory Map returned too many segments"); } var entireMap = new MemoryMapBlock[counter]; for (int i = 0; i < counter; i++) { var rawMemoryMap = rawMap[i]; entireMap[i] = new MemoryMapBlock { Address = rawMemoryMap.Address, Length = rawMemoryMap.Length, Type = rawMemoryMap.Type }; } return(entireMap); }