aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/memory/paging.c
diff options
context:
space:
mode:
authorMarvin Borner2020-05-16 00:42:04 +0200
committerMarvin Borner2020-05-16 00:42:04 +0200
commitffb7cb87593a5de58f7c5183020576dac9d50fc4 (patch)
treeb4d89fdbf7d5ed39e55f8e708ee87da17b957518 /src/kernel/memory/paging.c
parent916c21af52dc2230d689e1075457c4c29b4b262c (diff)
Non-dynamic working approach
Diffstat (limited to 'src/kernel/memory/paging.c')
-rw-r--r--src/kernel/memory/paging.c78
1 files changed, 35 insertions, 43 deletions
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
index 516f0f1..de93ffb 100644
--- a/src/kernel/memory/paging.c
+++ b/src/kernel/memory/paging.c
@@ -4,57 +4,47 @@
#include <stdint.h>
#include <system.h>
-int paging_enabled = 0;
+u32 *current_page_directory;
+u32 (*current_page_tables)[1024];
+u32 kernel_page_directory[1024] __attribute__((aligned(4096)));
+u32 kernel_page_tables[1024][1024] __attribute__((aligned(4096)));
-u32 tmp[1024][1024] __attribute__((aligned(4096)));
-struct page_directory *paging_kernel_directory __attribute__((aligned(4096))) =
- (struct page_directory *)tmp;
-struct page_directory *paging_directory __attribute__((aligned(4096))); // Current
-
-void paging_init(struct page_directory *dir, int user)
+void paging_init(u32 *dir, int user)
{
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- dir->tables[i]->pages[j] =
- ((j * 0x1000) + (i * PAGE_SIZE)) | PT_RW | (user ? PT_USER : 0);
+ current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW;
}
}
for (u32 i = 0; i < 1024; i++) {
- dir->tables[i] = ((u32)dir->tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0);
+ current_page_directory[i] = ((u32)current_page_tables[i]) | PD_RW | PD_PRESENT;
}
}
-struct page_directory *paging_make_directory(int user)
-{
- struct page_directory *dir = (struct page_directory *)malloc(sizeof(struct page_directory));
-
- paging_init(dir, user);
-
- return dir;
-}
-
extern void KERNEL_END();
void paging_install(u32 multiboot_address)
{
- paging_switch_directory(paging_kernel_directory);
- paging_init(paging_directory, 0);
+ paging_switch_directory(kernel_page_directory);
+ paging_init(current_page_directory, 0);
+ // if mmap approach didn't work
if (!memory_init(multiboot_address))
- paging_set_present(0, memory_get_all() >> 3);
+ paging_set_present(0, memory_get_all() >> 3); // /4
paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); // /4096
+ // paging_set_user(0, memory_get_all() >> 3); // HMM
- log("Enabling");
paging_enable();
log("Installed paging");
+}
+
+u32 *paging_make_directory(int user)
+{
+ u32 *dir = malloc(1024 * 1024 * 32);
- u32 a = (u32)malloc(4096);
- u32 b = (u32)malloc(4096);
- free((void *)b);
- free((void *)a);
- u32 c = (u32)malloc(2048);
- assert(a == c);
- info("kmalloc test succeeded!");
+ paging_init(dir, user);
+
+ return dir;
}
void paging_disable()
@@ -68,6 +58,7 @@ void paging_disable()
void paging_enable()
{
+ asm("mov %0, %%cr3" ::"r"(current_page_directory));
u32 cr0;
asm("mov %%cr0, %0" : "=r"(cr0));
cr0 |= 0x80000000;
@@ -75,10 +66,11 @@ void paging_enable()
paging_enabled = 1;
}
-void paging_switch_directory(struct page_directory *dir)
+void paging_switch_directory(u32 *dir)
{
- paging_directory = dir;
- asm("mov %0, %%cr3" ::"r"(dir));
+ current_page_tables = kernel_page_tables;
+ current_page_directory = dir;
+ asm("mov %0, %%cr3" ::"r"(current_page_directory));
}
void invlpg(u32 addr)
@@ -90,7 +82,7 @@ void paging_map(u32 phy, u32 virt, u16 flags)
{
u32 pdi = virt >> 22;
u32 pti = virt >> 12 & 0x03FF;
- paging_directory->tables[pdi]->pages[pti] = phy | flags;
+ current_page_tables[pdi][pti] = phy | flags;
invlpg(virt);
}
@@ -98,21 +90,21 @@ u32 paging_get_phys(u32 virt)
{
u32 pdi = virt >> 22;
u32 pti = (virt >> 12) & 0x03FF;
- return paging_directory->tables[pdi]->pages[pti] & 0xFFFFF000;
+ return current_page_tables[pdi][pti] & 0xFFFFF000;
}
u16 paging_get_flags(u32 virt)
{
u32 pdi = virt >> 22;
u32 pti = (virt >> 12) & 0x03FF;
- return paging_directory->tables[pdi]->pages[pti] & 0xFFF;
+ return current_page_tables[pdi][pti] & 0xFFF;
}
void paging_set_flag_up(u32 virt, u32 count, u32 flag)
{
u32 page_n = virt / 0x1000;
for (u32 i = page_n; i < page_n + count; i++) {
- paging_directory->tables[i / 1024]->pages[i % 1024] |= flag;
+ current_page_tables[i / 1024][i % 1024] |= flag;
invlpg(i * 0x1000);
}
}
@@ -121,7 +113,7 @@ void paging_set_flag_down(u32 virt, u32 count, u32 flag)
{
u32 page_n = virt / 0x1000;
for (u32 i = page_n; i < page_n + count; i++) {
- paging_directory->tables[i / 1024]->pages[i % 1024] &= ~flag;
+ current_page_tables[i / 1024][i % 1024] &= ~flag;
invlpg(i * 0x1000);
}
}
@@ -150,7 +142,7 @@ void paging_set_user(u32 virt, u32 count)
{
u32 page_n = virt / 0x1000;
for (u32 i = page_n; i < page_n + count; i += 1024) {
- paging_directory->tables[i] = ((u32)paging_directory->tables[i]) | PD_USER;
+ current_page_directory[i / 1024] |= PD_USER;
}
paging_set_flag_up(virt, count, PT_USER);
}
@@ -162,8 +154,8 @@ u32 paging_find_pages(u32 count)
u32 start_page = 0;
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- if (!(paging_directory->tables[i]->pages[j] & PT_PRESENT) ||
- (paging_directory->tables[i]->pages[j] & PT_USED)) {
+ if (!(current_page_tables[i][j] & PT_PRESENT) ||
+ (current_page_tables[i][j] & PT_USED)) {
continuous = 0;
start_dir = i;
start_page = j + 1;
@@ -191,10 +183,10 @@ u32 paging_get_used_pages()
u32 n = 0;
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- u8 flags = paging_directory->tables[i]->pages[j] & PT_USED;
+ u8 flags = current_page_tables[i][j] & PT_USED;
if (flags == 1)
n++;
}
}
return n;
-} \ No newline at end of file
+}