aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-06-01 23:30:40 +0200
committerMarvin Borner2020-06-01 23:30:40 +0200
commit0b3b63ffdedb2e37e0732c09eb0e967e256f0d71 (patch)
treef92a97a59e15d699b2594d3d313214f241ae8565
parent5782d6b0c10b322d78c5d1284cbd4199d2e0f7ce (diff)
Very clean mmap approach
Sorry for the previous commit messages, I was kind of frustrated.
-rw-r--r--src/kernel/fs/elf.c4
-rw-r--r--src/kernel/io/io.c24
-rw-r--r--src/kernel/io/io.h5
-rw-r--r--src/kernel/lib/lib.h4
-rw-r--r--src/kernel/lib/memory.c51
-rw-r--r--src/kernel/memory/alloc.c8
-rw-r--r--src/kernel/memory/mmap.c106
-rw-r--r--src/kernel/memory/mmap.h18
-rw-r--r--src/kernel/memory/paging.c241
-rw-r--r--src/kernel/memory/paging.h90
-rw-r--r--src/kernel/tasks/process.c2
-rw-r--r--src/kernel/tasks/process.h2
12 files changed, 290 insertions, 265 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c
index 9d4dd60..7b95c3b 100644
--- a/src/kernel/fs/elf.c
+++ b/src/kernel/fs/elf.c
@@ -53,7 +53,7 @@ struct process *elf_load(char *path)
proc->registers.useresp = 0x40000000 - (PAGE_SIZE / 2);
proc->registers.ebp = proc->registers.useresp;
proc->registers.esp = proc->registers.useresp;
- paging_map_user(stk, 0x40000000 - PAGE_SIZE);
+ //paging_map_user(stk, 0x40000000 - PAGE_SIZE);
for (int i = 0; i < header->phnum; i++, program_header++) {
switch (program_header->type) {
@@ -61,7 +61,7 @@ struct process *elf_load(char *path)
break;
case 1: {
u32 loc = (u32)valloc(PAGE_SIZE);
- paging_map_user(loc, program_header->vaddr);
+ //paging_map_user(loc, program_header->vaddr);
memcpy((void *)program_header->vaddr,
((void *)((u32)file) + program_header->offset),
program_header->filesz);
diff --git a/src/kernel/io/io.c b/src/kernel/io/io.c
index 801a2fe..af5f008 100644
--- a/src/kernel/io/io.c
+++ b/src/kernel/io/io.c
@@ -74,6 +74,30 @@ void outl(u16 port, u32 data)
asm volatile("outl %0, %1" ::"a"(data), "Nd"(port));
}
+u32 cr3_get()
+{
+ u32 cr3;
+ asm volatile("movl %%cr3, %%eax" : "=a"(cr3));
+ return cr3;
+}
+
+void cr3_set(u32 cr3)
+{
+ asm volatile("movl %%eax, %%cr3" ::"a"(cr3));
+}
+
+u32 cr0_get()
+{
+ u32 cr0;
+ asm volatile("movl %%cr0, %%eax" : "=a"(cr0));
+ return cr0;
+}
+
+void cr0_set(u32 cr0)
+{
+ asm volatile("movl %%eax, %%cr0" ::"a"(cr0));
+}
+
void serial_install()
{
outb(0x3f8 + 1, 0x00);
diff --git a/src/kernel/io/io.h b/src/kernel/io/io.h
index b5573cc..ce3c72b 100644
--- a/src/kernel/io/io.h
+++ b/src/kernel/io/io.h
@@ -51,6 +51,11 @@ void outw(u16 port, u16 data);
*/
void outl(u16 port, u32 data);
+u32 cr3_get();
+void cr3_set(u32 cr3);
+u32 cr0_get();
+void cr0_set(u32 cr0);
+
/**
* Initialize the serial conenction
*/
diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h
index a71c929..06f9eda 100644
--- a/src/kernel/lib/lib.h
+++ b/src/kernel/lib/lib.h
@@ -32,9 +32,7 @@ void *memset(void *dest, char val, u32 count);
*/
int memcmp(const void *a_ptr, const void *b_ptr, u32 size);
-void memory_info_init(struct multiboot_tag_basic_meminfo *tag);
-void memory_mmap_init(struct multiboot_tag_mmap *tag);
-int memory_init();
+void memory_init();
void memory_print();
u32 memory_get_all();
diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c
index 228f465..ef7cb78 100644
--- a/src/kernel/lib/memory.c
+++ b/src/kernel/lib/memory.c
@@ -1,5 +1,5 @@
#include <lib/stdio.h>
-#include <memory/paging.h>
+#include <memory/mmap.h>
#include <multiboot.h>
#include <stddef.h>
#include <stdint.h>
@@ -38,6 +38,7 @@ int memcmp(const void *a_ptr, const void *b_ptr, u32 size)
// TODO: Move memory lib!
u32 total = 0;
struct multiboot_tag_basic_meminfo *meminfo = NULL;
+struct multiboot_tag_mmap *mmap = NULL;
u32 memory_get_all()
{
@@ -53,7 +54,7 @@ u32 memory_get_all()
u32 memory_get_free()
{
- int free_memory = memory_get_all() - paging_get_used_pages() * 4;
+ int free_memory = memory_get_all() - 42 * 4; // TODO: Fix free memory
if (free_memory < 0)
return 0;
else
@@ -72,9 +73,8 @@ void memory_print()
info("Total free memory: %dMiB", (memory_get_free() >> 10));
}
-void memory_info_init(struct multiboot_tag_basic_meminfo *tag)
+void memory_info_init()
{
- meminfo = tag;
}
void memory_mmap_init(struct multiboot_tag_mmap *tag)
@@ -91,42 +91,43 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag)
// Translate to pages
if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) {
- paging_set_present(mmap->addr, mmap->len >> 13);
- } else if (mmap->type == MULTIBOOT_MEMORY_RESERVED) {
- paging_set_present(mmap->addr, mmap->len >> 13);
- paging_set_used(mmap->addr, mmap->len >> 13);
- } else if (mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE) {
- paging_set_present(mmap->addr, mmap->len >> 13);
- paging_set_used(mmap->addr, mmap->len >> 13);
- } else if (mmap->type == MULTIBOOT_MEMORY_NVS) {
- paging_set_present(mmap->addr, mmap->len >> 13);
- paging_set_used(mmap->addr, mmap->len >> 13);
- } else if (mmap->type == MULTIBOOT_MEMORY_BADRAM) {
- paging_set_present(mmap->addr, mmap->len >> 13);
- paging_set_used(mmap->addr, mmap->len >> 13);
+ for (u32 i = 0; i < mmap->len; i += 0x1000) {
+ if (mmap->addr + i > 0xFFFFFFFF)
+ break;
+ mmap_address_set_free((mmap->addr + i) & 0xFFFFF000);
+ }
+ } else {
+ for (u32 i = 0; i < mmap->len; i += 0x1000) {
+ if (mmap->addr + i > 0xFFFFFFFF)
+ break;
+ mmap_address_set_used((mmap->addr + i) & 0xFFFFF000);
+ }
}
+
+ total = sum >> 10; // I want kb
}
- total = sum >> 10; // I want kb
}
-int memory_init()
+void memory_init()
{
- int ret = 0;
- struct multiboot_tag *tag;
+ struct multiboot_tag *tag = NULL;
for (tag = (struct multiboot_tag *)(multiboot_address + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *)((u8 *)tag + ((tag->size + 7) & ~7))) {
if (tag->type == MULTIBOOT_TAG_TYPE_BASIC_MEMINFO) {
info("Got memory info");
- memory_info_init((struct multiboot_tag_basic_meminfo *)tag);
+ meminfo = (struct multiboot_tag_basic_meminfo *)tag;
} else if (tag->type == MULTIBOOT_TAG_TYPE_MMAP) {
info("Got memory map");
- memory_mmap_init((struct multiboot_tag_mmap *)tag);
- ret = 1;
+ mmap = (struct multiboot_tag_mmap *)tag;
}
}
- return ret;
+
+ assert(mmap && meminfo);
+ mmap_init(meminfo->mem_lower + meminfo->mem_upper);
+ memory_mmap_init(mmap);
+ mmap_init_finalize();
}
void bss_clean()
diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c
index d1d8b47..4f76080 100644
--- a/src/kernel/memory/alloc.c
+++ b/src/kernel/memory/alloc.c
@@ -1,6 +1,7 @@
#include <io/io.h>
#include <lib/lib.h>
#include <memory/alloc.h>
+#include <memory/mmap.h>
#include <memory/paging.h>
#include <stddef.h>
#include <stdint.h>
@@ -22,13 +23,13 @@ int liballoc_unlock()
void *liballoc_alloc(u32 p)
{
- u32 ptr = paging_alloc_pages((u32)p);
+ u32 ptr = kmalloc_frames((u32)p);
return (void *)ptr;
}
int liballoc_free(void *ptr, u32 p)
{
- paging_set_free((u32)ptr, (u32)p);
+ kfree_frames((u32)ptr, (u32)p);
return 0;
}
@@ -96,8 +97,7 @@ static long long l_possible_overruns = 0;
static void *liballoc_memset(void *s, int c, u32 n)
{
- u32 i;
- for (i = 0; i < n; i++)
+ for (u32 i = 0; i < n; i++)
((char *)s)[i] = c;
return s;
diff --git a/src/kernel/memory/mmap.c b/src/kernel/memory/mmap.c
new file mode 100644
index 0000000..ab021b8
--- /dev/null
+++ b/src/kernel/memory/mmap.c
@@ -0,0 +1,106 @@
+#include <memory/mmap.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <system.h>
+
+#define FRAME_SIZE 0x1000
+#define FRAME_COUNT (total_memory / 4)
+#define FRAME_TABLE_SIZE (FRAME_COUNT / 32)
+
+#define FREE 0x0
+#define USED 0x1
+
+void *kmalloc(u32 size);
+
+extern u32 kernel_end;
+u32 kernel_end_address = (u32)&kernel_end;
+
+u32 total_memory;
+
+u32 *frame_table;
+
+void *kmalloc(u32 size)
+{
+ void *ret;
+
+ ret = (void *)kernel_end_address;
+ kernel_end_address += size;
+
+ return ret;
+}
+
+// TODO: Efficiency
+void *kmalloc_frames(u32 num)
+{
+ u8 found;
+
+ for (u32 i = 0; i < FRAME_COUNT; i++) {
+ found = 1;
+ for (u32 j = 0; j < num; j++) {
+ if (mmap_index_check(i + j) == USED) {
+ found = 0;
+ break;
+ }
+ }
+ if (found) {
+ for (u32 j = 0; j < num; j++) {
+ mmap_index_set_used(i + j);
+ }
+ return (void *)(i * FRAME_SIZE);
+ }
+ }
+
+ warn("Not enough frames");
+ return NULL;
+}
+
+void kfree_frames(void *ptr, u32 num)
+{
+ u32 address = (u32)ptr;
+ u32 i = address;
+
+ while (i < address + (num * FRAME_SIZE)) {
+ mmap_address_set_free(address);
+ i += FRAME_SIZE;
+ }
+}
+
+u8 mmap_index_check(u32 n)
+{
+ return (frame_table[n / 32] >> (n % 32)) & 0x1;
+}
+
+void mmap_init(u32 size)
+{
+ total_memory = size;
+ frame_table = kmalloc(FRAME_TABLE_SIZE);
+}
+
+void mmap_init_finalize()
+{
+ // TODO: Efficiency
+ //memset(frame_table, 0xFF, (&kernel_end / FRAME_SIZE) / 8);
+ for (u32 i = 0; i < kernel_end_address; i += FRAME_SIZE) {
+ mmap_address_set_used(i);
+ }
+}
+
+void mmap_address_set_free(u32 address)
+{
+ frame_table[(address / FRAME_SIZE) / 32] &= ~(1 << ((address / FRAME_SIZE) % 32));
+}
+
+void mmap_address_set_used(u32 address)
+{
+ frame_table[(address / FRAME_SIZE) / 32] |= (1 << ((address / FRAME_SIZE) % 32));
+}
+
+void mmap_index_set_free(u32 n)
+{
+ frame_table[n / 32] &= ~(1 << (n % 32));
+}
+
+void mmap_index_set_used(u32 n)
+{
+ frame_table[n / 32] |= 1 << (n % 32);
+} \ No newline at end of file
diff --git a/src/kernel/memory/mmap.h b/src/kernel/memory/mmap.h
new file mode 100644
index 0000000..1de801f
--- /dev/null
+++ b/src/kernel/memory/mmap.h
@@ -0,0 +1,18 @@
+#ifndef MELVIX_MMAP
+#define MELVIX_MMAP
+
+#include <stdint.h>
+
+void *kmalloc_frames(u32 num);
+void kfree_frames(void *ptr, u32 num);
+
+u8 mmap_check(u32 n);
+void mmap_init(u32 size);
+void mmap_init_finalize();
+void mmap_address_set_free(u32 address);
+void mmap_address_set_used(u32 address);
+u8 mmap_index_check(u32 n);
+void mmap_index_set_free(u32 n);
+void mmap_index_set_used(u32 n);
+
+#endif \ No newline at end of file
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
index 0e2cea4..1d9f6b1 100644
--- a/src/kernel/memory/paging.c
+++ b/src/kernel/memory/paging.c
@@ -1,238 +1,109 @@
+#include <io/io.h>
#include <lib/lib.h>
-#include <memory/alloc.h>
+#include <memory/mmap.h>
#include <memory/paging.h>
#include <stdint.h>
#include <system.h>
-u32 kernel_page_directory[PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN)));
-u32 kernel_page_tables[PAGE_COUNT][PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN)));
-u32 *temp_dir[PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN)));
-
-u32 **page_directory __attribute__((aligned(PAGE_ALIGN)));
-
-void paging_init(u32 **dir)
-{
- //log("%d", paging_get_used_pages());
- for (u32 i = 0; i < PAGE_COUNT; i++) {
- dir[i] = kernel_page_tables[i];
- for (u32 j = 0; j < PAGE_COUNT; j++) {
- dir[i][j] = kernel_page_tables[i][j];
- }
- }
-}
-
-void paging_kernel_init()
-{
- for (u32 i = 0; i < PAGE_COUNT; i++)
- for (u32 j = 0; j < PAGE_COUNT; j++)
- kernel_page_tables[i][j] =
- ((j * PAGE_ALIGN) + (i * PAGE_SIZE)) | PT_RW | PT_USER;
-
- for (u32 i = 0; i < PAGE_COUNT; i++)
- kernel_page_directory[i] =
- ((u32)kernel_page_tables[i]) | PD_RW | PD_PRESENT | PD_USER;
-
- page_directory = temp_dir;
- for (u32 i = 0; i < PAGE_COUNT; i++) {
- page_directory[i] = kernel_page_tables[i];
- for (u32 j = 0; j < PAGE_COUNT; j++) {
- page_directory[i][j] = kernel_page_tables[i][j];
- }
- }
-}
+struct page_dir *kernel_page_directory;
void paging_install()
{
- paging_switch_directory((u32 **)kernel_page_directory);
- paging_kernel_init();
-
- if (!memory_init())
- paging_set_present(0, memory_get_all() >> 3);
- paging_set_used(0, ((u32)&kernel_end >> 12) + 1);
-
- paging_enable();
- log("Installed paging");
-
- // Test!
- u32 *a = malloc(PAGE_ALIGN);
- u32 *b = malloc(PAGE_ALIGN);
- free(b);
- free(a);
- u32 *c = malloc(2048);
- assert(a == c);
- c[42] = 0x4242;
- assert(c[42] == 0x4242);
- free(c);
- info("Malloc test succeeded!");
-}
+ memory_init();
-u32 **paging_make_directory()
-{
- /* u32 **dir = valloc(PAGE_COUNT * sizeof(*dir)); */
- /* dir[0] = malloc(PAGE_COUNT * PAGE_COUNT * sizeof(**dir)); */
- /* for (u32 i = 1; i < PAGE_COUNT; i++) */
- /* dir[i] = dir[0] + i * PAGE_COUNT; */
- u32 **dir = valloc(PAGE_COUNT * sizeof(*dir));
- for (u32 i = 0; i < PAGE_COUNT; i++)
- dir[i] = malloc(PAGE_COUNT + sizeof(**dir));
+ struct page_table *page_table;
+ page_table = kmalloc_frames(1);
+ memset(page_table, 0, sizeof(struct page_table));
for (u32 i = 0; i < PAGE_COUNT; i++) {
- dir[i] = kernel_page_directory[i];
- /* for (u32 j = 0; j < PAGE_COUNT; j++) { */
- /* dir[i][j] = (&kernel_page_directory[i])[j]; */
- /* } */
+ page_table->entries[i].present = 1;
+ page_table->entries[i].writable = 1;
+ page_table->entries[i].address = SHIFT(i * PAGE_SIZE);
}
- paging_switch_directory(dir);
- log("%d", 42);
+ kernel_page_directory = kmalloc_frames(1);
+ memset(kernel_page_directory, 0, sizeof(struct page_dir));
+ kernel_page_directory->entries[0].present = 1;
+ kernel_page_directory->entries[0].writable = 1;
+ kernel_page_directory->entries[0].address = SHIFT((u32)page_table);
- return dir;
-}
-
-void paging_remove_directory(u32 **dir)
-{
- // TODO: Fix freeing of directory by calculating aligned offset
- free(dir[0]);
- free(dir);
+ paging_switch_directory((u32)kernel_page_directory);
+ paging_enable();
+ info("Installed paging");
}
void paging_disable()
{
- u32 cr0;
- asm("mov %%cr0, %0" : "=r"(cr0));
+ u32 cr0 = cr0_get();
cr0 &= 0x7fffffff;
- asm("mov %0, %%cr0" ::"r"(cr0));
+ cr0_set(cr0);
paging_enabled = 0;
}
void paging_enable()
{
- u32 cr0;
- asm("mov %%cr0, %0" : "=r"(cr0));
+ u32 cr0 = cr0_get();
cr0 |= 0x80000000;
- asm("mov %0, %%cr0" ::"r"(cr0));
+ cr0_set(cr0);
paging_enabled = 1;
}
-void paging_switch_directory(u32 **dir)
-{
- page_directory = dir;
- asm("mov %0, %%cr3" ::"r"(dir));
-}
-
-void invlpg(u32 addr)
-{
- asm("invlpg (%0)" ::"r"(addr) : "memory");
-}
-
-void paging_map(u32 phy, u32 virt, u16 flags)
-{
- u32 pdi = virt >> 22;
- u32 pti = virt >> 12 & 0x03FF;
- page_directory[pdi][pti] = phy | flags;
- invlpg(virt);
-}
-
-void paging_map_user(u32 phy, u32 virt)
+void paging_switch_directory(u32 dir)
{
- u32 pdi = virt >> 22;
- /* u32 pti = virt >> 12 & 0x03FF; */
- for (int i = 0; i < 1024; i++) {
- page_directory[pdi][i] = phy | PT_RW | PT_PRESENT | PT_USER;
- phy += 4096;
- }
- invlpg(virt);
+ cr3_set(dir);
}
-u32 paging_get_phys(u32 virt)
+struct page_table_entry *paging_get_page(u32 address, struct page_dir *page_dir)
{
- u32 pdi = virt >> 22;
- u32 pti = (virt >> 12) & 0x03FF;
- return page_directory[pdi][pti] & 0xFFFFF000;
-}
+ struct page_table *page_table;
-u16 paging_get_flags(u32 virt)
-{
- u32 pdi = virt >> 22;
- u32 pti = (virt >> 12) & 0x03FF;
- return page_directory[pdi][pti] & 0xFFF;
-}
+ address /= PAGE_SIZE;
+ u32 n = address / PAGE_COUNT;
-void paging_set_flag_up(u32 virt, u32 count, u32 flag)
-{
- //debug("Setting flag %b for %d tables", flag, count);
- u32 page_n = virt / PAGE_ALIGN;
- for (u32 i = page_n; i < page_n + count; i++) {
- page_directory[i / PAGE_COUNT][i % PAGE_COUNT] |= flag;
- invlpg(i * PAGE_ALIGN);
- }
-}
+ if (page_dir->entries[n].present == 0) {
+ page_table = kmalloc_frames(1);
+ memset(page_table, 0, sizeof(struct page_table));
-void paging_set_flag_down(u32 virt, u32 count, u32 flag)
-{
- u32 page_n = virt / PAGE_ALIGN;
- for (u32 i = page_n; i < page_n + count; i++) {
- page_directory[i / PAGE_COUNT][i % PAGE_COUNT] &= ~flag;
- invlpg(i * PAGE_ALIGN);
+ page_dir->entries[n].address = SHIFT((u32)page_table);
+ page_dir->entries[n].present = 1;
+ page_dir->entries[n].writable = 1;
+ page_dir->entries[n].user = 1;
+ } else {
+ page_table = (void *)UNSHIFT(page_dir->entries[n].address);
}
-}
-void paging_set_present(u32 virt, u32 count)
-{
- paging_set_flag_up(virt, count, PT_PRESENT);
+ return &page_table->entries[address % PAGE_COUNT];
}
-void paging_set_absent(u32 virt, u32 count)
+void paging_frame_alloc(struct page_table_entry *page)
{
- paging_set_flag_down(virt, count, PT_PRESENT);
-}
+ void *ptr = kmalloc_frames(1);
-void paging_set_used(u32 virt, u32 count)
-{
- paging_set_flag_up(virt, count, PT_USED);
+ if (page->address != 0) {
+ warn("Page is already allocated");
+ return;
+ }
+ page->address = SHIFT((u32)ptr);
+ page->present = 1;
+ page->user = 1;
}
-void paging_set_free(u32 virt, u32 count)
+void paging_frame_free(struct page_table_entry *page)
{
- paging_set_flag_down(virt, count, PT_USED);
+ kfree_frames((void *)UNSHIFT(page->address), 1);
+ memset((void *)page, 0, sizeof(struct page_table_entry));
}
-u32 paging_find_pages(u32 count)
+struct page_dir *paging_make_dir()
{
- u32 continuous = 0;
- u32 start_dir = 0;
- u32 start_page = 0;
- for (u32 i = 0; i < PAGE_COUNT; i++) {
- for (u32 j = 0; j < PAGE_COUNT; j++) {
- if (!(page_directory[i][j] & PT_PRESENT) ||
- (page_directory[i][j] & PT_USED)) {
- continuous = 0;
- start_dir = i;
- start_page = j + 1;
- } else {
- if (++continuous == count)
- return (start_dir * PAGE_SIZE) + (start_page * PAGE_ALIGN);
- }
- }
- }
+ struct page_dir *ret = kmalloc_frames(1);
- panic("Out of memory!");
- return 0;
-}
+ memcpy(ret, kernel_page_directory, sizeof(struct page_dir));
-u32 paging_alloc_pages(u32 count)
-{
- u32 ptr = paging_find_pages(count);
- paging_set_used(ptr, count);
- return ptr;
+ return ret;
}
-u32 paging_get_used_pages()
+void paging_free_dir(struct page_dir *page_dir)
{
- u32 n = 0;
- for (u32 i = 0; i < PAGE_COUNT; i++)
- for (u32 j = 0; j < PAGE_COUNT; j++)
- if (page_directory[i][j] & PT_USED)
- n++;
- return n;
+ kfree_frames(page_dir, 1);
} \ No newline at end of file
diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h
index 29d584c..ac0dbfa 100644
--- a/src/kernel/memory/paging.h
+++ b/src/kernel/memory/paging.h
@@ -3,56 +3,58 @@
#include <stdint.h>
-#define PAGE_ALIGN 4096
+#define PAGE_SIZE 0x1000
#define PAGE_COUNT 1024
-#define PAGE_SIZE PAGE_ALIGN *PAGE_COUNT
-
-#define PD_PRESENT 1 << 0
-#define PD_RW 1 << 1
-#define PD_USER 1 << 2
-#define PD_WRITETHR 1 << 3
-#define PD_CACHE_D 1 << 4
-#define PD_ACCESSED 1 << 5
-#define PD_4M_PAGE 1 << 7
-
-#define PT_PRESENT 1 << 0
-#define PT_RW 1 << 1
-#define PT_USER 1 << 2
-#define PT_WRITETHR 1 << 3
-#define PT_CACHE_D 1 << 4
-#define PT_ACCESSED 1 << 5
-#define PT_DIRTY 1 << 6
-#define PT_GLOBAL 1 << 8
-#define PT_USED 1 << 9
-
-u32 **page_directory __attribute__((aligned(PAGE_ALIGN)));
-u32 kernel_page_tables[PAGE_COUNT][PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN)));
+#define SHIFT(address) ((address) >> 12)
+#define UNSHIFT(address) ((address) << 12)
+
int paging_enabled;
+struct page_table_entry {
+ u32 present : 1;
+ u32 writable : 1;
+ u32 user : 1;
+ u32 write_through : 1;
+ u32 cache_disable : 1;
+ u32 accessed : 1;
+ u32 dirty : 1;
+ u32 attribute : 1;
+ u32 global : 1;
+ u32 available : 3;
+ u32 address : 20;
+} __attribute__((packed));
+
+struct page_table {
+ struct page_table_entry entries[PAGE_COUNT];
+};
+
+struct page_dir_entry {
+ u32 present : 1;
+ u32 writable : 1;
+ u32 user : 1;
+ u32 write_through : 1;
+ u32 cache_disable : 1;
+ u32 accessed : 1;
+ u32 reserved : 1;
+ u32 page_size : 1;
+ u32 global : 1;
+ u32 available : 3;
+ u32 address : 20;
+} __attribute__((packed));
+
+struct page_dir {
+ struct page_dir_entry entries[PAGE_COUNT];
+};
+
void paging_install();
void paging_enable();
void paging_disable();
+void paging_switch_directory(u32 dir);
-u32 **paging_make_directory();
-void paging_remove_directory(u32 **dir);
-void paging_switch_directory(u32 **dir);
-
-void paging_map(u32 phy, u32 virt, u16 flags);
-void paging_map_user(u32 phy, u32 virt);
-u32 paging_get_phys(u32 virt);
-u16 paging_get_flags(u32 virt);
-u32 paging_get_used_pages();
-
-void paging_set_flags(u32 virt, u32 count, u16 flags);
-void paging_set_flag_up(u32 virt, u32 count, u32 flag);
-void paging_set_flag_down(u32 virt, u32 count, u32 flag);
-void paging_set_present(u32 virt, u32 count);
-void paging_set_absent(u32 virt, u32 count);
-void paging_set_used(u32 virt, u32 count);
-void paging_set_free(u32 virt, u32 count);
-void paging_set_user(u32 virt, u32 count);
-
-u32 paging_find_pages(u32 count);
-u32 paging_alloc_pages(u32 count);
+struct page_table_entry *paging_get_page(u32 address, struct page_dir *page_dir);
+void paging_frame_alloc(struct page_table_entry *page);
+void paging_frame_free(struct page_table_entry *page);
+struct page_dir *paging_make_dir();
+void paging_free_dir();
#endif \ No newline at end of file
diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c
index 5f70bc7..0b13b6b 100644
--- a/src/kernel/tasks/process.c
+++ b/src/kernel/tasks/process.c
@@ -182,7 +182,7 @@ struct process *process_make_new()
proc->registers.cs = 0x1B;
proc->registers.ds = 0x23;
proc->registers.ss = 0x23;
- proc->cr3 = paging_make_directory();
+ proc->cr3 = paging_make_dir();
proc->brk = 0x50000000;
proc->pid = pid++;
return proc;
diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h
index ef66c2a..5c72e64 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;