aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-02-16 17:29:19 +0100
committerMarvin Borner2020-02-16 17:29:50 +0100
commit45184af20936cb889b658e69e00a0bb3d522757f (patch)
tree4b6c3408e526fe733ccfa960726c37e70dc6f989
parentf5b995586e28f7db426f4707a4348dc067df41c0 (diff)
Revert to good ol' paging
-rw-r--r--src/kernel/fs/ata_pio.c2
-rw-r--r--src/kernel/fs/install.c2
-rw-r--r--src/kernel/fs/iso9660/iso9660.c2
-rw-r--r--src/kernel/fs/load.c4
-rw-r--r--src/kernel/fs/marfs/directory.c2
-rw-r--r--src/kernel/fs/marfs/new_file.c2
-rw-r--r--src/kernel/fs/marfs/read_whole_file.c2
-rw-r--r--src/kernel/fs/marfs/sectorlevel.c2
-rw-r--r--src/kernel/gdt/gdt.c2
-rw-r--r--src/kernel/graphics/vesa.c19
-rw-r--r--src/kernel/input/ps2/keyboard.c2
-rw-r--r--src/kernel/lib/stdio/debug.c2
-rw-r--r--src/kernel/lib/stdio/vprintf.c2
-rw-r--r--src/kernel/lib/stdlib/htoa.c2
-rw-r--r--src/kernel/lib/stdlib/itoa.c2
-rw-r--r--src/kernel/lib/string/strdup.c2
-rw-r--r--src/kernel/memory/alloc.c457
-rw-r--r--src/kernel/memory/alloc.h24
-rw-r--r--src/kernel/memory/kheap.c311
-rw-r--r--src/kernel/memory/kheap.h52
-rw-r--r--src/kernel/memory/ordered_array.c68
-rw-r--r--src/kernel/memory/ordered_array.h31
-rw-r--r--src/kernel/memory/paging.c283
-rw-r--r--src/kernel/memory/paging.h77
-rw-r--r--src/kernel/net/rtl8139.c2
-rw-r--r--src/kernel/syscall.c20
-rw-r--r--src/kernel/syscall.h80
-rw-r--r--src/kernel/syscall/actions/sys_free.c2
-rw-r--r--src/kernel/syscall/actions/sys_get_pointers.c2
-rw-r--r--src/kernel/tasks/task.c35
-rw-r--r--src/kernel/tasks/task.h4
31 files changed, 807 insertions, 692 deletions
diff --git a/src/kernel/fs/ata_pio.c b/src/kernel/fs/ata_pio.c
index fef3a32..b6dcdcc 100644
--- a/src/kernel/fs/ata_pio.c
+++ b/src/kernel/fs/ata_pio.c
@@ -1,6 +1,6 @@
#include <kernel/io/io.h>
#include <kernel/fs/ata_pio.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
struct ata_interface *new_ata(uint8_t master, uint16_t port_base)
{
diff --git a/src/kernel/fs/install.c b/src/kernel/fs/install.c
index f7e2489..84d74fd 100644
--- a/src/kernel/fs/install.c
+++ b/src/kernel/fs/install.c
@@ -6,7 +6,7 @@
#include <kernel/acpi/acpi.h>
#include <kernel/lib/stdio.h>
#include <kernel/timer/timer.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
#include <kernel/fs/load.h>
void install_melvix()
diff --git a/src/kernel/fs/iso9660/iso9660.c b/src/kernel/fs/iso9660/iso9660.c
index 2262408..81ef18a 100644
--- a/src/kernel/fs/iso9660/iso9660.c
+++ b/src/kernel/fs/iso9660/iso9660.c
@@ -2,7 +2,7 @@
#include <kernel/fs/atapi_pio.h>
#include <kernel/fs/iso9660/iso9660.h>
#include <kernel/lib/stdlib.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
struct iso9660_entity *ISO9660_get(char **dirs, uint8_t dirs_sz)
{
diff --git a/src/kernel/fs/load.c b/src/kernel/fs/load.c
index be7d5b8..cd422d0 100644
--- a/src/kernel/fs/load.c
+++ b/src/kernel/fs/load.c
@@ -4,11 +4,11 @@
#include <kernel/fs/atapi_pio.h>
#include <kernel/system.h>
#include <kernel/fs/iso9660/iso9660.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
void load_binaries()
{
- userspace = kmalloc(10000);
+ userspace = (uint32_t) kmalloc(10000);
font = (struct font *) kmalloc(100000);; // High quality shit
uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000));
diff --git a/src/kernel/fs/marfs/directory.c b/src/kernel/fs/marfs/directory.c
index dce92b1..fd8ecd6 100644
--- a/src/kernel/fs/marfs/directory.c
+++ b/src/kernel/fs/marfs/directory.c
@@ -2,7 +2,7 @@
#include <kernel/fs/ata_pio.h>
#include <kernel/lib/stdlib.h>
#include <kernel/fs/marfs/marfs.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
uint32_t marfs_new_dir(uint32_t uid)
{
diff --git a/src/kernel/fs/marfs/new_file.c b/src/kernel/fs/marfs/new_file.c
index ab1c241..8f85ffa 100644
--- a/src/kernel/fs/marfs/new_file.c
+++ b/src/kernel/fs/marfs/new_file.c
@@ -1,7 +1,7 @@
#include <stdint.h>
#include <kernel/fs/ata_pio.h>
#include <kernel/fs/marfs/marfs.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
static uint8_t last_max_level = 0;
diff --git a/src/kernel/fs/marfs/read_whole_file.c b/src/kernel/fs/marfs/read_whole_file.c
index 4507f66..f530441 100644
--- a/src/kernel/fs/marfs/read_whole_file.c
+++ b/src/kernel/fs/marfs/read_whole_file.c
@@ -1,7 +1,7 @@
#include <stdint.h>
#include <kernel/fs/ata_pio.h>
#include <kernel/fs/marfs/marfs.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
static uint8_t last_max_level = 0;
diff --git a/src/kernel/fs/marfs/sectorlevel.c b/src/kernel/fs/marfs/sectorlevel.c
index 8302054..96a24ba 100644
--- a/src/kernel/fs/marfs/sectorlevel.c
+++ b/src/kernel/fs/marfs/sectorlevel.c
@@ -1,7 +1,7 @@
#include <stdint.h>
#include <kernel/fs/ata_pio.h>
#include <kernel/fs/marfs/marfs.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
uint8_t marfs_init(struct ata_interface *_interface)
{
diff --git a/src/kernel/gdt/gdt.c b/src/kernel/gdt/gdt.c
index 5b43025..8d0b5ff 100644
--- a/src/kernel/gdt/gdt.c
+++ b/src/kernel/gdt/gdt.c
@@ -2,7 +2,7 @@
#include <kernel/gdt/gdt.h>
#include <kernel/system.h>
#include <kernel/lib/lib.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
struct gdt_entry {
unsigned short limit_low;
diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c
index eaca94a..2e14705 100644
--- a/src/kernel/graphics/vesa.c
+++ b/src/kernel/graphics/vesa.c
@@ -1,14 +1,11 @@
#include <kernel/graphics/vesa.h>
#include <kernel/fs/load.h>
-#include <kernel/lib/lib.h>
#include <kernel/system.h>
#include <kernel/lib/stdlib.h>
#include <kernel/lib/stdio.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
#include <kernel/memory/paging.h>
-extern page_directory_t *current_directory;
-
void switch_to_vga()
{
serial_printf("Force switch to VGA!");
@@ -182,16 +179,10 @@ void set_optimal_resolution()
vbe_set_mode(highest);
uint32_t fb_size = vbe_width * vbe_height * vbe_bpl;
- cursor_buffer = (unsigned char *) kmalloc(fb_size);
- uint32_t j = (uint32_t) fb;
- while ((unsigned char *) j < fb + fb_size) {
- paging_set_frame(j);
- page_t *page = paging_get_page(j, 1, current_directory);
- page->present = 1;
- page->rw = 1;
- page->user = 1;
- page->frame = j / 0x1000;
- j += 0x1000;
+ cursor_buffer = kmalloc(fb_size);
+ for (uint32_t z = 0; z < fb_size; z += 4096) {
+ paging_map((uint32_t) fb + z, (uint32_t) fb + z, PT_PRESENT | PT_RW | PT_USED);
+ paging_map((uint32_t) cursor_buffer + z, (uint32_t) cursor_buffer + z, PT_PRESENT | PT_RW | PT_USED);
}
serial_printf("0x%x", fb);
diff --git a/src/kernel/input/ps2/keyboard.c b/src/kernel/input/ps2/keyboard.c
index 3c4ef0a..6721193 100644
--- a/src/kernel/input/ps2/keyboard.c
+++ b/src/kernel/input/ps2/keyboard.c
@@ -3,7 +3,7 @@
#include <kernel/graphics/vesa.h>
#include <kernel/input/input.h>
#include <kernel/lib/string.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
int shift_pressed;
int control_pressed;
diff --git a/src/kernel/lib/stdio/debug.c b/src/kernel/lib/stdio/debug.c
index f670588..cd042f4 100644
--- a/src/kernel/lib/stdio/debug.c
+++ b/src/kernel/lib/stdio/debug.c
@@ -3,7 +3,7 @@
#include <kernel/lib/string.h>
#include <kernel/lib/stdlib.h>
#include <kernel/io/io.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
void _write_serial(const char *data)
{
diff --git a/src/kernel/lib/stdio/vprintf.c b/src/kernel/lib/stdio/vprintf.c
index 72f3917..af8e47f 100644
--- a/src/kernel/lib/stdio/vprintf.c
+++ b/src/kernel/lib/stdio/vprintf.c
@@ -3,7 +3,7 @@
#include <kernel/lib/stdio.h>
#include <kernel/lib/string.h>
#include <kernel/lib/stdlib.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
void _writes(const char *data)
{
diff --git a/src/kernel/lib/stdlib/htoa.c b/src/kernel/lib/stdlib/htoa.c
index ccb01f1..49ca703 100644
--- a/src/kernel/lib/stdlib/htoa.c
+++ b/src/kernel/lib/stdlib/htoa.c
@@ -1,6 +1,6 @@
#include <stdint.h>
#include <kernel/lib/string.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
static const char HTOA_TABLE[] = "0123456789ABCDEF";
diff --git a/src/kernel/lib/stdlib/itoa.c b/src/kernel/lib/stdlib/itoa.c
index ea03aa2..dec75bf 100644
--- a/src/kernel/lib/stdlib/itoa.c
+++ b/src/kernel/lib/stdlib/itoa.c
@@ -1,7 +1,7 @@
#include <kernel/lib/math.h>
#include <stdint.h>
#include <kernel/lib/string.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
#include <kernel/memory/paging.h>
static const char ITOA_TABLE[] = "0123456789";
diff --git a/src/kernel/lib/string/strdup.c b/src/kernel/lib/string/strdup.c
index 7ddbf74..e59dff4 100644
--- a/src/kernel/lib/string/strdup.c
+++ b/src/kernel/lib/string/strdup.c
@@ -1,5 +1,5 @@
#include <kernel/lib/string.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
char *strdup(const char *orig)
{
diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c
new file mode 100644
index 0000000..cffcace
--- /dev/null
+++ b/src/kernel/memory/alloc.c
@@ -0,0 +1,457 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <kernel/memory/paging.h>
+#include <kernel/memory/alloc.h>
+
+int liballoc_lock()
+{
+ // asm ("cli");
+ return 0;
+}
+
+int liballoc_unlock()
+{
+ // asm ("sti");
+ return 0;
+}
+
+void *liballoc_alloc(size_t p)
+{
+ uint32_t ptr = paging_alloc_pages((uint32_t) p);
+ return (void *) ptr;
+}
+
+int liballoc_free(void *ptr, size_t p)
+{
+ paging_set_free((uint32_t) ptr, (uint32_t) p);
+ return 0;
+}
+
+#define ALIGNMENT 16ul
+#define ALIGN_TYPE char
+#define ALIGN_INFO sizeof(ALIGN_TYPE) * 16
+#define USE_CASE1
+#define USE_CASE2
+#define USE_CASE3
+#define USE_CASE4
+#define USE_CASE5
+
+#define ALIGN(ptr) \
+ if ( ALIGNMENT > 1 ) { \
+ uintptr_t diff; \
+ ptr = (void*) ((uintptr_t) ptr + ALIGN_INFO); \
+ diff = (uintptr_t) ptr & (ALIGNMENT - 1); \
+ if (diff != 0) { \
+ diff = ALIGNMENT - diff; \
+ ptr = (void*) ((uintptr_t) ptr + diff); \
+ } \
+ *((ALIGN_TYPE*) ((uintptr_t) ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \
+ }
+
+#define UNALIGN(ptr) \
+ if (ALIGNMENT > 1) { \
+ uintptr_t diff = *((ALIGN_TYPE*) ((uintptr_t) ptr - ALIGN_INFO)); \
+ if (diff < (ALIGNMENT + ALIGN_INFO)) { \
+ ptr = (void*) ((uintptr_t) ptr - diff); \
+ } \
+ }
+
+#define LIBALLOC_MAGIC 0x900df00d
+#define LIBALLOC_DEAD 0xbaadf00d
+
+struct liballoc_major {
+ struct liballoc_major *prev;
+ struct liballoc_major *next;
+ unsigned int pages;
+ unsigned int size;
+ unsigned int usage;
+ struct liballoc_minor *first;
+};
+
+struct liballoc_minor {
+ struct liballoc_minor *prev;
+ struct liballoc_minor *next;
+ struct liballoc_major *block;
+ unsigned int magic;
+ unsigned int size;
+ unsigned int req_size;
+};
+
+static struct liballoc_major *l_memRoot = NULL;
+static struct liballoc_major *l_bestBet = NULL;
+
+static unsigned int l_pageSize = 4096;
+static unsigned int l_pageCount = 16;
+static unsigned long long l_allocated = 0;
+static unsigned long long l_inuse = 0;
+
+static long long l_warningCount = 0;
+static long long l_errorCount = 0;
+static long long l_possibleOverruns = 0;
+
+static void *liballoc_memset(void *s, int c, size_t n)
+{
+ unsigned int i;
+ for (i = 0; i < n; i++)
+ ((char *) s)[i] = c;
+
+ return s;
+}
+
+static void *liballoc_memcpy(void *s1, const void *s2, size_t n)
+{
+ char *cdest;
+ char *csrc;
+ unsigned int *ldest = (unsigned int *) s1;
+ unsigned int *lsrc = (unsigned int *) s2;
+
+ while (n >= sizeof(unsigned int)) {
+ *ldest++ = *lsrc++;
+ n -= sizeof(unsigned int);
+ }
+
+ cdest = (char *) ldest;
+ csrc = (char *) lsrc;
+
+ while (n > 0) {
+ *cdest++ = *csrc++;
+ n -= 1;
+ }
+ return s1;
+}
+
+static struct liballoc_major *allocate_new_page(unsigned int size)
+{
+ unsigned int st;
+ struct liballoc_major *maj;
+
+ st = size + sizeof(struct liballoc_major);
+ st += sizeof(struct liballoc_minor);
+
+ if ((st % l_pageSize) == 0)
+ st = st / (l_pageSize);
+ else
+ st = st / (l_pageSize) + 1;
+
+ if (st < l_pageCount) st = l_pageCount;
+
+ maj = (struct liballoc_major *) liballoc_alloc(st);
+
+ if (maj == NULL) {
+ l_warningCount += 1;
+ return NULL;
+ }
+
+ maj->prev = NULL;
+ maj->next = NULL;
+ maj->pages = st;
+ maj->size = st * l_pageSize;
+ maj->usage = sizeof(struct liballoc_major);
+ maj->first = NULL;
+
+ l_allocated += maj->size;
+
+ return maj;
+}
+
+void *PREFIX(malloc)(size_t req_size)
+{
+ int startedBet = 0;
+ unsigned long long bestSize = 0;
+ void *p = NULL;
+ uintptr_t diff;
+ struct liballoc_major *maj;
+ struct liballoc_minor *min;
+ struct liballoc_minor *new_min;
+ unsigned long size = req_size;
+
+ if (ALIGNMENT > 1) {
+ size += ALIGNMENT + ALIGN_INFO;
+ }
+
+ liballoc_lock();
+
+ if (size == 0) {
+ l_warningCount += 1;
+ liballoc_unlock();
+ return PREFIX(malloc)(1);
+ }
+
+ if (l_memRoot == NULL) {
+ l_memRoot = allocate_new_page(size);
+ if (l_memRoot == NULL) {
+ liballoc_unlock();
+ return NULL;
+ }
+ }
+
+ maj = l_memRoot;
+ startedBet = 0;
+
+ if (l_bestBet != NULL) {
+ bestSize = l_bestBet->size - l_bestBet->usage;
+
+ if (bestSize > (size + sizeof(struct liballoc_minor))) {
+ maj = l_bestBet;
+ startedBet = 1;
+ }
+ }
+
+ while (maj != NULL) {
+ diff = maj->size - maj->usage;
+ if (bestSize < diff) {
+ l_bestBet = maj;
+ bestSize = diff;
+ }
+
+#ifdef USE_CASE1
+ if (diff < (size + sizeof(struct liballoc_minor))) {
+ if (maj->next != NULL) {
+ maj = maj->next;
+ continue;
+ }
+
+ if (startedBet == 1) {
+ maj = l_memRoot;
+ startedBet = 0;
+ continue;
+ }
+
+ maj->next = allocate_new_page(size);
+ if (maj->next == NULL) break;
+ maj->next->prev = maj;
+ maj = maj->next;
+ }
+#endif
+
+#ifdef USE_CASE2
+ if (maj->first == NULL) {
+ maj->first = (struct liballoc_minor *) ((uintptr_t) maj + sizeof(struct liballoc_major));
+
+ maj->first->magic = LIBALLOC_MAGIC;
+ maj->first->prev = NULL;
+ maj->first->next = NULL;
+ maj->first->block = maj;
+ maj->first->size = size;
+ maj->first->req_size = req_size;
+ maj->usage += size + sizeof(struct liballoc_minor);
+ l_inuse += size;
+ p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor));
+ ALIGN(p);
+ liballoc_unlock();
+ return p;
+ }
+#endif
+
+#ifdef USE_CASE3
+ diff = (uintptr_t) (maj->first);
+ diff -= (uintptr_t) maj;
+ diff -= sizeof(struct liballoc_major);
+
+ if (diff >= (size + sizeof(struct liballoc_minor))) {
+ maj->first->prev = (struct liballoc_minor *) ((uintptr_t) maj + sizeof(struct liballoc_major));
+ maj->first->prev->next = maj->first;
+ maj->first = maj->first->prev;
+ maj->first->magic = LIBALLOC_MAGIC;
+ maj->first->prev = NULL;
+ maj->first->block = maj;
+ maj->first->size = size;
+ maj->first->req_size = req_size;
+ maj->usage += size + sizeof(struct liballoc_minor);
+ l_inuse += size;
+ p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor));
+ ALIGN(p);
+ liballoc_unlock();
+ return p;
+ }
+#endif
+
+#ifdef USE_CASE4
+ min = maj->first;
+
+ while (min != NULL) {
+ if (min->next == NULL) {
+ diff = (uintptr_t) (maj) + maj->size;
+ diff -= (uintptr_t) min;
+ diff -= sizeof(struct liballoc_minor);
+ diff -= min->size;
+ if (diff >= (size + sizeof(struct liballoc_minor))) {
+ min->next = (struct liballoc_minor *) ((uintptr_t) min + sizeof(struct liballoc_minor) + min->size);
+ min->next->prev = min;
+ min = min->next;
+ min->next = NULL;
+ min->magic = LIBALLOC_MAGIC;
+ min->block = maj;
+ min->size = size;
+ min->req_size = req_size;
+ maj->usage += size + sizeof(struct liballoc_minor);
+ l_inuse += size;
+ p = (void *) ((uintptr_t) min + sizeof(struct liballoc_minor));
+ ALIGN(p);
+ liballoc_unlock();
+ return p;
+ }
+ }
+
+ if (min->next != NULL) {
+ diff = (uintptr_t) (min->next);
+ diff -= (uintptr_t) min;
+ diff -= sizeof(struct liballoc_minor);
+ diff -= min->size;
+
+ if (diff >= (size + sizeof(struct liballoc_minor))) {
+ new_min = (struct liballoc_minor *) ((uintptr_t) min + sizeof(struct liballoc_minor) + min->size);
+ new_min->magic = LIBALLOC_MAGIC;
+ new_min->next = min->next;
+ new_min->prev = min;
+ new_min->size = size;
+ new_min->req_size = req_size;
+ new_min->block = maj;
+ min->next->prev = new_min;
+ min->next = new_min;
+ maj->usage += size + sizeof(struct liballoc_minor);
+ l_inuse += size;
+ p = (void *) ((uintptr_t) new_min + sizeof(struct liballoc_minor));
+ ALIGN(p);
+ liballoc_unlock();
+ return p;
+ }
+ }
+
+ min = min->next;
+ }
+#endif
+
+#ifdef USE_CASE5
+ if (maj->next == NULL) {
+ if (startedBet == 1) {
+ maj = l_memRoot;
+ startedBet = 0;
+ continue;
+ }
+ maj->next = allocate_new_page(size);
+ if (maj->next == NULL) break;
+ maj->next->prev = maj;
+ }
+#endif
+ maj = maj->next;
+ }
+
+ liballoc_unlock();
+
+ return NULL;
+}
+
+void PREFIX(free)(void *ptr)
+{
+ struct liballoc_minor *min;
+ struct liballoc_major *maj;
+
+ if (ptr == NULL) {
+ l_warningCount += 1;
+ return;
+ }
+
+ UNALIGN(ptr);
+ liballoc_lock();
+
+ min = (struct liballoc_minor *) ((uintptr_t) ptr - sizeof(struct liballoc_minor));
+
+ if (min->magic != LIBALLOC_MAGIC) {
+ l_errorCount += 1;
+
+ if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
+ ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
+ ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) {
+ l_possibleOverruns += 1;
+ }
+
+ liballoc_unlock();
+ return;
+ }
+
+ maj = min->block;
+ l_inuse -= min->size;
+ maj->usage -= (min->size + sizeof(struct liballoc_minor));
+ min->magic = LIBALLOC_DEAD;
+
+ if (min->next != NULL) min->next->prev = min->prev;
+ if (min->prev != NULL) min->prev->next = min->next;
+ if (min->prev == NULL) maj->first = min->next;
+ if (maj->first == NULL) {
+ if (l_memRoot == maj) l_memRoot = maj->next;
+ if (l_bestBet == maj) l_bestBet = NULL;
+ if (maj->prev != NULL) maj->prev->next = maj->next;
+ if (maj->next != NULL) maj->next->prev = maj->prev;
+ l_allocated -= maj->size;
+ liballoc_free(maj, maj->pages);
+ } else {
+ if (l_bestBet != NULL) {
+ int bestSize = l_bestBet->size - l_bestBet->usage;
+ int majSize = maj->size - maj->usage;
+ if (majSize > bestSize) l_bestBet = maj;
+ }
+ }
+ liballoc_unlock();
+}
+
+void *PREFIX(calloc)(size_t nobj, size_t size)
+{
+ int real_size;
+ void *p;
+
+ real_size = nobj * size;
+
+ p = PREFIX(malloc)(real_size);
+
+ liballoc_memset(p, 0, real_size);
+
+ return p;
+}
+
+void *PREFIX(realloc)(void *p, size_t size)
+{
+ void *ptr;
+ struct liballoc_minor *min;
+ unsigned int real_size;
+
+ if (size == 0) {
+ PREFIX(free)(p);
+ return NULL;
+ }
+
+ if (p == NULL) return PREFIX(malloc)(size);
+
+ ptr = p;
+ UNALIGN(ptr);
+ liballoc_lock();
+ min = (struct liballoc_minor *) ((uintptr_t) ptr - sizeof(struct liballoc_minor));
+
+ if (min->magic != LIBALLOC_MAGIC) {
+ l_errorCount += 1;
+ if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
+ ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
+ ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) {
+ l_possibleOverruns += 1;
+ }
+
+ liballoc_unlock();
+ return NULL;
+ }
+
+ real_size = min->req_size;
+
+ if (real_size >= size) {
+ min->req_size = size;
+ liballoc_unlock();
+ return p;
+ }
+
+ liballoc_unlock();
+
+ ptr = PREFIX(malloc)(size);
+ liballoc_memcpy(ptr, p, real_size);
+ PREFIX(free)(p);
+
+ return ptr;
+} \ No newline at end of file
diff --git a/src/kernel/memory/alloc.h b/src/kernel/memory/alloc.h
new file mode 100644
index 0000000..1f454b9
--- /dev/null
+++ b/src/kernel/memory/alloc.h
@@ -0,0 +1,24 @@
+#ifndef MELVIX_ALLOC_H
+#define MELVIX_ALLOC_H
+
+#include <stddef.h>
+
+#define PREFIX(func) k ## func
+
+int liballoc_lock();
+
+int liballoc_unlock();
+
+void *liballoc_alloc(size_t);
+
+int liballoc_free(void *, size_t);
+
+void *PREFIX(malloc)(size_t);
+
+void *PREFIX(realloc)(void *, size_t);
+
+void *PREFIX(calloc)(size_t, size_t);
+
+void PREFIX(free)(void *);
+
+#endif \ No newline at end of file
diff --git a/src/kernel/memory/kheap.c b/src/kernel/memory/kheap.c
deleted file mode 100644
index 40551bc..0000000
--- a/src/kernel/memory/kheap.c
+++ /dev/null
@@ -1,311 +0,0 @@
-#include <stdint.h>
-#include <kernel/memory/kheap.h>
-#include <kernel/memory/paging.h>
-#include <kernel/system.h>
-
-uint32_t placement_address = (uint32_t) &ASM_KERNEL_END;
-extern page_directory_t *kernel_directory;
-heap_t *kheap = 0;
-
-uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys)
-{
- if (kheap != 0) {
- void *addr = alloc(sz, (uint8_t) align, kheap);
- if (phys != 0) {
- page_t *page = paging_get_page((uint32_t) addr, 0, kernel_directory);
- *phys = page->frame * 0x1000 + ((uint32_t) addr & 0xFFF);
- }
- return (uint32_t) addr;
- } else {
- if (align == 1 && (placement_address & 0xFFFFF000)) {
- placement_address &= 0xFFFFF000;
- placement_address += 0x1000;
- }
- if (phys) {
- *phys = placement_address;
- }
- uint32_t tmp = placement_address;
- placement_address += sz;
- return tmp;
- }
-}
-
-void kfree(void *p)
-{
- free(p, kheap);
-}
-
-uint32_t kmalloc_a(uint32_t sz)
-{
- return kmalloc_int(sz, 1, 0);
-}
-
-uint32_t kmalloc_p(uint32_t sz, uint32_t *phys)
-{
- return kmalloc_int(sz, 0, phys);
-}
-
-uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys)
-{
- return kmalloc_int(sz, 1, phys);
-}
-
-uint32_t kmalloc(uint32_t sz)
-{
- return kmalloc_int(sz, 0, 0);
-}
-
-static void expand(uint32_t new_size, heap_t *heap)
-{
- assert(new_size > heap->end_address - heap->start_address);
-
- if ((new_size & 0xFFFFF000) != 0) {
- new_size &= 0xFFFFF000;
- new_size += 0x1000;
- }
-
- assert(heap->start_address + new_size <= heap->max_address);
-
- uint32_t old_size = heap->end_address - heap->start_address;
-
- uint32_t i = old_size;
- while (i < new_size) {
- paging_alloc_frame(paging_get_page(heap->start_address + i, 1, kernel_directory),
- (heap->supervisor) ? 1 : 0, (heap->readonly) ? 0 : 1);
- i += 0x1000;
- }
- heap->end_address = heap->start_address + new_size;
-}
-
-static uint32_t contract(uint32_t new_size, heap_t *heap)
-{
- assert(new_size < heap->end_address - heap->start_address);
-
- if (new_size & 0x1000) {
- new_size &= 0x1000;
- new_size += 0x1000;
- }
-
- if (new_size < HEAP_MIN_SIZE)
- new_size = HEAP_MIN_SIZE;
-
- uint32_t old_size = heap->end_address - heap->start_address;
- uint32_t i = old_size - 0x1000;
- while (new_size < i) {
- paging_free_frame(paging_get_page(heap->start_address + i, 0, kernel_directory));
- i -= 0x1000;
- }
-
- heap->end_address = heap->start_address + new_size;
- return new_size;
-}
-
-static int32_t find_smallest_hole(uint32_t size, uint8_t page_align, heap_t *heap)
-{
- uint32_t iterator = 0;
- while (iterator < heap->index.size) {
- header_t *header = (header_t *) lookup_ordered_array(iterator, &heap->index);
- if (page_align > 0) {
- uint32_t location = (uint32_t) header;
- int32_t offset = 0;
- if (((location + sizeof(header_t)) & 0xFFFFF000) != 0)
- offset = 0x1000 - (location + sizeof(header_t)) % 0x1000;
- int32_t hole_size = (int32_t) header->size - offset;
- if (hole_size >= (int32_t) size)
- break;
- } else if (header->size >= size)
- break;
- iterator++;
- }
- if (iterator == heap->index.size)
- return -1;
- else
- return iterator;
-}
-
-static int8_t header_t_less_than(void *a, void *b)
-{
- return (int8_t) ((((header_t *) a)->size < ((header_t *) b)->size) ? 1 : 0);
-}
-
-heap_t *create_heap(uint32_t start, uint32_t end_addr, uint32_t max, uint8_t supervisor, uint8_t readonly)
-{
- heap_t *heap = (heap_t *) kmalloc(sizeof(heap_t));
-
- assert(start % 0x1000 == 0);
- assert(end_addr % 0x1000 == 0);
-
- heap->index = place_ordered_array((void *) start, HEAP_INDEX_SIZE, &header_t_less_than);
-
- start += sizeof(type_t) * HEAP_INDEX_SIZE;
-
- if ((start & 0xFFFFF000) != 0) {
- start &= 0xFFFFF000;
- start += 0x1000;
- }
-
- heap->start_address = start;
- heap->end_address = end_addr;
- heap->max_address = max;
- heap->supervisor = supervisor;
- heap->readonly = readonly;
-
- header_t *hole = (header_t *) start;
- hole->size = end_addr - start;
- hole->magic = HEAP_MAGIC;
- hole->is_hole = 1;
- insert_ordered_array((void *) hole, &heap->index);
-
- return heap;
-}
-
-void *alloc(uint32_t size, uint8_t page_align, heap_t *heap)
-{
- uint32_t new_size = size + sizeof(header_t) + sizeof(footer_t);
- int32_t iterator = find_smallest_hole(new_size, page_align, heap);
-
- if (iterator == -1) {
- uint32_t old_length = heap->end_address - heap->start_address;
- uint32_t old_end_address = heap->end_address;
-
- expand(old_length + new_size, heap);
- uint32_t new_length = heap->end_address - heap->start_address;
-
- iterator = 0;
- uint32_t idx = (uint32_t) -1;
- uint32_t value = 0x0;
- while ((uint32_t) iterator < heap->index.size) {
- uint32_t tmp = (uint32_t) lookup_ordered_array((uint32_t) iterator, &heap->index);
- if (tmp > value) {
- value = tmp;
- idx = (uint32_t) iterator;
- }
- iterator++;
- }
-
- if ((int) idx == -1) {
- header_t *header = (header_t *) old_end_address;
- header->magic = HEAP_MAGIC;
- header->size = new_length - old_length;
- header->is_hole = 1;
- footer_t *footer = (footer_t *) (old_end_address + header->size - sizeof(footer_t));
- footer->magic = HEAP_MAGIC;
- footer->header = header;
- insert_ordered_array((void *) header, &heap->index);
- } else {
- header_t *header = lookup_ordered_array(idx, &heap->index);
- header->size += new_length - old_length;
- footer_t *footer = (footer_t *) ((uint32_t) header + header->size - sizeof(footer_t));
- footer->header = header;
- footer->magic = HEAP_MAGIC;
- }
- return alloc(size, page_align, heap);
- }
-
- header_t *orig_hole_header = (header_t *) lookup_ordered_array((uint32_t) iterator, &heap->index);
- uint32_t orig_hole_pos = (uint32_t) orig_hole_header;
- uint32_t orig_hole_size = orig_hole_header->size;
- if (orig_hole_size - new_size < sizeof(header_t) + sizeof(footer_t)) {
- size += orig_hole_size - new_size;
- new_size = orig_hole_size;
- }
-
- if (page_align && orig_hole_pos & 0xFFFFF000) {
- uint32_t new_location = orig_hole_pos + 0x1000 - (orig_hole_pos & 0xFFF) - sizeof(header_t);
- header_t *hole_header = (header_t *) orig_hole_pos;
- hole_header->size = 0x1000 - (orig_hole_pos & 0xFFF) - sizeof(header_t);
- hole_header->magic = HEAP_MAGIC;
- hole_header->is_hole = 1;
- footer_t *hole_footer = (footer_t *) ((uint32_t) new_location - sizeof(footer_t));
- hole_footer->magic = HEAP_MAGIC;
- hole_footer->header = hole_header;
- orig_hole_pos = new_location;
- orig_hole_size = orig_hole_size - hole_header->size;
- } else {
- remove_ordered_array((uint32_t) iterator, &heap->index);
- }
-
- header_t *block_header = (header_t *) orig_hole_pos;
- block_header->magic = HEAP_MAGIC;
- block_header->is_hole = 0;
- block_header->size = new_size;
- footer_t *block_footer = (footer_t *) (orig_hole_pos + sizeof(header_t) + size);
- block_footer->magic = HEAP_MAGIC;
- block_footer->header = block_header;
-
- if (orig_hole_size - new_size > 0) {
- header_t *hole_header = (header_t *) (orig_hole_pos + sizeof(header_t) + size + sizeof(footer_t));
- hole_header->magic = HEAP_MAGIC;
- hole_header->is_hole = 1;
- hole_header->size = orig_hole_size - new_size;
- footer_t *hole_footer = (footer_t *) ((uint32_t) hole_header + orig_hole_size - new_size - sizeof(footer_t));
- if ((uint32_t) hole_footer < heap->end_address) {
- hole_footer->magic = HEAP_MAGIC;
- hole_footer->header = hole_header;
- }
- insert_ordered_array((void *) hole_header, &heap->index);
- }
-
- return (void *) ((uint32_t) block_header + sizeof(header_t));
-}
-
-void free(void *p, heap_t *heap)
-{
- if (p == 0)
- return;
-
- header_t *header = (header_t *) ((uint32_t) p - sizeof(header_t));
- footer_t *footer = (footer_t *) ((uint32_t) header + header->size - sizeof(footer_t));
-
- assert(header->magic == HEAP_MAGIC);
- assert(footer->magic == HEAP_MAGIC);
-
- header->is_hole = 1;
-
- char do_add = 1;
-
- footer_t *test_footer = (footer_t *) ((uint32_t) header - sizeof(footer_t));
- if (test_footer->magic == HEAP_MAGIC &&
- test_footer->header->is_hole == 1) {
- uint32_t cache_size = header->size;
- header = test_footer->header;
- footer->header = header;
- header->size += cache_size;
- do_add = 0;
- }
-
- header_t *test_header = (header_t *) ((uint32_t) footer + sizeof(footer_t));
- if (test_header->magic == HEAP_MAGIC &&
- test_header->is_hole) {
- header->size += test_header->size;
- test_footer = (footer_t *) ((uint32_t) test_header + test_header->size - sizeof(footer_t));
- footer = test_footer;
- uint32_t iterator = 0;
- while ((iterator < heap->index.size) && (lookup_ordered_array(iterator, &heap->index) != (void *) test_header))
- iterator++;
-
- assert(iterator < heap->index.size);
- remove_ordered_array(iterator, &heap->index);
- }
-
- if ((uint32_t) footer + sizeof(footer_t) == heap->end_address) {
- uint32_t old_length = heap->end_address - heap->start_address;
- uint32_t new_length = contract((uint32_t) header - heap->start_address, heap);
- if (header->size - (old_length - new_length) > 0) {
- header->size -= old_length - new_length;
- footer = (footer_t *) ((uint32_t) header + header->size - sizeof(footer_t));
- footer->magic = HEAP_MAGIC;
- footer->header = header;
- } else {
- uint32_t iterator = 0;
- while ((iterator < heap->index.size) &&
- (lookup_ordered_array(iterator, &heap->index) != (void *) test_header))
- iterator++;
- if (iterator < heap->index.size)
- remove_ordered_array(iterator, &heap->index);
- }
- }
-
- if (do_add == 1)
- insert_ordered_array((void *) header, &heap->index);
-} \ No newline at end of file
diff --git a/src/kernel/memory/kheap.h b/src/kernel/memory/kheap.h
deleted file mode 100644
index f31a2d3..0000000
--- a/src/kernel/memory/kheap.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef MELVIX_KHEAP_H
-#define MELVIX_KHEAP_H
-
-#include <stdint.h>
-#include <kernel/memory/ordered_array.h>
-
-#define KHEAP_START 0xC0000000
-#define KHEAP_INITIAL_SIZE 0x100000
-
-#define HEAP_INDEX_SIZE 0x20000
-#define HEAP_MAGIC 0xabcdef42
-#define HEAP_MIN_SIZE 0x70000
-
-typedef struct {
- uint32_t magic;
- uint8_t is_hole;
- uint32_t size;
-} header_t;
-
-typedef struct {
- uint32_t magic;
- header_t *header;
-} footer_t;
-
-typedef struct {
- ordered_array_t index;
- uint32_t start_address;
- uint32_t end_address;
- uint32_t max_address;
- uint8_t supervisor;
- uint8_t readonly;
-} heap_t;
-
-heap_t *create_heap(uint32_t start, uint32_t end, uint32_t max, uint8_t supervisor, uint8_t readonly);
-
-void *alloc(uint32_t size, uint8_t page_align, heap_t *heap);
-
-void free(void *p, heap_t *heap);
-
-uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys);
-
-uint32_t kmalloc_a(uint32_t sz);
-
-uint32_t kmalloc_p(uint32_t sz, uint32_t *phys);
-
-uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys);
-
-uint32_t kmalloc(uint32_t sz);
-
-void kfree(void *p);
-
-#endif \ No newline at end of file
diff --git a/src/kernel/memory/ordered_array.c b/src/kernel/memory/ordered_array.c
deleted file mode 100644
index 5d94491..0000000
--- a/src/kernel/memory/ordered_array.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <kernel/memory/ordered_array.h>
-#include <stdint.h>
-#include <kernel/lib/lib.h>
-#include <kernel/system.h>
-#include "kheap.h"
-
-int8_t standard_lessthan_predicate(type_t a, type_t b)
-{
- return (int8_t) ((a < b) ? 1 : 0);
-}
-
-ordered_array_t create_ordered_array(uint32_t max_size, lessthan_predicate_t less_than)
-{
- ordered_array_t to_ret;
- to_ret.array = (void *) kmalloc(max_size * sizeof(type_t));
- memset(to_ret.array, 0, max_size * sizeof(type_t));
- to_ret.size = 0;
- to_ret.max_size = max_size;
- to_ret.less_than = less_than;
- return to_ret;
-}
-
-ordered_array_t place_ordered_array(void *addr, uint32_t max_size, lessthan_predicate_t less_than)
-{
- ordered_array_t to_ret;
- to_ret.array = (type_t *) addr;
- memset(to_ret.array, 0, max_size * sizeof(type_t));
- to_ret.size = 0;
- to_ret.max_size = max_size;
- to_ret.less_than = less_than;
- return to_ret;
-}
-
-void insert_ordered_array(type_t item, ordered_array_t *array)
-{
- assert((int) array->less_than);
- uint32_t iterator = 0;
- while (iterator < array->size && array->less_than(array->array[iterator], item))
- iterator++;
- if (iterator == array->size)
- array->array[array->size++] = item;
- else {
- type_t tmp = array->array[iterator];
- array->array[iterator] = item;
- while (iterator < array->size) {
- iterator++;
- type_t tmp2 = array->array[iterator];
- array->array[iterator] = tmp;
- tmp = tmp2;
- }
- array->size++;
- }
-}
-
-type_t lookup_ordered_array(uint32_t i, ordered_array_t *array)
-{
- assert(i < array->size);
- return array->array[i];
-}
-
-void remove_ordered_array(uint32_t i, ordered_array_t *array)
-{
- while (i < array->size) {
- array->array[i] = array->array[i + 1];
- i++;
- }
- array->size--;
-} \ No newline at end of file
diff --git a/src/kernel/memory/ordered_array.h b/src/kernel/memory/ordered_array.h
deleted file mode 100644
index cf753e3..0000000
--- a/src/kernel/memory/ordered_array.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef MELVIX_ORDERED_ARRAY_H
-#define MELVIX_ORDERED_ARRAY_H
-
-#include <stdint.h>
-
-typedef void *type_t;
-
-typedef int8_t (*lessthan_predicate_t)(type_t, type_t);
-
-typedef struct {
- type_t *array;
- uint32_t size;
- uint32_t max_size;
- lessthan_predicate_t less_than;
-} ordered_array_t;
-
-int8_t standard_lessthan_predicate(type_t a, type_t b);
-
-ordered_array_t create_ordered_array(uint32_t max_size, lessthan_predicate_t less_than);
-
-ordered_array_t place_ordered_array(void *addr, uint32_t max_size, lessthan_predicate_t less_than);
-
-void destroy_ordered_array(ordered_array_t *array);
-
-void insert_ordered_array(type_t item, ordered_array_t *array);
-
-type_t lookup_ordered_array(uint32_t i, ordered_array_t *array);
-
-void remove_ordered_array(uint32_t i, ordered_array_t *array);
-
-#endif
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
index bca5ed3..e4169ba 100644
--- a/src/kernel/memory/paging.c
+++ b/src/kernel/memory/paging.c
@@ -1,203 +1,192 @@
+#include <stdint.h>
#include <kernel/memory/paging.h>
-#include <kernel/memory/kheap.h>
-#include <kernel/lib/lib.h>
#include <kernel/system.h>
+#include <kernel/lib/lib.h>
int paging_enabled = 0;
-page_directory_t *kernel_directory = 0;
-page_directory_t *current_directory = 0;
-
-uint32_t *frames;
-uint32_t nframes;
+uint32_t *current_page_directory;
+uint32_t (*current_page_tables)[1024];
+uint32_t kernel_page_directory[1024] __attribute__((aligned(4096)));
+uint32_t kernel_page_tables[1024][1024] __attribute__((aligned(4096)));
+uint32_t user_page_directory[1024] __attribute__((aligned(4096)));
+uint32_t user_page_tables[1024][1024] __attribute__((aligned(4096)));
-extern uint32_t placement_address;
-extern heap_t *kheap;
-
-extern void copy_page_physical();
+void paging_init()
+{
+ for (uint32_t i = 0; i < 1024; i++) {
+ for (uint32_t j = 0; j < 1024; j++) {
+ current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW;
+ }
+ }
-#define INDEX_FROM_BIT(a) (a/(8*4))
-#define OFFSET_FROM_BIT(a) (a%(8*4))
+ for (uint32_t i = 0; i < 1024; i++) {
+ current_page_directory[i] = ((uint32_t) current_page_tables[i]) | PD_RW | PD_PRESENT;
+ }
-void paging_set_frame(uint32_t frame_addr)
-{
- uint32_t frame = frame_addr / 0x1000;
- uint32_t idx = INDEX_FROM_BIT(frame);
- uint32_t off = OFFSET_FROM_BIT(frame);
- frames[idx] |= (0x1 << off);
+ paging_set_present(0, memory_get_all() >> 3); // /4
}
-void paging_clear_frame(uint32_t frame_addr)
+void paging_install()
{
- uint32_t frame = frame_addr / 0x1000;
- uint32_t idx = INDEX_FROM_BIT(frame);
- uint32_t off = OFFSET_FROM_BIT(frame);
- frames[idx] &= ~(0x1 << off);
+ // User paging
+ paging_switch_directory(1);
+ paging_init();
+ paging_set_user(0, memory_get_all() >> 3);
+
+ // Kernel paging
+ paging_switch_directory(0);
+ paging_init();
+ paging_set_used(0, ((uint32_t) ASM_KERNEL_END >> 12) + 1); // /4096
+
+ paging_enable();
+
+ vga_log("Installed paging");
}
-uint32_t paging_first_frame()
+void paging_disable()
{
- uint32_t i, j;
- for (i = 0; i < INDEX_FROM_BIT(nframes); i++) {
- if (frames[i] != 0xFFFFFFFF) {
- for (j = 0; j < 32; j++) {
- uint32_t toTest = (0x1 << j);
- if (!(frames[i] & toTest)) {
- return i * 4 * 8 + j;
- }
- }
- }
- }
- return 0;
+ uint32_t cr0;
+ asm ("mov %%cr0, %0": "=r"(cr0));
+ cr0 &= 0x7fffffff;
+ asm ("mov %0, %%cr0"::"r"(cr0));
+ paging_enabled = 0;
}
-void paging_alloc_frame(page_t *page, int is_kernel, int is_writeable)
+void paging_switch_directory(int user)
{
- if (page->frame != 0) {
- return;
+ if (user == 1) {
+ current_page_tables = user_page_tables;
+ current_page_directory = user_page_directory;
} else {
- uint32_t idx = paging_first_frame();
- if (idx == (uint32_t) -1)
- panic("No free frames!");
- paging_set_frame(idx * 0x1000);
- page->present = 1;
- page->rw = (is_writeable == 1) ? 1 : 0;
- page->user = (is_kernel == 1) ? 0 : 1;
- page->frame = idx;
+ current_page_tables = kernel_page_tables;
+ current_page_directory = kernel_page_directory;
}
+ asm ("mov %0, %%cr3"::"r"(current_page_directory));
}
-void paging_free_frame(page_t *page)
+void paging_enable()
{
- uint32_t frame;
- if (!(frame = page->frame)) {
- return;
- } else {
- paging_clear_frame(frame);
- page->frame = 0x0;
- }
+ asm ("mov %0, %%cr3"::"r"(current_page_directory));
+ uint32_t cr0;
+ asm ("mov %%cr0, %0": "=r"(cr0));
+ cr0 |= 0x80000000;
+ asm ("mov %0, %%cr0"::"r"(cr0));
+ paging_enabled = 1;
}
-void paging_install()
+inline void invlpg(uint32_t addr)
{
- uint32_t mem_end_page = memory_get_all() << 10;
-
- nframes = mem_end_page / 0x1000;
- frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes));
- memset(frames, 0, INDEX_FROM_BIT(nframes));
-
- kernel_directory = (page_directory_t *) kmalloc_a(sizeof(page_directory_t));
- memset(kernel_directory, 0, sizeof(page_directory_t));
- kernel_directory->physical_address = (uint32_t) kernel_directory->tables_physical;
-
- for (uint32_t i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000)
- paging_get_page((uint32_t) i, 1, kernel_directory);
-
- int i = 0;
- while (i < 0x400000) {
- paging_alloc_frame(paging_get_page((uint32_t) i, 1, kernel_directory), 0, 0);
- i += 0x1000;
- }
-
- for (i = KHEAP_START; i < (int) (KHEAP_START + KHEAP_INITIAL_SIZE); i += 0x1000)
- paging_alloc_frame(paging_get_page((uint32_t) i, 1, kernel_directory), 0, 0);
-
- paging_switch_directory(kernel_directory);
-
- kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0);
-
- current_directory = paging_clone_directory(kernel_directory);
- paging_switch_directory(current_directory);
- vga_log("Installed Paging");
+ asm ("invlpg (%0)"::"r" (addr) : "memory");
}
-void paging_switch_directory(page_directory_t *dir)
+void paging_map(uint32_t phy, uint32_t virt, uint16_t flags)
{
- current_directory = dir;
- asm volatile("mov %0, %%cr3"::"r"(dir->physical_address));
- uint32_t cr0;
- asm volatile("mov %%cr0, %0": "=r"(cr0));
- cr0 |= 0x80000000; // Enable paging!
- asm volatile("mov %0, %%cr0"::"r"(cr0));
+ uint32_t pdi = virt >> 22;
+ uint32_t pti = virt >> 12 & 0x03FF;
+ current_page_tables[pdi][pti] = phy | flags;
+ invlpg(virt);
}
-void paging_enable()
+uint32_t paging_get_phys(uint32_t virt)
{
- paging_switch_directory(kernel_directory);
- paging_enabled = 1;
+ uint32_t pdi = virt >> 22;
+ uint32_t pti = (virt >> 12) & 0x03FF;
+ return current_page_tables[pdi][pti] & 0xFFFFF000;
}
-void paging_disable()
+uint16_t paging_get_flags(uint32_t virt)
{
- uint32_t cr0;
- asm ("mov %%cr0, %0": "=r"(cr0));
- cr0 &= 0x7fffffff;
- asm ("mov %0, %%cr0"::"r"(cr0));
- paging_enabled = 0;
+ uint32_t pdi = virt >> 22;
+ uint32_t pti = (virt >> 12) & 0x03FF;
+ return current_page_tables[pdi][pti] & 0xFFF;
}
-page_t *paging_get_page(uint32_t address, int make, page_directory_t *dir)
+void paging_set_flag_up(uint32_t virt, uint32_t count, uint32_t flag)
{
- address /= 0x1000;
- uint32_t table_idx = address / 1024;
+ uint32_t page_n = virt / 4096;
+ for (uint32_t i = page_n; i < page_n + count; i++) {
+ current_page_tables[i / 1024][i % 1024] |= flag;
+ invlpg(i * 4096);
+ }
+}
- if (dir->tables[table_idx]) {
- return &dir->tables[table_idx]->pages[address % 1024];
- } else if (make) {
- uint32_t tmp;
- dir->tables[table_idx] = (page_table_t *) kmalloc_ap(sizeof(page_table_t), &tmp);
- memset(dir->tables[table_idx], 0, 0x1000);
- dir->tables_physical[table_idx] = tmp | 0x7; // PRESENT, RW, US
- return &dir->tables[table_idx]->pages[address % 1024];
- } else {
- return 0;
+void paging_set_flag_down(uint32_t virt, uint32_t count, uint32_t flag)
+{
+ uint32_t page_n = virt / 4096;
+ for (uint32_t i = page_n; i < page_n + count; i++) {
+ current_page_tables[i / 1024][i % 1024] &= ~flag;
+ invlpg(i * 4096);
}
}
-static page_table_t *paging_clone_table(page_table_t *src, uint32_t *physAddr)
+void paging_set_present(uint32_t virt, uint32_t count)
{
- page_table_t *table = (page_table_t *) kmalloc_ap(sizeof(page_table_t), physAddr);
- memset(table, 0, sizeof(page_directory_t));
+ paging_set_flag_up(virt, count, PT_PRESENT);
+}
- for (int i = 0; i < 1024; i++) {
- if (!src->pages[i].frame)
- continue;
+void paging_set_absent(uint32_t virt, uint32_t count)
+{
+ paging_set_flag_down(virt, count, PT_PRESENT);
+}
- paging_alloc_frame(&table->pages[i], 0, 0);
+void paging_set_used(uint32_t virt, uint32_t count)
+{
+ paging_set_flag_up(virt, count, PT_USED);
+}
- if (src->pages[i].present) table->pages[i].present = 1;
- if (src->pages[i].rw) table->pages[i].rw = 1;
- if (src->pages[i].user) table->pages[i].user = 1;
- if (src->pages[i].accessed)table->pages[i].accessed = 1;
- if (src->pages[i].dirty) table->pages[i].dirty = 1;
+void paging_set_free(uint32_t virt, uint32_t count)
+{
+ paging_set_flag_down(virt, count, PT_USED);
+}
- copy_page_physical(src->pages[i].frame * 0x1000, table->pages[i].frame * 0x1000);
+void paging_set_user(uint32_t virt, uint32_t count)
+{
+ uint32_t page_n = virt / 4096;
+ for (uint32_t i = page_n; i < page_n + count; i += 1024) {
+ current_page_directory[i / 1024] |= PD_ALL_PRIV;
}
- return table;
+ paging_set_flag_up(virt, count, PT_ALL_PRIV);
}
-page_directory_t *paging_clone_directory(page_directory_t *src)
+uint32_t paging_find_pages(uint32_t count)
{
- uint32_t phys;
- page_directory_t *dir = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t), &phys);
- memset(dir, 0, sizeof(page_directory_t));
-
- uint32_t offset = (uint32_t) dir->tables_physical - (uint32_t) dir;
+ uint32_t continuous = 0;
+ uint32_t startDir = 0;
+ uint32_t startPage = 0;
+ for (uint32_t i = 0; i < 1024; i++) {
+ for (uint32_t j = 0; j < 1024; j++) {
+ if (!(current_page_tables[i][j] & PT_PRESENT) || (current_page_tables[i][j] & PT_USED)) {
+ continuous = 0;
+ startDir = i;
+ startPage = j + 1;
+ } else {
+ if (++continuous == count)
+ return (startDir * 0x400000) + (startPage * 0x1000);
+ }
+ }
+ }
- dir->physical_address = phys + offset;
+ panic("Out of memory!");
+ return 0;
+}
- for (int i = 0; i < 1024; i++) {
- if (!src->tables[i])
- continue;
+uint32_t paging_alloc_pages(uint32_t count)
+{
+ uint32_t ptr = paging_find_pages(count);
+ paging_set_used(ptr, count);
+ paging_set_user(ptr, count);
+ return ptr;
+}
- if (kernel_directory->tables[i] == src->tables[i]) {
- dir->tables[i] = src->tables[i];
- dir->tables_physical[i] = src->tables_physical[i];
- } else {
- uint32_t phys;
- dir->tables[i] = paging_clone_table(src->tables[i], &phys);
- dir->tables_physical[i] = phys | 0x07;
+uint32_t paging_get_used_pages()
+{
+ uint32_t n = 0;
+ for (uint32_t i = 0; i < 1024; i++) {
+ for (uint32_t j = 0; j < 1024; j++) {
+ uint8_t flags = current_page_tables[i][j] & PT_USED;
+ if (flags == 1) n++;
}
}
- return dir;
+ return n;
} \ No newline at end of file
diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h
index 74d486f..ff542e3 100644
--- a/src/kernel/memory/paging.h
+++ b/src/kernel/memory/paging.h
@@ -2,46 +2,63 @@
#define MELVIX_PAGING_H
#include <stdint.h>
-#include <kernel/interrupts/interrupts.h>
-
-typedef struct page {
- uint32_t present: 1;
- uint32_t rw: 1;
- uint32_t user: 1;
- uint32_t accessed: 1;
- uint32_t dirty: 1;
- uint32_t unused: 7;
- uint32_t frame: 20;
-} page_t;
-
-typedef struct page_table {
- page_t pages[1024];
-} page_table_t;
-
-typedef struct page_directory {
- page_table_t *tables[1024];
- uint32_t tables_physical[1024];
- uint32_t physical_address;
-} page_directory_t;
-int paging_enabled;
+#define PD_PRESENT 1 << 0
+#define PD_RW 1 << 1
+#define PD_ALL_PRIV 1 << 2
+#define PD_WRITETHR 1 << 3
+#define PD_CACHE_D 1 << 4
+#define PD_ACCESSED 1 << 5
+#define PD_4M_PAGE 1 << 7
-void paging_set_frame(uint32_t frame_addr);
+#define PT_PRESENT 1 << 0
+#define PT_RW 1 << 1
+#define PT_ALL_PRIV 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
-void paging_alloc_frame(page_t *page, int is_kernel, int is_writeable);
+int paging_enabled;
-void paging_free_frame(page_t *page);
+uint32_t *current_page_directory;
void paging_install();
-void paging_switch_directory(page_directory_t *dir);
-
void paging_enable();
void paging_disable();
-page_t *paging_get_page(uint32_t address, int make, page_directory_t *dir);
+void paging_switch_directory(int user);
+
+void paging_map(uint32_t phy, uint32_t virt, uint16_t flags);
+
+uint32_t paging_get_phys(uint32_t virt);
+
+uint16_t paging_get_flags(uint32_t virt);
+
+void paging_set_flags(uint32_t virt, uint32_t count, uint16_t flags);
+
+void paging_set_flag_up(uint32_t virt, uint32_t count, uint32_t flag);
+
+void paging_set_flag_down(uint32_t virt, uint32_t count, uint32_t flag);
+
+void paging_set_present(uint32_t virt, uint32_t count);
+
+void paging_set_absent(uint32_t virt, uint32_t count);
+
+void paging_set_used(uint32_t virt, uint32_t count);
+
+void paging_set_free(uint32_t virt, uint32_t count);
+
+void paging_set_user(uint32_t virt, uint32_t count);
+
+uint32_t paging_find_pages(uint32_t count);
+
+uint32_t paging_alloc_pages(uint32_t count);
-page_directory_t *paging_clone_directory(page_directory_t *src);
+uint32_t paging_get_used_pages();
-#endif
+#endif \ No newline at end of file
diff --git a/src/kernel/net/rtl8139.c b/src/kernel/net/rtl8139.c
index 13a9c29..6e682b5 100644
--- a/src/kernel/net/rtl8139.c
+++ b/src/kernel/net/rtl8139.c
@@ -3,7 +3,7 @@
#include <kernel/system.h>
#include <kernel/interrupts/interrupts.h>
#include <kernel/lib/stdio.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
int rtl_irq = 0;
uint8_t mac[6];
diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c
new file mode 100644
index 0000000..68750e1
--- /dev/null
+++ b/src/kernel/syscall.c
@@ -0,0 +1,20 @@
+#include <kernel/syscall.h>
+
+/**
+ * DEFINITIONS
+ */
+DEFN_SYSCALL0(halt, 0);
+
+DEFN_SYSCALL1(write, 1, const char *);
+
+DEFN_SYSCALL1(read, 2, const char *);
+
+DEFN_SYSCALL1(writec, 3, char);
+
+DEFN_SYSCALL0(readc, 4);
+
+DEFN_SYSCALL0(get_pointers, 5);
+
+DEFN_SYSCALL1(alloc, 6, uint32_t);
+
+DEFN_SYSCALL1(free, 7, uint32_t); \ No newline at end of file
diff --git a/src/kernel/syscall.h b/src/kernel/syscall.h
new file mode 100644
index 0000000..2d79458
--- /dev/null
+++ b/src/kernel/syscall.h
@@ -0,0 +1,80 @@
+#ifndef MELVIX_SYSCALL_H
+#define MELVIX_SYSCALL_H
+
+#include <stdint.h>
+
+#define DECL_SYSCALL0(fn) int syscall_##fn();
+#define DECL_SYSCALL1(fn, p1) int syscall_##fn(p1);
+#define DECL_SYSCALL2(fn, p1, p2) int syscall_##fn(p1,p2);
+#define DECL_SYSCALL3(fn, p1, p2, p3) int syscall_##fn(p1,p2,p3);
+#define DECL_SYSCALL4(fn, p1, p2, p3, p4) int syscall_##fn(p1,p2,p3,p4);
+#define DECL_SYSCALL5(fn, p1, p2, p3, p4, p5) int syscall_##fn(p1,p2,p3,p4,p5);
+
+#define DEFN_SYSCALL0(fn, num) \
+int syscall_##fn() \
+{ \
+ int a; \
+ asm volatile("int $0x80" : "=a" (a) : "0" (num)); \
+ return a; \
+}
+
+#define DEFN_SYSCALL1(fn, num, P1) \
+int syscall_##fn(P1 p1) \
+{ \
+ int a; \
+ asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1)); \
+ return a; \
+}
+
+#define DEFN_SYSCALL2(fn, num, P1, P2) \
+int syscall_##fn(P1 p1, P2 p2) \
+{ \
+ int a; \
+ asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2)); \
+ return a; \
+}
+
+#define DEFN_SYSCALL3(fn, num, P1, P2, P3) \
+int syscall_##fn(P1 p1, P2 p2, P3 p3) \
+{ \
+ int a; \
+ asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d"((int)p3)); \
+ return a; \
+}
+
+#define DEFN_SYSCALL4(fn, num, P1, P2, P3, P4) \
+int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4) \
+{ \
+ int a; \
+ asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4)); \
+ return a; \
+}
+
+#define DEFN_SYSCALL5(fn, num) \
+int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
+{ \
+ int a; \
+ asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4), "D" ((int)p5)); \
+ return a; \
+}
+
+/**
+ * DECLARATIONS
+ */
+DECL_SYSCALL0(halt);
+
+DECL_SYSCALL1(write, const char *);
+
+DECL_SYSCALL1(read, const char *);
+
+DECL_SYSCALL1(writec, char);
+
+DECL_SYSCALL0(readc);
+
+DECL_SYSCALL0(get_pointers);
+
+DECL_SYSCALL1(alloc, uint32_t);
+
+DECL_SYSCALL1(free, uint32_t);
+
+#endif \ No newline at end of file
diff --git a/src/kernel/syscall/actions/sys_free.c b/src/kernel/syscall/actions/sys_free.c
index 5f52564..f1a0371 100644
--- a/src/kernel/syscall/actions/sys_free.c
+++ b/src/kernel/syscall/actions/sys_free.c
@@ -1,5 +1,5 @@
#include <stdint.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
uint32_t sys_free(uint32_t ptr)
{
diff --git a/src/kernel/syscall/actions/sys_get_pointers.c b/src/kernel/syscall/actions/sys_get_pointers.c
index bc00b3b..cd824db 100644
--- a/src/kernel/syscall/actions/sys_get_pointers.c
+++ b/src/kernel/syscall/actions/sys_get_pointers.c
@@ -1,7 +1,7 @@
#include <stdint.h>
#include <kernel/graphics/vesa.h>
#include <kernel/fs/load.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
struct userspace_pointers {
unsigned char *fb;
diff --git a/src/kernel/tasks/task.c b/src/kernel/tasks/task.c
index 5451288..2c30346 100644
--- a/src/kernel/tasks/task.c
+++ b/src/kernel/tasks/task.c
@@ -1,16 +1,12 @@
#include <kernel/memory/paging.h>
#include <kernel/tasks/task.h>
-#include <kernel/memory/kheap.h>
+#include <kernel/memory/alloc.h>
#include <kernel/lib/lib.h>
#include <kernel/gdt/gdt.h>
#include <kernel/system.h>
-#include <kernel/syscall.h>
-volatile task_t *current_task;
-volatile task_t *ready_queue;
-
-extern page_directory_t *kernel_directory;
-extern page_directory_t *current_directory;
+task_t *current_task;
+task_t *ready_queue;
extern uint32_t read_eip();
@@ -26,9 +22,9 @@ void tasking_install()
current_task->esp = 0;
current_task->ebp = 0;
current_task->eip = 0;
- current_task->page_directory = current_directory;
+ current_task->page_directory = current_page_directory;
current_task->next = 0;
- current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE);
+ current_task->kernel_stack = kmalloc(KERNEL_STACK_SIZE);
vga_log("Installed Tasking");
asm ("sti");
@@ -39,7 +35,7 @@ void move_stack(void *new_stack_start, uint32_t size)
for (uint32_t i = (uint32_t) new_stack_start;
i >= ((uint32_t) new_stack_start - size);
i -= 0x1000) {
- paging_alloc_frame(paging_get_page(i, 1, current_directory), 0, 1);
+ // paging_alloc_frame(paging_get_page(i, 1, current_page_directory), 0, 1);
}
uint32_t pd_addr;
@@ -96,12 +92,12 @@ void switch_task()
esp = current_task->esp;
ebp = current_task->ebp;
- current_directory = current_task->page_directory;
+ current_page_directory = current_task->page_directory;
- set_kernel_stack(current_task->kernel_stack + KERNEL_STACK_SIZE);
+ set_kernel_stack((uintptr_t) (current_task->kernel_stack + KERNEL_STACK_SIZE));
- paging_switch_directory(current_directory);
- perform_task_switch(eip, current_directory->physical_address, ebp, esp);
+ paging_switch_directory((int) current_page_directory);
+ perform_task_switch(eip, (uint32_t) current_page_directory, ebp, esp);
}
int fork()
@@ -110,14 +106,14 @@ int fork()
task_t *parent_task = (task_t *) current_task;
- page_directory_t *directory = paging_clone_directory(current_directory);
+ uint32_t *directory = 0;//paging_clone_directory(current_page_directory);
task_t *new_task = (task_t *) kmalloc(sizeof(task_t));
new_task->id = (int) next_pid++;
new_task->esp = new_task->ebp = 0;
new_task->eip = 0;
new_task->page_directory = directory;
- current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE);
+ current_task->kernel_stack = kmalloc(KERNEL_STACK_SIZE);
new_task->next = 0;
task_t *tmp_task = (task_t *) ready_queue;
@@ -148,7 +144,7 @@ int getpid()
void exec(uint32_t binary)
{
- set_kernel_stack(current_task->kernel_stack + KERNEL_STACK_SIZE);
+ set_kernel_stack((uintptr_t) (current_task->kernel_stack + KERNEL_STACK_SIZE));
info("Switching to user mode...");
@@ -164,7 +160,10 @@ void exec(uint32_t binary)
pushl %%esp; \
pushf; \
pushl $0x1B; \
- push %0; \
+ push $1f; \
iret; \
+ 1: \
" : : "r" (binary));
+
+ // syscall_write("test");
} \ No newline at end of file
diff --git a/src/kernel/tasks/task.h b/src/kernel/tasks/task.h
index 60047eb..7cd6afa 100644
--- a/src/kernel/tasks/task.h
+++ b/src/kernel/tasks/task.h
@@ -10,8 +10,8 @@ typedef struct task {
int id;
uint32_t esp, ebp;
uint32_t eip;
- page_directory_t *page_directory;
- uint32_t kernel_stack;
+ uint32_t *page_directory;
+ uint32_t *kernel_stack;
struct task *next;
} task_t;