Now with arbitrary kernel page allocation.
parent
f058f250f8
commit
fae1c1a4c1
|
@ -5,4 +5,5 @@
|
|||
|
||||
void paging_init_simple(void);
|
||||
u8 paging_get_physical(u32 Virtual, u32 *Physical);
|
||||
void paging_allocate_page(u32 Virtual);
|
||||
#endif
|
||||
|
|
|
@ -21,5 +21,6 @@ void system_parse_multiboot_header(void *Header);
|
|||
u32 system_get_memory_upper(void);
|
||||
u32 system_get_memory_lower(void);
|
||||
s8 *system_get_bootloader_name(void);
|
||||
u8 system_memory_available(u32 Start, u32 Length);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,4 +45,10 @@ void kmain(void *MultibootHeader, u32 Magic)
|
|||
}
|
||||
|
||||
interrupts_init_simple();
|
||||
|
||||
paging_allocate_page(0xDEADBEEF);
|
||||
u32 *Beef = (u32*)0xDEADBEEF;
|
||||
*Beef = 13371337;
|
||||
|
||||
kprintf("Beef: %u\n", *Beef);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#include "Tier0/paging.h"
|
||||
#include "Tier0/system.h"
|
||||
#include "Tier0/kstdio.h"
|
||||
#include "types.h"
|
||||
|
||||
// 10 megabytes is safe guess, I guess.
|
||||
#define PAGING_FREEFORALL_START 0x00F00000
|
||||
|
||||
u32 g_kernel_page_directory[1024] __attribute__ ((aligned (4096)));
|
||||
u32 g_low_page_table[1024] __attribute__ ((aligned (4096)));
|
||||
u32 g_kernel_page_tables[1024][1024] __attribute__ ((aligned (4096)));
|
||||
|
||||
u32 g_paging_current_offset = PAGING_FREEFORALL_START;
|
||||
|
||||
u8 paging_get_physical(u32 Virtual, u32 *Physical)
|
||||
{
|
||||
|
@ -37,28 +43,89 @@ void paging_dump_directory(void)
|
|||
{
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
kprintf("[i] Virtual 0x%X - 0x%X, Entry 0x%X.\n", i * 4096 * 1024, \
|
||||
(i + 1) * 4096 * 1024, g_kernel_page_directory[i] & 0xFFFFF000);
|
||||
kprintf("[i] Virtual 0x%X - 0x%X, Table 0x%X.\n", i * 4096 * 1024, \
|
||||
(i + 1) * 4096 * 1024, g_kernel_page_directory[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Hey, Serge, or whoever will read this.
|
||||
//
|
||||
// Do NOT modify me to be used in user processes. I know it may be tempting to
|
||||
// do so, but don't. I'm dead serious.
|
||||
//
|
||||
// This is strictly (!) kernel-only. This assumes that the tables are already
|
||||
// created. If we were to create an empty set of tables, it would mean wasting
|
||||
// 1MB of memory for each process - and that's a Bad Thing. However, we can
|
||||
// permit ourselves to do this for the kernel. Heck, it's necessary - we need
|
||||
// solid paging to make a solid heap which will enable us to create dynamic
|
||||
// page tables for user processes. Woo.
|
||||
|
||||
// This maps 4KB
|
||||
void paging_map_kernel_page(u32 Virtual, u32 Physical)
|
||||
{
|
||||
u16 DirectoryIndex = (Virtual >> 22) & 0x3FF;
|
||||
|
||||
// Set directory entry to available
|
||||
u32 *DirectoryEntry = &g_kernel_page_directory[DirectoryIndex];
|
||||
*DirectoryEntry |= 0x03;
|
||||
|
||||
u16 TableIndex = (Virtual >> 12) & 0x3FF;
|
||||
|
||||
u32 *TableEntry = &g_kernel_page_tables[DirectoryIndex][TableIndex];
|
||||
|
||||
|
||||
*TableEntry = 0;
|
||||
// Set to present and writable
|
||||
*TableEntry |= 0x3;
|
||||
// Set to point to the physical address.
|
||||
*TableEntry |= (Physical & 0xFFFFF000);
|
||||
}
|
||||
|
||||
|
||||
// This maps 4MB
|
||||
void paging_map_kernel_table(u32 Virtual, u32 Physical)
|
||||
{
|
||||
for (u16 i = 0; i < 1024; i++)
|
||||
paging_map_kernel_page(Virtual + i * 0x1000, Physical + i * 0x1000);
|
||||
}
|
||||
|
||||
void paging_init_simple(void)
|
||||
{
|
||||
void *RealKernelPageDir = (u8 *)g_kernel_page_directory + 0x40000000;
|
||||
void *RealLowPageTable = (u8 *)g_low_page_table + 0x40000000;
|
||||
// Initialize the directory
|
||||
for (u16 i = 0; i < 1024; i++)
|
||||
g_kernel_page_directory[i] = (((u32)g_kernel_page_tables[i]) \
|
||||
+ 0x40000000);
|
||||
|
||||
for (u16 i = 0; i < 1024; i++)
|
||||
{
|
||||
g_low_page_table[i] = (i * 4096) | 0x03;
|
||||
g_kernel_page_directory[i] = 0;
|
||||
}
|
||||
// Initialize the kernel mappings (0..8MB and 3072..3080MB
|
||||
paging_map_kernel_table(0x00000000, 0x00000000);
|
||||
paging_map_kernel_table(0x00400000, 0x00400000);
|
||||
|
||||
g_kernel_page_directory[0] = (u32)RealLowPageTable | 0x03;
|
||||
g_kernel_page_directory[768] = (u32)RealLowPageTable | 0x03;
|
||||
|
||||
paging_map_kernel_table(0xC0000000, 0x00000000);
|
||||
paging_map_kernel_table(0xC0400000, 0x00400000);
|
||||
|
||||
void *PhysicalDirectory = (u8 *)g_kernel_page_directory + \
|
||||
0x40000000;
|
||||
__asm volatile ( "mov %0, %%eax\n"
|
||||
"mov %%eax, %%cr3\n"
|
||||
"mov %%cr0, %%eax\n"
|
||||
"orl $0x80000000, %%eax\n"
|
||||
"mov %%eax, %%cr0\n" :: "m" (RealKernelPageDir));
|
||||
"mov %%eax, %%cr0\n" :: "m" (PhysicalDirectory));
|
||||
}
|
||||
|
||||
// This allocates a 4kb page for whatever reason
|
||||
void paging_allocate_page(u32 Virtual)
|
||||
{
|
||||
u32 MaximumAddress = system_get_memory_upper();
|
||||
while (!system_memory_available(g_paging_current_offset, 0x1000))
|
||||
{
|
||||
g_paging_current_offset += 0x1000;
|
||||
if (g_paging_current_offset > MaximumAddress)
|
||||
{
|
||||
kprintf("[e] Fatal error: out of memory!\n");
|
||||
for (;;) {}
|
||||
}
|
||||
}
|
||||
|
||||
paging_map_kernel_page(Virtual, g_paging_current_offset);
|
||||
g_paging_current_offset += 0x1000;
|
||||
}
|
||||
|
|
|
@ -76,3 +76,25 @@ s8 *system_get_bootloader_name(void)
|
|||
{
|
||||
return g_system_bootloader;
|
||||
}
|
||||
|
||||
u8 system_memory_available(u32 Start, u32 Length)
|
||||
{
|
||||
for (u8 i = 0; i < g_system_num_invalid_areas; i++)
|
||||
{
|
||||
T_SYSTEM_INVALID_RAM Area = g_system_invalid_areas[i];
|
||||
|
||||
// If the start address is somwhere in the invalid area
|
||||
if (Area.Base <= Start && Area.Base + Area.Size > Start)
|
||||
return 0;
|
||||
|
||||
// If the end address is somewhere in the invalid area
|
||||
if (Area.Base <= Start + Length && Area.Base + Area.Size > Start + Length)
|
||||
return 0;
|
||||
|
||||
// If the request spans accross an invalid area
|
||||
if (Area.Base >= Start && Start + Length < Area.Base + Area.Size)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue