/// <summary> /// Reserves a range of memory pages so that they cannot be allocated using /// <see cref="M:Alloc()" /> or <see cref="M:RangeAlloc(uint count)" />. /// </summary> /// <param name="pageStart"> /// A pointer which is aligned along the platform's native page boundaries. /// </param> /// <param name="pages"> /// The amount of pages to reserve. /// </param> public static bool ReservePageRange(void *firstPage, uint pages, string name) { ReservedPages *reservePages = GetReservedPage(); reservePages->Address = (uint)firstPage; reservePages->Size = pages; return(true); }
private static void DumpReservedStack(ReservedPages *pageStack, uint stackPtr, int count) { for (int i = (int)stackPtr - 1; i >= 0 && i >= stackPtr - count; i--) { ADC.TextMode.Write(i); ADC.TextMode.Write(": Address: "); ADC.TextMode.Write((int)pageStack->Address); ADC.TextMode.Write(", Size: "); ADC.TextMode.Write((int)pageStack->Size); pageStack++; ADC.TextMode.WriteLine(); } }
/// <summary> /// Returns true if the given page is reserved (that is, not available for allocation). /// </summary> public static bool IsPageReserved(void *page) { uint sp = 0; ReservedPages *ptr = rpStack; uint pageAddr = (uint)page; while (sp < rpStackPointer) { if (pageAddr >= ptr[sp].Address && pageAddr < (ptr[sp].Address + (ptr[sp].Size * Pager.AtomicPageSize))) { return(true); } sp++; } return(false); }
/// <summary> /// Reserves a memory page so that it cannot be allocated using /// <see cref="M:Alloc()" /> or <see cref="M:RangeAlloc(uint count)" />. /// </summary> /// <param name="page"> /// A pointer which is aligned along the platform's native page boundaries. /// </param> public static bool ReservePage(void *page) { if (page == null) { return(false); } // we should be doing this.. but it's so slow.. if (IsPageReserved(page)) // ugh... { return(true); } //if (!IsPageFree(page, &fsp)) // return false; ReservedPages *pages = GetReservedPage(); pages->Address = (uint)page; pages->Size = 1; return(true); }
/// <summary> /// Initializes page management and paging. Using <see cref="Alloc" /> /// and related management functions before calling this function results /// in a kernel panic. After this function is called, the /// <see cref="ReservePage"/> and <see cref="ReservePageRange" /> /// functions can be used to reserve memory that should not be allocated. /// You should ensure that no memory allocations have happened between /// calling this function and reserving memory. /// </summary> public static void Setup (byte* kernelOffset, uint _kernelSize, uint totalKbMem) { PagingMemoryRequirements* pagingMemory = stackalloc PagingMemoryRequirements[1]; // The total memory in bytes totalMem = totalKbMem * 1024; // Total pages totalPages = totalMem / Pager.AtomicPageSize; // First page of the kernel kernelStartPage = (byte*)PtrToPage (kernelOffset); // Kernel size in pages kernelSize = (_kernelSize / Pager.AtomicPageSize) + 1; // Allocate the free page stack immediately after end of the kernel fpStack = (uint*)(kernelStartPage + (kernelSize * Pager.AtomicPageSize)); // Initalize the stack pointer fpStackPointer = 0; // Free page stack size in pages fpStackSize = (totalPages * (uint)sizeof (uint*) / Pager.AtomicPageSize) + 1; // Allocate the reserved page stack immediately after free page stack rpStack = (ReservedPages*)((uint)fpStack + (fpStackSize * Pager.AtomicPageSize)); // Initalize the reserve stack pointer rpStackPointer = 0; // Reserve stack size in pages rpStackSize = 1; // fixed - should be enough // Allocate paging information pagingData = (byte*)(rpStack + (rpStackSize * Pager.AtomicPageSize)); pagingMemory->Start = (void*)pagingData; // Reserve 4 mega bytes of memory for Virtual memory manager // FIXME: pagingDataSize = (4 * 1024 * 1024) / 4096; // Reserve the memory ranges we're using. ReservePageRange (kernelStartPage, kernelSize, "kernel"); ReservePageRange (fpStack, fpStackSize, "fpstack"); ReservePageRange (rpStack, rpStackSize, "rpstack"); ReservePageRange (pagingData, pagingDataSize, "paging"); // Reserve memory below 0x100000 (1MB) for the BIOS/video memory ReservePageRange ((void*)0, (0x100000 / ADC.Pager.AtomicPageSize), "Reserve memory below 0x100000 (1MB) for the BIOS/video memory"); // FIXME: the value we get back from Pager.Setup is not the same value that // we 'return' from inside the method itself!!!! Errors error = Errors.Unknown; Pager.Setup (totalKbMem, pagingData, pagingDataSize, &error); if (error != Errors.Success) { PrintError (error); return; } // NOTE: 0x0000 page is reserved currentPage = 1; error = Errors.Unknown; Pager.Enable (&error); if (error != Errors.Success) PrintError (error); }
/// <summary> /// Initializes page management and paging. Using <see cref="Alloc" /> /// and related management functions before calling this function results /// in a kernel panic. After this function is called, the /// <see cref="ReservePage"/> and <see cref="ReservePageRange" /> /// functions can be used to reserve memory that should not be allocated. /// You should ensure that no memory allocations have happened between /// calling this function and reserving memory. /// </summary> public static void Setup(byte *kernelOffset, uint _kernelSize, uint totalKbMem) { PagingMemoryRequirements *pagingMemory = stackalloc PagingMemoryRequirements[1]; // The total memory in bytes totalMem = totalKbMem * 1024; // Total pages totalPages = totalMem / Pager.AtomicPageSize; // First page of the kernel kernelStartPage = (byte *)PtrToPage(kernelOffset); // Kernel size in pages kernelSize = (_kernelSize / Pager.AtomicPageSize) + 1; // Allocate the free page stack immediately after end of the kernel fpStack = (uint *)(kernelStartPage + (kernelSize * Pager.AtomicPageSize)); // Initalize the stack pointer fpStackPointer = 0; // Free page stack size in pages fpStackSize = (totalPages * (uint)sizeof(uint *) / Pager.AtomicPageSize) + 1; // Allocate the reserved page stack immediately after free page stack rpStack = (ReservedPages *)((uint)fpStack + (fpStackSize * Pager.AtomicPageSize)); // Initalize the reserve stack pointer rpStackPointer = 0; // Reserve stack size in pages rpStackSize = 1; // fixed - should be enough // Allocate paging information pagingData = (byte *)(rpStack + (rpStackSize * Pager.AtomicPageSize)); pagingMemory->Start = (void *)pagingData; // Reserve 4 mega bytes of memory for Virtual memory manager // FIXME: pagingDataSize = (4 * 1024 * 1024) / 4096; // Reserve the memory ranges we're using. ReservePageRange(kernelStartPage, kernelSize, "kernel"); ReservePageRange(fpStack, fpStackSize, "fpstack"); ReservePageRange(rpStack, rpStackSize, "rpstack"); ReservePageRange(pagingData, pagingDataSize, "paging"); // Reserve memory below 0x100000 (1MB) for the BIOS/video memory ReservePageRange((void *)0, (0x100000 / ADC.Pager.AtomicPageSize), "Reserve memory below 0x100000 (1MB) for the BIOS/video memory"); // FIXME: the value we get back from Pager.Setup is not the same value that // we 'return' from inside the method itself!!!! Errors error = Errors.Unknown; Pager.Setup(totalKbMem, pagingData, pagingDataSize, &error); if (error != Errors.Success) { PrintError(error); return; } // NOTE: 0x0000 page is reserved currentPage = 1; error = Errors.Unknown; Pager.Enable(&error); if (error != Errors.Success) { PrintError(error); } }