Exemple #1
0
        /// <summary>
        /// Initializes paging
        /// </summary>
        public static void Init()
        {
            // Flags
            PageFlags kernelFlags   = PageFlags.Present | PageFlags.Writable;
            PageFlags usercodeFlags = PageFlags.Present | PageFlags.UserMode;
            PageFlags userFlags     = PageFlags.Present | PageFlags.Writable | PageFlags.UserMode;

            // Bit array to store which frames are free
            bitmap = new BitArray(4096 * 1024 / 4);

            // Create a new page directory for the kernel
            // Note: At this point, virtual address == physical address due to identity mapping
            KernelDirectory = CreateNewDirectoryPhysically(userFlags);
            SetPageDirectory(KernelDirectory, KernelDirectory);

            // Identity map
            int end = (int)PhysicalMemoryManager.FirstFree();

            for (int address = 0; address < end; address += 0x1000)
            {
                MapPage(KernelDirectory, address, address, kernelFlags);
                bitmap.SetBit(address / 0x1000);
            }

            // Usercode is a section that is code in the kernel available to usermode
            int usercode = (int)getUsercodeAddress();

            MapPage(KernelDirectory, usercode, usercode, usercodeFlags);

            // Enable paging
            Enable();
        }
Exemple #2
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);
        }
Exemple #3
0
        /// <summary>
        /// Maps a physical address (range) to a free virtual address (range)
        /// </summary>
        /// <param name="directory">The page directory</param>
        /// <param name="phys">The physical address</param>
        /// <param name="size">The size of the range</param>
        /// <param name="flags">The flags</param>
        /// <returns>The virtual address</returns>
        public static void *MapToVirtual(PageDirectory *directory, int phys, int size, PageFlags flags)
        {
            int sizeAligned = (int)AlignUp((uint)size) / 0x1000;
            int free        = bitmap.FindFirstFreeRange(sizeAligned, true);
            int virt        = free * 0x1000;

            for (int i = 0; i < sizeAligned; i++)
            {
                int offset = i * 0x1000;
                MapPage(directory, phys + offset, virt + offset, flags);
                PhysicalMemoryManager.Set(phys + offset);
            }
            Paging.setDirectoryInternal(Paging.CurrentDirectoryPhysical);
            return((void *)virt);
        }
Exemple #4
0
        /// <summary>
        /// Frees an allocate virtual address range and marks the corresponding physical addresses as free
        /// </summary>
        /// <param name="address">The starting address</param>
        /// <param name="size">The size</param>
        public static void UnMap(void *address, int size)
        {
            // Page align size
            uint sizeAligned  = AlignUp((uint)size);
            int  start        = (int)AlignDown((uint)address) / 0x1000;
            int  addressStart = (int)AlignDown((uint)address);
            int  addressEnd   = addressStart + (int)sizeAligned;

            // Free physical memory
            for (int i = addressStart; i < addressEnd; i += 0x1000)
            {
                void *phys = GetPhysicalFromVirtual((void *)i);
                PhysicalMemoryManager.Free(phys);
            }

            // Free virtual memory
            bitmap.ClearRange(start, (int)(sizeAligned / 0x1000));
        }
Exemple #5
0
        /// <summary>
        /// Initializes the specific x86 stuff
        /// </summary>
        public static void Init()
        {
            GDT.Init();
            PIC.Remap();
            IDT.Init();
            IRQ.Init();

            PhysicalMemoryManager.Init();
            Paging.Init();
            Heap.InitRealHeap();

            IOApicManager.Init();
            Acpi.Init();
            LocalApic.InitLocalAPIC();
            IOApicManager.InitIOApics();

            CMOS.UpdateTime();
            Time.FullTicks = Time.CalculateEpochTime();
        }
Exemple #6
0
        /// <summary>
        /// Allocates a virtual address range
        /// </summary>
        /// <param name="size">The size</param>
        /// <returns>The pointer to the block</returns>
        public static void *AllocateVirtual(int size)
        {
            // Page align size
            uint sizeAligned = AlignUp((uint)size);

            // Allocate
            int       free  = bitmap.FindFirstFreeRange((int)(sizeAligned / 0x1000), true);
            int       start = free * 0x1000;
            int       end   = (int)(start + sizeAligned);
            PageFlags flags = PageFlags.Present | PageFlags.Writable | PageFlags.UserMode;

            for (int address = start; address < end; address += 0x1000)
            {
                int phys = (int)PhysicalMemoryManager.Alloc();
                MapPage(KernelDirectory, phys, address, flags);
                MapPage(CurrentDirectory, phys, address, flags);
            }

            // Clear the data before returning it for safety
            Memory.Memclear((void *)start, size);

            return((void *)start);
        }