Example #1
0
        /// <summary>
        /// Creates a new page directory using only physical memory (used in Init)
        /// </summary>
        /// <param name="flags">The flags</param>
        /// <returns>The page directory</returns>
        public static PageDirectory *CreateNewDirectoryPhysically(PageFlags flags)
        {
            // Allocate a new block of physical memory to store our physical page in
            PageDirectory *directory = (PageDirectory *)Heap.AlignedAlloc(0x1000, sizeof(PageDirectory));

            directory->PhysicalDirectory = directory;
            if (directory == null)
            {
                Panic.DoPanic("directory == null");
            }

            // Allocate the tables
            for (int i = 0; i < 1024; i++)
            {
                PageTable *table = (PageTable *)PhysicalMemoryManager.Alloc();
                if (table == null)
                {
                    Panic.DoPanic("table == null");
                }

                Memory.Memclear(table, sizeof(PageTable));

                // Note: At this point, virtual address == physical address due to identity mapping
                directory->PhysicalTables[i] = (int)table | (int)flags;
                directory->VirtualTables[i]  = (int)table;
            }

            return(directory);
        }
Example #2
0
        /// <summary>
        /// Maps a page in a directory
        /// </summary>
        /// <param name="directory">The page directory</param>
        /// <param name="phys">The physical address</param>
        /// <param name="virt">The virtual address</param>
        /// <param name="flags">The flags</param>
        public static void MapPage(PageDirectory *directory, int phys, int virt, PageFlags flags)
        {
            // Get indices
            int pageIndex  = virt / 0x1000;
            int tableIndex = pageIndex / 1024;

            // Set page using its virtual address
            PageTable *table = (PageTable *)directory->VirtualTables[tableIndex];

            table->Pages[pageIndex & (1024 - 1)] = ToFrameAddress(phys) | (int)flags;
        }
Example #3
0
        /// <summary>
        /// Gets the physical address from a virtual address
        /// </summary>
        /// <param name="pageDir">The page directory to look into</param>
        /// <param name="virt">The virtual address</param>
        /// <returns>The physical address</returns>
        public static void *GetPhysicalFromVirtual(PageDirectory *pageDir, void *virt)
        {
            // Get indices
            int address   = (int)virt;
            int remaining = address % 0x1000;
            int frame     = address / 0x1000;

            // Find corresponding table to the virtual address
            PageTable *table = (PageTable *)pageDir->VirtualTables[frame / 1024];

            if (table == null)
            {
                Panic.DoPanic("table == null");
            }

            // Calculate page
            int page = table->Pages[frame & (1024 - 1)];

            return((void *)(GetFrameAddress(page) + remaining));
        }
Example #4
0
        /// <summary>
        /// Clones a page directory and its tables
        /// </summary>
        /// <param name="source">The source page directory</param>
        /// <returns>The cloned page directory</returns>
        public static PageDirectory *CloneDirectory(PageDirectory *source)
        {
            // Note: sizeof(PageDirectory) is not neccesarily a page
            int pageDirSizeAligned = (int)AlignUp((uint)sizeof(PageDirectory));

            // One block for the page directory and the page tables
            int allocated = (int)Heap.AlignedAlloc(0x1000, pageDirSizeAligned + 1024 * sizeof(PageTable));

            if (allocated == 0)
            {
                Panic.DoPanic("Couldn't clone page directory because there is no memory left");
            }

            PageDirectory *destination = (PageDirectory *)allocated;

            destination->PhysicalDirectory = (PageDirectory *)GetPhysicalFromVirtual((void *)allocated);
            for (int i = 0; i < 1024; i++)
            {
                int sourceTable = source->VirtualTables[i];
                if (sourceTable == 0)
                {
                    Panic.DoPanic("sourceTable == 0?!");
                }

                // Get the pointer without the flags and the flags seperately
                PageTable *sourceTablePtr = (PageTable *)sourceTable;
                int        flags          = source->PhysicalTables[i] & 0xFFF;

                // Calculate addresses
                int        addressOffset    = pageDirSizeAligned + i * sizeof(PageTable);
                PageTable *newTable         = (PageTable *)(allocated + addressOffset);
                int        newTablePhysical = (int)GetPhysicalFromVirtual(newTable);

                // Copy table data and set pointers
                Memory.Memcpy(newTable, sourceTablePtr, sizeof(PageTable));
                destination->PhysicalTables[i] = newTablePhysical | flags;
                destination->VirtualTables[i]  = (int)newTable;
            }

            return(destination);
        }