aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-05-23 18:43:22 +0200
committerMarvin Borner2020-05-23 18:43:22 +0200
commit7e53464d7bb2187fe0754fbdc04becbdccae11fe (patch)
treea90a8350bb34d114478d041ff1b6b2af0f90bd45
parent44f6465b541259c608c043b0c5c8f70ae43b51e2 (diff)
Dynamic paging approach
I think this is it. I really do. I guess.
-rw-r--r--src/kernel/fs/elf.c2
-rw-r--r--src/kernel/memory/paging.c50
-rw-r--r--src/kernel/memory/paging.h8
-rw-r--r--src/kernel/tasks/process.h2
4 files changed, 27 insertions, 35 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c
index fe180c4..e11b91f 100644
--- a/src/kernel/fs/elf.c
+++ b/src/kernel/fs/elf.c
@@ -26,7 +26,7 @@ int is_elf(struct elf_header *header)
struct process *elf_load(char *path)
{
log("ELF START");
- u32 *prev_dir;
+ u32 **prev_dir;
if (current_proc)
prev_dir = current_proc->cr3;
else
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
index 917a186..db9fc2d 100644
--- a/src/kernel/memory/paging.c
+++ b/src/kernel/memory/paging.c
@@ -4,35 +4,38 @@
#include <stdint.h>
#include <system.h>
-u32 *current_page_directory;
-u32 (*current_page_tables)[1024];
-u32 kernel_page_directory[1024] __attribute__((aligned(4096)));
+u32 **current_page_directory;
+u32 *kernel_page_directory[1024] __attribute__((aligned(4096)));
u32 kernel_page_tables[1024][1024] __attribute__((aligned(4096)));
-void paging_init(u32 *dir, u32 tables[1024][1024], int user)
+void paging_init(u32 **dir, int user)
{
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- tables[i][j] =
- ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0);
+ dir[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0);
}
}
for (u32 i = 0; i < 1024; i++) {
- dir[i] = ((u32)tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0);
+ dir[i] = ((u32)dir[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0);
}
}
extern void KERNEL_END();
void paging_install()
{
- paging_init(kernel_page_directory, kernel_page_tables, 0);
- paging_switch_directory(kernel_page_directory);
+ for (u32 i = 0; i < 1024; i++) {
+ kernel_page_directory[i] = kernel_page_tables[i];
+ }
+
+ paging_init((u32 **)kernel_page_directory, 0);
+ paging_switch_directory((u32 **)kernel_page_directory);
if (!memory_init())
paging_set_present(0, memory_get_all() >> 3);
paging_set_used(0, ((u32)KERNEL_END >> 12) + 1);
+ log("Installing paging");
paging_enable();
log("Installed paging");
@@ -79,9 +82,8 @@ void paging_enable()
paging_enabled = 1;
}
-void paging_switch_directory(u32 *dir)
+void paging_switch_directory(u32 **dir)
{
- current_page_tables = dir;
current_page_directory = dir;
asm("mov %0, %%cr3" ::"r"(current_page_directory));
}
@@ -95,7 +97,7 @@ void paging_map(u32 phy, u32 virt, u16 flags)
{
u32 pdi = virt >> 22;
u32 pti = virt >> 12 & 0x03FF;
- current_page_tables[pdi][pti] = phy | flags;
+ current_page_directory[pdi][pti] = phy | flags;
invlpg(virt);
}
@@ -103,21 +105,21 @@ u32 paging_get_phys(u32 virt)
{
u32 pdi = virt >> 22;
u32 pti = (virt >> 12) & 0x03FF;
- return current_page_tables[pdi][pti] & 0xFFFFF000;
+ return current_page_directory[pdi][pti] & 0xFFFFF000;
}
u16 paging_get_flags(u32 virt)
{
u32 pdi = virt >> 22;
u32 pti = (virt >> 12) & 0x03FF;
- return current_page_tables[pdi][pti] & 0xFFF;
+ return current_page_directory[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++) {
- current_page_tables[i / 1024][i % 1024] |= flag;
+ current_page_directory[i / 1024][i % 1024] |= flag;
invlpg(i * 0x1000);
}
}
@@ -126,7 +128,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++) {
- current_page_tables[i / 1024][i % 1024] &= ~flag;
+ current_page_directory[i / 1024][i % 1024] &= ~flag;
invlpg(i * 0x1000);
}
}
@@ -151,15 +153,6 @@ void paging_set_free(u32 virt, u32 count)
paging_set_flag_down(virt, count, PT_USED);
}
-void paging_set_user(u32 virt, u32 count)
-{
- u32 page_n = virt / 0x1000;
- for (u32 i = page_n; i < page_n + count; i += 1024) {
- current_page_directory[i / 1024] |= PD_USER;
- }
- paging_set_flag_up(virt, count, PT_USER);
-}
-
u32 paging_find_pages(u32 count)
{
u32 continuous = 0;
@@ -167,8 +160,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 (!(current_page_tables[i][j] & PT_PRESENT) ||
- (current_page_tables[i][j] & PT_USED)) {
+ if (!(current_page_directory[i][j] & PT_PRESENT) ||
+ (current_page_directory[i][j] & PT_USED)) {
continuous = 0;
start_dir = i;
start_page = j + 1;
@@ -187,7 +180,6 @@ u32 paging_alloc_pages(u32 count)
{
u32 ptr = paging_find_pages(count);
paging_set_used(ptr, count);
- paging_set_user(ptr, count);
return ptr;
}
@@ -196,7 +188,7 @@ u32 paging_get_used_pages()
u32 n = 0;
for (u32 i = 0; i < 1024; i++) {
for (u32 j = 0; j < 1024; j++) {
- u8 flags = current_page_tables[i][j] & PT_USED;
+ u8 flags = current_page_directory[i][j] & PT_USED;
if (flags == 1)
n++;
}
diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h
index 553c0e6..29409ab 100644
--- a/src/kernel/memory/paging.h
+++ b/src/kernel/memory/paging.h
@@ -23,16 +23,16 @@
#define PT_GLOBAL 1 << 8
#define PT_USED 1 << 9
-u32 *current_page_directory;
-u32 kernel_page_directory[1024] __attribute__((aligned(4096)));
+u32 **current_page_directory;
+u32 *kernel_page_directory[1024] __attribute__((aligned(4096)));
int paging_enabled;
void paging_install();
void paging_enable();
void paging_disable();
-u32 *paging_make_directory(int user);
-void paging_switch_directory(u32 *dir);
+u32 **paging_make_directory(int user);
+void paging_switch_directory(u32 **dir);
void paging_map(u32 phy, u32 virt, u16 flags);
u32 paging_get_phys(u32 virt);
diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h
index 96ef44b..ef66c2a 100644
--- a/src/kernel/tasks/process.h
+++ b/src/kernel/tasks/process.h
@@ -13,7 +13,7 @@ struct mmap {
};
struct process {
- u32 *cr3;
+ u32 **cr3;
struct regs registers;
u32 pid;