diff options
author | Marvin Borner | 2020-02-16 17:29:19 +0100 |
---|---|---|
committer | Marvin Borner | 2020-02-16 17:29:50 +0100 |
commit | 45184af20936cb889b658e69e00a0bb3d522757f (patch) | |
tree | 4b6c3408e526fe733ccfa960726c37e70dc6f989 | |
parent | f5b995586e28f7db426f4707a4348dc067df41c0 (diff) |
Revert to good ol' paging
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; |