/// <summary> /// Temporary kernel memory allocation before a real heap is set up /// </summary> /// <param name="size">The size</param> /// <param name="align">If the block should be aligned</param> /// <returns>A block of memory</returns> public static unsafe void *KAlloc(int size, bool align) { #if HEAP_DEBUG if (useRealHeap) { Panic.DoPanic("[HEAP] KAlloc has been called after real heap started!"); } #endif if (PhysicalMemoryManager.IsInitialized) { return(PhysicalMemoryManager.AllocRange(size)); } else { uint address = (uint)CurrentEnd; if (align) { address = Paging.AlignUp(address); } // At least 4byte align if ((address & 3) != 0) { address &= 3; address += 4; } CurrentEnd = (void *)(address + size); return((void *)address); } }
/// <summary> /// Initializes the physical memory manager /// </summary> public static unsafe void Init() { // Bit array to store which addresses are free bitmap = new BitArray(4096 * 1024 / 4); mutex = new Mutex(); uint aligned = Paging.AlignUp((uint)Heap.CurrentEnd); Set(0, aligned); IsInitialized = true; }
/// <summary> /// Allocates the first free range /// </summary> /// <param name="size">The size</param> /// <returns>The start address</returns> public static unsafe void *AllocRange(int size) { size = (int)Paging.AlignUp((uint)size) / 0x1000; mutex.Lock(); int firstFree = bitmap.FindFirstFreeRange(size, true); mutex.Unlock(); void *address = (void *)(firstFree * 0x1000); return(address); }
public static void AcpiOsUnmapMemory(void *LogicalAddress, uint Length) { // Align address down so we can get the offset uint down = Paging.AlignDown((uint)LogicalAddress); uint offset = (uint)LogicalAddress - down; // Length in rounded pagesize uint len = Paging.AlignUp(Length + offset); Paging.UnMapKeepPhysical((void *)down, (int)len); }
/// <summary> /// Sets the range as used /// </summary> /// <param name="address">The starting address</param> /// <param name="size">The size of the range</param> public static void Set(int address, uint size) { uint start = Paging.AlignUp((uint)address); size = Paging.AlignUp(size); mutex.Lock(); for (uint i = start; i < start + size; i += 0x1000) { bitmap.SetBit((int)(i / 0x1000)); } mutex.Unlock(); }
/// <summary> /// Calculates the required amount of pages /// </summary> /// <param name="size">The requested size</param> /// <returns>The required amount of pages</returns> private static int getRequiredPageCount(int size) { // Calculate the required amount of pages (round up to nearest page) int required = (int)Paging.AlignUp((uint)size) / 0x1000; #if HEAP_DEBUG_DESCRIPTOR Console.Write("[HEAP] Required page count: "); Console.WriteNum(required); Console.Write('\n'); #endif return((required < MINIMALPAGES) ? MINIMALPAGES : required); }
public static void *AcpiOsMapMemory(ulong PhysicalAddress, uint Length) { // Align address down so we can get the offset uint down = Paging.AlignDown((uint)PhysicalAddress); uint offset = (uint)PhysicalAddress - down; // Length in rounded pagesize uint len = Paging.AlignUp(Length + offset); // Map void *mapped = Paging.MapToVirtual(Paging.CurrentDirectory, (int)down, (int)len, Paging.PageFlags.Present | Paging.PageFlags.Writable); return((void *)((uint)mapped + offset)); }