diff options
-rw-r--r-- | src/kernel/boot.asm | 15 | ||||
-rw-r--r-- | src/kernel/graphics/vesa.c | 18 | ||||
-rw-r--r-- | src/kernel/graphics/vga.c | 8 | ||||
-rw-r--r-- | src/kernel/interact.asm | 33 | ||||
-rw-r--r-- | src/kernel/io/io.c | 60 | ||||
-rw-r--r-- | src/kernel/io/io.h | 16 | ||||
-rw-r--r-- | src/kernel/kernel.c | 14 | ||||
-rw-r--r-- | src/kernel/lib/lib.h | 8 | ||||
-rw-r--r-- | src/kernel/lib/string.c | 17 | ||||
-rw-r--r-- | src/kernel/paging/kheap.c | 371 | ||||
-rw-r--r-- | src/kernel/paging/kheap.h | 139 | ||||
-rw-r--r-- | src/kernel/paging/ordered_array.c | 66 | ||||
-rw-r--r-- | src/kernel/paging/ordered_array.h | 66 | ||||
-rw-r--r-- | src/kernel/paging/paging.c | 278 | ||||
-rw-r--r-- | src/kernel/paging/paging.h | 101 | ||||
-rw-r--r-- | src/kernel/system.h | 2 |
16 files changed, 794 insertions, 418 deletions
diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index d7d78fd..97e68f5 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -41,6 +41,21 @@ stublet: call kernel_main jmp $ +[global copy_page_physical] +copy_page_physical: + push ebx + pushf + cli + mov ebx, [esp+12] + mov ecx, [esp+16] + + ; Disable paging + mov edx, cr0 + and edx, 0x7fffffff + mov cr0, edx + + mov edx, 1024 + %include "src/kernel/gdt/gdt.asm" %include "src/kernel/interrupts/idt.asm" diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index 9cfcd66..03c189f 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -7,7 +7,7 @@ #include "font.h" void switch_to_vga() { - write_serial("Force switch to VGA!"); + serial_write("Force switch to VGA!\n"); vesa_available = 0; regs16_t regs; regs.ax = 0x0003; @@ -15,7 +15,7 @@ void switch_to_vga() { } struct edid_data get_edid() { - struct edid_data *edid = umalloc(sizeof(struct edid_data)); + /*struct edid_data *edid = umalloc(sizeof(struct edid_data)); regs16_t regs; regs.ax = 0x4F15; @@ -26,11 +26,11 @@ struct edid_data get_edid() { ufree(edid); - return *edid; + return *edid;*/ } struct vbe_mode_info *vbe_set_mode(unsigned short mode) { - write_serial("Setting VBE mode!"); + serial_write("Setting VBE mode!\n"); vesa_available = 0; regs16_t regs; regs.ax = 0x4F02; @@ -142,12 +142,11 @@ void vesa_set_pixel(uint16_t x, uint16_t y, uint32_t color) { } void vesa_draw_char(char ch, int x, int y) { - int cx, cy; int mask[8] = {1, 2, 4, 8, 16, 32, 64, 128}; unsigned char *glyph = font[ch - 32]; - for (cy = 0; cy < 13; cy++) { - for (cx = 0; cx < 8; cx++) { + for (int cy = 0; cy < 13; cy++) { + for (int cx = 0; cx < 8; cx++) { if (glyph[cy] & mask[cx]) { vesa_set_pixel(x + 8 - cx, y + 13 - cy, terminal_color); } @@ -156,14 +155,13 @@ void vesa_draw_char(char ch, int x, int y) { } void vesa_draw_rectangle(int x1, int y1, int x2, int y2, int color) { - int i, j; char blue = color & 255; char green = (color >> 8) & 255; char red = (color >> 16) & 255; int pos1 = x1 * vbe_bpp + y1 * vbe_pitch; char *draw = &fb[pos1]; - for (i = 0; i <= y2 - y1; i++) { - for (j = 0; j <= x2 - x1; j++) { + for (int i = 0; i <= y2 - y1; i++) { + for (int j = 0; j <= x2 - x1; j++) { draw[vbe_bpp * j] = blue; draw[vbe_bpp * j + 1] = green; draw[vbe_bpp * j + 2] = red; diff --git a/src/kernel/graphics/vga.c b/src/kernel/graphics/vga.c index da2a7f4..a470af8 100644 --- a/src/kernel/graphics/vga.c +++ b/src/kernel/graphics/vga.c @@ -146,18 +146,16 @@ void terminal_put_keyboard_char(char c) { void terminal_write_string(const char *data) { // terminal_write(data, strlen(data)); - write_serial(data); + serial_write(data); } void terminal_write_number(int data) { - char converted[128]; - itoa(data, converted, 10); - write_serial(converted); + serial_write_dec(data); // terminal_write(converted, strlen(converted)); } void terminal_write_line(const char *data) { - write_serial(data); + serial_write(data); terminal_column = 0; // terminal_write_string(data); terminal_column = 0; diff --git a/src/kernel/interact.asm b/src/kernel/interact.asm index 8a3e91e..eaad82e 100644 --- a/src/kernel/interact.asm +++ b/src/kernel/interact.asm @@ -1,33 +1,5 @@ -; -; Protected Mode BIOS Call Functionailty v2.0 - by Napalm -; ------------------------------------------------------- -; -; This is code shows how its POSSIBLE to execute BIOS interrupts -; by switch out to real-mode and then back into protected mode. -; -; If you wish to use all or part of this code you must agree -; to the license at the following URL. -; +; Protected Mode BIOS Call Functionality v2.0 - by Napalm ; License: http://creativecommons.org/licenses/by-sa/2.0/uk/ -; -; Notes: This file is in NASM syntax. -; Turn off paging before calling these functions. -; int32() resets all selectors. -; -; C Prototype: -; void _cdelc int32(unsigned char intnum, regs16_t *regs); -; -; Example of usage: -; regs.ax = 0x0013; -; int32(0x10, ®s); -; memset((char *)0xA0000, 1, (320*200)); -; memset((char *)0xA0000 + (100*320+80), 14, 80); -; regs.ax = 0x0000; -; int32(0x16, ®s); -; regs.ax = 0x0003; -; int32(0x10, ®s); -; -; [bits 32] global int32, _int32 @@ -60,6 +32,9 @@ endstruc section .text int32: use32 ; by Napalm + mov edx, cr0 + and edx, 0x7fffffff + mov cr0, edx _int32: cli ; disable interrupts pusha ; save register state to 32bit stack diff --git a/src/kernel/io/io.c b/src/kernel/io/io.c index 30dcee2..dc2d59a 100644 --- a/src/kernel/io/io.c +++ b/src/kernel/io/io.c @@ -40,21 +40,65 @@ void init_serial() { send_b(0x3f8 + 3, 0x03); send_b(0x3f8 + 2, 0xC7); send_b(0x3f8 + 4, 0x0B); - write_serial("Installed serial connection!"); + serial_write("Installed serial connection!\n"); } int is_transmit_empty() { return receive_b(0x3f8 + 5) & 0x20; } -void write_serial(char *data) { +void serial_put(char ch) { + while (is_transmit_empty() == 0); + send_b(0x3f8, ch); +} + +void serial_write(char *data) { for (size_t i = 0; i < strlen(data); i++) { - while (is_transmit_empty() == 0); - send_b(0x3f8, data[i]); + serial_put(data[i]); + } +} + +void serial_write_hex(int n) { + int tmp; + + serial_write("0x"); + char noZeroes = 1; + + for (int i = 28; i > 0; i -= 4) { + tmp = (n >> i) & 0xF; + if (tmp == 0 && noZeroes != 0) continue; + + if (tmp >= 0xA) { + noZeroes = 0; + serial_put(tmp - 0xA + 'a'); + } else { + noZeroes = 0; + serial_put(tmp + '0'); + } + } + + tmp = n & 0xF; + if (tmp >= 0xA) { + serial_put(tmp - 0xA + 'a'); + } else { + serial_put(tmp + '0'); } - char *linebreak = "\n"; - for (size_t i = 0; i < strlen(linebreak); i++) { - while (is_transmit_empty() == 0); - send_b(0x3f8, linebreak[i]); +} + +void serial_write_dec(int n) { + if (n == 0) serial_put('0'); + int acc = n; + char c[32]; + int i = 0; + while (acc > 0) { + c[i] = '0' + acc % 10; + acc /= 10; + i++; } + c[i] = 0; + static char c2[32]; + c2[i--] = 0; + int j = 0; + while (i >= 0) c2[i--] = c[j++]; + serial_write(c2); } diff --git a/src/kernel/io/io.h b/src/kernel/io/io.h index e72d794..a34bd21 100644 --- a/src/kernel/io/io.h +++ b/src/kernel/io/io.h @@ -52,8 +52,20 @@ void init_serial(); /** * Write a string to the serial port (QEMU logging) - * @param data + * @param data The string that should get transmitted */ -void write_serial(char *data); +void serial_write(char *data); + +/** + * Write a hex number to the serial port (QEMU logging) + * @param n The hex number that should get transmitted + */ +void serial_write_hex(int n); + +/** + * Write a dec number to the serial port (QEMU logging) + * @param n The dec number that should get transmitted + */ +void serial_write_dec(int n); #endif diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 30a8e35..e028178 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,6 +9,7 @@ #include "paging/kheap.h" void init() { + initialise_paging(); timer_install(); gdt_install(); idt_install(); @@ -16,26 +17,21 @@ void init() { irq_install(); init_serial(); // terminal_initialize(); // TODO: Replace VGA functions with VESA - // init_kheap(); - // page_init(); - // keyboard_install(); - // mouse_install(); asm volatile ("sti"); } void kernel_main(void) { set_optimal_resolution(); init(); - // info("Melvix loaded successfully!\n\n"); - // info("Loading VESA..."); + /* TODO: Fix page fault exception vesa_draw_string("This is a testing text!"); if (vesa_available) { - write_serial("Loaded VESA!"); + serial_write("Loaded VESA!\n"); } else { - write_serial("VESA loading failed!"); - } + serial_write("VESA loading failed!\n"); + }*/ // __asm__ ("div %0" :: "r"(0)); // Exception testing x/0 loop: diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h index 0292cc3..03b4a3e 100644 --- a/src/kernel/lib/lib.h +++ b/src/kernel/lib/lib.h @@ -61,12 +61,4 @@ void *memory_set(void *dest, char val, size_t count); */ int memory_compare(const void *a_ptr, const void *b_ptr, size_t size); -/** - * Convert an int into a string - * @param i The integer which should be converted - * @param b The converted int as string - * @param base The desired base - */ -void *itoa(int i, char *b, int base); - #endif diff --git a/src/kernel/lib/string.c b/src/kernel/lib/string.c index ef746d6..1e41d15 100644 --- a/src/kernel/lib/string.c +++ b/src/kernel/lib/string.c @@ -34,20 +34,3 @@ char *strcpy(char *dest, const char *src) { dest[i] = 0; return dest; } - -void *itoa(int i, char *b, int base) { - int temp_i; - temp_i = i; - int stringLen = 1; - - while ((int) temp_i / base != 0) { - temp_i = (int) temp_i / base; - stringLen++; - } - - temp_i = i; - do { - *(b + stringLen - 1) = (temp_i % base) + '0'; - temp_i = (int) temp_i / base; - } while (stringLen--); -}
\ No newline at end of file diff --git a/src/kernel/paging/kheap.c b/src/kernel/paging/kheap.c index 2004cb8..94aa547 100644 --- a/src/kernel/paging/kheap.c +++ b/src/kernel/paging/kheap.c @@ -1,168 +1,297 @@ +#include <stdint.h> #include "kheap.h" #include "paging.h" -#include "../lib/lib.h" +#include "ordered_array.h" #include "../system.h" -unsigned int placement_address; +extern uint32_t end; +uint32_t placement_address = (uint32_t) &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, (unsigned char) align, kheap); + if (phys != 0) { + page_t *page = 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; + } +} -heap_header_t *kheap = NULL; -heap_header_t *uheap = NULL; +void kfree(void *p) { + free(p, kheap); +} -void init_kheap() { - end = (unsigned int) &end; - placement_address = end; +uint32_t kmalloc_a(uint32_t sz) { + return kmalloc_int(sz, 1, 0); +} - kheap = (heap_header_t *) fmalloc(KHEAP_SIZE); - init_heap(kheap, KHEAP_SIZE); +uint32_t kmalloc_p(uint32_t sz, uint32_t *phys) { + return kmalloc_int(sz, 0, phys); +} - uheap = (heap_header_t *) kmalloc_a(UHEAP_SIZE); - init_heap(uheap, UHEAP_SIZE); - vpage_map_user(root_vpage_dir, (unsigned int) &uheap, (unsigned int) &uheap); +uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys) { + return kmalloc_int(sz, 1, phys); } -void *fmalloc(unsigned int size) { - assert(placement_address + size < MEM_END); - unsigned int hold = placement_address; - memory_set((void *) hold, 0, size); - placement_address += size; - return (void *) hold; +uint32_t kmalloc(uint32_t sz) { + return kmalloc_int(sz, 0, 0); } -void *kmalloc_a(unsigned int size) { - //assert(((placement_address & 0xFFFFF000) + 0x1000) + size < MEM_END); - placement_address &= 0xFFFFF000; - placement_address += 0x1000; +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; + } - unsigned int hold = placement_address; - placement_address += size; + assert(heap->start_address + new_size <= heap->max_address); - return (void *) hold; + uint32_t old_size = heap->end_address - heap->start_address; + uint32_t i = old_size; + while (i < new_size) { + alloc_frame(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; } -heap_header_t *find_sized_heap(heap_header_t *heap, size_t size) { - while ((heap->size < HEAP_FIND_SIZE + size) || (heap->free != 1)) { - assert(heap->magic == KHEAP_MAGIC); - assert(heap->magic2 == KHEAP_MAGIC2); - heap_footer_t *foot = (heap_footer_t *) ((unsigned int) heap + HEAP_S + heap->size); - assert(foot->magic == KHEAP_MAGIC); - assert(foot->magic2 == KHEAP_MAGIC2); +static uint32_t contract(uint32_t new_size, heap_t *heap) { + assert(new_size < heap->end_address - heap->start_address); - if (foot->size == KHEAP_END) - panic("out of heap space"); + if (new_size & 0x1000) { + new_size &= 0x1000; + new_size += 0x1000; + } - if (foot->size != heap->size) - panic("heap footer/header mismatch"); + if (new_size < HEAP_MIN_SIZE) + new_size = HEAP_MIN_SIZE; - heap = (heap_header_t *) ((unsigned int) foot + sizeof(heap_footer_t)); + uint32_t old_size = heap->end_address - heap->start_address; + uint32_t i = old_size - 0x1000; + while (new_size < i) { + free_frame(get_page(heap->start_address + i, 0, kernel_directory)); + i -= 0x1000; } - - return heap; + heap->end_address = heap->start_address + new_size; + return new_size; } -void split_heap(heap_header_t *heap, size_t size) { - heap_footer_t *foot = (heap_footer_t *) ((unsigned int) heap + HEAP_S + size); - foot->magic = KHEAP_MAGIC; - foot->magic2 = KHEAP_MAGIC2; - foot->size = size; - - size_t new_size = heap->size - HEAP_TOTAL - size; - heap->size = size; - - heap = (heap_header_t *) ((unsigned int) foot + sizeof(heap_footer_t)); - heap->size = new_size; - heap->free = 1; - heap->magic = KHEAP_MAGIC; - heap->magic2 = KHEAP_MAGIC2; - - foot = (heap_footer_t *) ((unsigned int) heap + HEAP_S + heap->size); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { - warn("invalid footer in split"); - // dump_struct(foot, sizeof(heap_footer_t)); +static int find_smallest_hole(uint32_t size, unsigned char 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; + int offset = 0; + if ((location + sizeof(header_t)) & 0xFFFFF000 != 0) + offset = 0x1000 - (location + sizeof(header_t)) % 0x1000; + int hole_size = (int) header->size - offset; + + if (hole_size >= (int) size) + break; + } else if (header->size >= size) + break; + iterator++; } - if (foot->size != KHEAP_END) - foot->size = new_size; + if (iterator == heap->index.size) + return -1; + else + return iterator; } -void free_internal(heap_header_t *heap, void *address) { - heap_header_t *head = (heap_header_t *) ((unsigned int) address - HEAP_S); - if (head == heap) { - warn("can't collapse top of heap"); - head->free = 1; - return; - } +static char header_t_less_than(void *a, void *b) { + return (((header_t *) a)->size < ((header_t *) b)->size) ? 1 : 0; +} - if ((head->magic != KHEAP_MAGIC) || (head->magic2 != KHEAP_MAGIC2)) { - //warn("invalid header in heap"); - //dump_struct(head, sizeof(heap_header_t)); - return; +heap_t *create_heap(uint32_t start, uint32_t end_addr, uint32_t max, unsigned char supervisor, unsigned char 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_footer_t *foot = (heap_footer_t *) ((unsigned int) head + HEAP_S + head->size); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) - panic("bad heap in free() call"); + 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; +} - foot = (heap_footer_t *) ((unsigned int) head - sizeof(heap_footer_t)); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { - //warn("invalid footer in heap"); - return; +void *alloc(uint32_t size, unsigned char page_align, heap_t *heap) { + uint32_t new_size = size + sizeof(header_t) + sizeof(footer_t); + + int 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 = -1; + uint32_t value = 0x0; + while (iterator < heap->index.size) { + uint32_t tmp = (uint32_t) lookup_ordered_array(iterator, &heap->index); + if (tmp > value) { + value = tmp; + idx = iterator; + } + iterator++; + } + + if (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); } - if (foot->size == KHEAP_END) - panic("impossible condition for heap"); + header_t *orig_hole_header = (header_t *) lookup_ordered_array(iterator, &heap->index); + uint32_t orig_hole_pos = (uint32_t) orig_hole_header; + uint32_t orig_hole_size = orig_hole_header->size; - heap = (heap_header_t *) ((unsigned int) foot - foot->size - HEAP_S); - if ((heap->magic != KHEAP_MAGIC) || (heap->magic2 != KHEAP_MAGIC2)) { - warn("invalid parent in heap"); - return; + if (orig_hole_size - new_size < sizeof(header_t) + sizeof(footer_t)) { + size += orig_hole_size - new_size; + new_size = orig_hole_size; } - foot = (heap_footer_t *) ((unsigned int) heap + (heap->size + head->size + HEAP_TOTAL) + HEAP_S); - if ((foot->magic != KHEAP_MAGIC) || (foot->magic2 != KHEAP_MAGIC2)) { - return; + 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(iterator, &heap->index); } - heap->size += head->size + HEAP_TOTAL; - foot->size = heap->size; + 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 *malloc_internal(heap_header_t *heap, size_t size) { - heap = find_sized_heap(heap, size + 8); - heap->free = 0; - split_heap(heap, size); - return (void *) ((unsigned int) heap + HEAP_S); -} +void free(void *p, heap_t *heap) { + if (p == 0) + return; -void init_heap(heap_header_t *heap, size_t size) { - heap->magic = KHEAP_MAGIC; - heap->magic2 = KHEAP_MAGIC2; - heap->free = 1; - heap->size = size - HEAP_TOTAL; + header_t *header = (header_t *) ((uint32_t) p - sizeof(header_t)); + footer_t *footer = (footer_t *) ((uint32_t) header + header->size - sizeof(footer_t)); - heap_footer_t *foot = (heap_footer_t *) ((unsigned int) heap + HEAP_S + heap->size); - foot->magic = KHEAP_MAGIC; - foot->magic2 = KHEAP_MAGIC2; - foot->size = KHEAP_END; -} + assert(header->magic == HEAP_MAGIC); + assert(footer->magic == HEAP_MAGIC); -void *kmalloc(unsigned int size) { - if (kheap == NULL) - return fmalloc(size); + header->is_hole = 1; + char do_add = 1; - return malloc_internal(kheap, size); -} + 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; + } -void kfree(void *address) { - if (kheap == NULL) - return; + 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); + } - free_internal(kheap, address); -} + 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); + } + } -void *umalloc(size_t size) { - return malloc_internal(uheap, size); + if (do_add == 1) + insert_ordered_array((void *) header, &heap->index); } - -void ufree(void *address) { - free_internal(uheap, address); -}
\ No newline at end of file diff --git a/src/kernel/paging/kheap.h b/src/kernel/paging/kheap.h index 7a92957..a1d946c 100644 --- a/src/kernel/paging/kheap.h +++ b/src/kernel/paging/kheap.h @@ -1,51 +1,112 @@ #ifndef MELVIX_KHEAP_H #define MELVIX_KHEAP_H -#include <stdbool.h> -#include <stddef.h> +#include "ordered_array.h" -#define KHEAP_MAGIC 0x13374242 -#define KHEAP_MAGIC2 0xDEADBEEF -#define KHEAP_END 0xFFFFDEAD -#define MEM_END 0x8000000 +#define KHEAP_START 0xC0000000 +#define KHEAP_INITIAL_SIZE 0x100000 -extern unsigned int end; +#define HEAP_INDEX_SIZE 0x20000 +#define HEAP_MAGIC 0x03A93A90 +#define HEAP_MIN_SIZE 0x70000 +/** + * Size information of holes/blocks + */ typedef struct { - unsigned int magic; - bool free; - unsigned int size; - unsigned int magic2; -} heap_header_t; + uint32_t magic; + unsigned char is_hole; // 1 if hole + uint32_t size; +} header_t; typedef struct { - unsigned int magic; - unsigned int size; - unsigned int magic2; -} heap_footer_t; + uint32_t magic; + header_t *header; +} footer_t; -#define HEAP_S (sizeof(heap_header_t)) -#define HEAP_TOTAL (sizeof(heap_footer_t) + HEAP_S) -#define HEAP_MINIMUM 1 -#define HEAP_FIND_SIZE (HEAP_TOTAL + HEAP_MINIMUM) - -void init_kheap(); - -void *fmalloc(unsigned int size); - -void *kmalloc(unsigned int size); - -void *kmalloc_a(unsigned int size); - -void kfree(void *ptr); - -void *umalloc(size_t size); - -void ufree(void *address); - -void init_heap(heap_header_t *heap, size_t size); - -#define KHEAP_SIZE 0xFFFFF -#define UHEAP_SIZE 0xFFFFF +typedef struct { + ordered_array_t index; + uint32_t start_address; + uint32_t end_address; + uint32_t max_address; + unsigned char supervisor; + unsigned char readonly; +} heap_t; + +/** + * Create a new heap + * @param start + * @param end + * @param max + * @param supervisor + * @param readonly + * @return The heap pointer + */ +heap_t *create_heap(uint32_t start, uint32_t end, uint32_t max, unsigned char supervisor, unsigned char readonly); + +/** + * Allocate a region of memory + * @param size The size of the memory + * @param page_align Start the block on a page boundary + * @param heap The Heap pointer + * @return + */ +void *alloc(uint32_t size, unsigned char page_align, heap_t *heap); + +/** + * Release an allocated block + * @param p The block + * @param heap The heap + */ +void free(void *p, heap_t *heap); + +/** + * Release an allocated block using kheap + * @param p The block + */ +void kfree(void *p); + +/** + * Allocate a chunk of memory + * @param sz The size of the memory + * @param align Start the block on a page boundary + * @param phys Location of the memory if not 0 + * @return The memory address + */ +uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys); + +/** + * Allocate a page-aligned chunk of memory + * @param sz The size of the memory + * @return The memory address + */ +uint32_t kmalloc_a(uint32_t sz); + +/** + * Allocate a chunk of memory in a physical address + * @param sz The size of the memory + * @param phys The physical address + * @return The memory address + */ +uint32_t kmalloc_p(uint32_t sz, uint32_t *phys); + +/** + * Allocate a page-aligned chunk of memory in a physical address + * @param sz The size of the memory + * @param phys The physical address + * @return The memory address + */ +uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys); + +/** + * Allocate a chunk of memory (non page-aligned and no physical address) + * @param sz The size of the memory + * @return The memory address + */ +uint32_t kmalloc(uint32_t sz); + +/** + General deallocation function. +**/ #endif diff --git a/src/kernel/paging/ordered_array.c b/src/kernel/paging/ordered_array.c new file mode 100644 index 0000000..563a936 --- /dev/null +++ b/src/kernel/paging/ordered_array.c @@ -0,0 +1,66 @@ +#include <stdint.h> +#include "ordered_array.h" +#include "kheap.h" +#include "../lib/lib.h" +#include "../system.h" + +char standard_lessthan_predicate(type_t a, type_t b) { + return (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)); + memory_set(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; + memory_set(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 destroy_ordered_array(ordered_array_t *array) { + kfree(array->array); +} + +void insert_ordered_array(type_t item, ordered_array_t *array) { + assert(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--; +} diff --git a/src/kernel/paging/ordered_array.h b/src/kernel/paging/ordered_array.h new file mode 100644 index 0000000..223ea14 --- /dev/null +++ b/src/kernel/paging/ordered_array.h @@ -0,0 +1,66 @@ +#ifndef MELVIX_ORDERED_ARRAY_H +#define MELVIX_ORDERED_ARRAY_H + +#include <stdint.h> + +/** + * The array can store anything - so a void pointer is used + */ +typedef void *type_t; + +typedef char (*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; + +/** + * A standard less-than predicate + * @param a The first parameter + * @param b The second parameter + * @return Non-zero if the first parameter is bigger than the second + */ +char standard_lessthan_predicate(type_t a, type_t b); + +/** + * Create an ordered array + * @param max_size Maximal size + * @param less_than The less-than predicate + * @return The newly created array + */ +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); + +/** + * Destroy an ordered array + * @param array The ordered array + */ +void destroy_ordered_array(ordered_array_t *array); + +/** + * Add an item into the array + * @param item The item + * @param array The array + */ +void insert_ordered_array(type_t item, ordered_array_t *array); + +/** + * Lookup the item at a specific index + * @param i The index + * @param array The array + * @return + */ +type_t lookup_ordered_array(uint32_t i, ordered_array_t *array); + +/** + * Delete an item at an index from an array + * @param i The index + * @param array The array + */ +void remove_ordered_array(uint32_t i, ordered_array_t *array); + +#endif diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c index 122e4c0..8f95bab 100644 --- a/src/kernel/paging/paging.c +++ b/src/kernel/paging/paging.c @@ -1,158 +1,198 @@ -#include <stddef.h> #include "paging.h" #include "kheap.h" #include "../lib/lib.h" #include "../graphics/graphics.h" -#include "../interrupts/interrupts.h" +#include "../io/io.h" -vpage_dir_t *current_vpage_dir = NULL; -vpage_dir_t *root_vpage_dir = NULL; +page_directory_t *kernel_directory = 0; +page_directory_t *current_directory = 0; +uint32_t *frames; +uint32_t nframes; -page_table_t *get_cr3() { - unsigned int cr3; +extern uint32_t placement_address; +extern heap_t *kheap; - asm volatile ("movl %%cr3, %%eax" : "=a" (cr3)); - return (page_table_t *) cr3; -} - -unsigned int get_cr0() { - unsigned int cr0; +#define INDEX_FROM_BIT(a) (a/(8*4)) +#define OFFSET_FROM_BIT(a) (a%(8*4)) - asm volatile ("movl %%cr0, %%eax" : "=a" (cr0)); - return cr0; +static void 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); } -void set_cr3(vpage_dir_t *dir) { - asm volatile ("movl %%eax, %%cr3"::"a" ((unsigned int) &dir->tables[0])); +static void clear_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); } -void set_cr0(unsigned int new_cr0) { - asm volatile ("movl %%eax, %%cr0"::"a" (new_cr0)); +static uint32_t test_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); + return (frames[idx] & (0x1 << off)); } -void switch_vpage_dir(vpage_dir_t *dir) { - set_cr3(dir); - set_cr0(get_cr0() | 0x80000000); +static uint32_t first_frame() { + 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; + } + } + } + } } -vpage_dir_t *mk_vpage_dir() { - vpage_dir_t *dir = (vpage_dir_t *) kmalloc_a(sizeof(vpage_dir_t)); - - int i; - for (i = 0; i < 1024; i++) - dir->tables[i] = EMPTY_TAB; - - return dir; +void alloc_frame(page_t *page, int is_kernel, int is_writeable) { + if (page->frame != 0) { + return; + } else { + uint32_t idx = first_frame(); + if (idx == (uint32_t) -1) panic("No free frames!"); + set_frame(idx * 0x1000); + page->present = 1; + page->rw = (is_writeable == 1) ? 1 : 0; + page->user = (is_kernel == 1) ? 0 : 1; + page->frame = idx; + } } -page_table_t *mk_vpage_table() { - page_table_t *tab = (page_table_t *) kmalloc_a(sizeof(page_table_t)); - - int i; - for (i = 0; i < 1024; i++) { - tab->pages[i].present = 0; - tab->pages[i].rw = 1; +void free_frame(page_t *page) { + uint32_t frame; + if (!(frame = page->frame)) { + return; + } else { + clear_frame(frame); + page->frame = 0x0; } - - return tab; } -void vpage_map(vpage_dir_t *dir, unsigned int phys, unsigned int virt) { - short id = virt >> 22; - page_table_t *tab = mk_vpage_table(); +void initialise_paging() { + uint32_t mem_end_page = 0x1000000; + nframes = mem_end_page / 0x1000; + frames = (uint32_t *) kmalloc(INDEX_FROM_BIT(nframes)); + memory_set(frames, 0, INDEX_FROM_BIT(nframes)); + + uint32_t phys; + kernel_directory = (page_directory_t *) kmalloc_a(sizeof(page_directory_t)); + memory_set(kernel_directory, 0, sizeof(page_directory_t)); + kernel_directory->physicalAddr = (uint32_t) kernel_directory->tablesPhysical; + + int i = 0; + for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000) + get_page(i, 1, kernel_directory); + + i = 0; + while (i < 0x400000) { + alloc_frame(get_page(i, 1, kernel_directory), 0, 0); + i += 0x1000; + } - dir->tables[id] = ((page_table_t *) ((unsigned int) tab | 3)); + for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000) + alloc_frame(get_page(i, 1, kernel_directory), 0, 0); - int i; - for (i = 0; i < 1024; i++) { - tab->pages[i].frame = phys >> 12; - tab->pages[i].present = 1; - phys += 4096; - } + irq_install_handler(14, page_fault); + switch_page_directory(kernel_directory); + kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0); + current_directory = clone_directory(kernel_directory); + switch_page_directory(current_directory); } -void vpage_map_user(vpage_dir_t *dir, unsigned int phys, unsigned int virt) { - short id = virt >> 22; - page_table_t *tab = mk_vpage_table(); - - dir->tables[id] = ((page_table_t *) ((unsigned int) tab | 3 | 4)); +void switch_page_directory(page_directory_t *dir) { + current_directory = dir; + asm volatile("mov %0, %%cr3"::"r"(dir->physicalAddr)); + uint32_t cr0; + asm volatile("mov %%cr0, %0": "=r"(cr0)); + cr0 |= 0x80000000; + asm volatile("mov %0, %%cr0"::"r"(cr0)); +} - int i; - for (i = 0; i < 1024; i++) { - tab->pages[i].frame = phys >> 12; - tab->pages[i].present = 1; - tab->pages[i].user = 1; - phys += 4096; +page_t *get_page(uint32_t address, int make, page_directory_t *dir) { + address /= 0x1000; + uint32_t table_idx = address / 1024; + + 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); + memory_set(dir->tables[table_idx], 0, 0x1000); + dir->tablesPhysical[table_idx] = tmp | 0x7; + return &dir->tables[table_idx]->pages[address % 1024]; + } else { + return 0; } } -void vpage_fault(struct regs *r) { - asm volatile ("cli"); - - unsigned int no_page = r->err_code & 1; - unsigned int rw = r->err_code & 2; - unsigned int um = r->err_code & 4; - unsigned int re = r->err_code & 8; - unsigned int dc = r->err_code & 16; - - if (dc) terminal_write_line(" (Instruction decode error) "); - if (!no_page) terminal_write_line(" (No page present) "); - if (um) terminal_write_line(" (in user mode) "); - if (rw) terminal_write_line(" (Write permissions) "); - if (re) terminal_write_line(" (RE) "); - - terminal_write_line("\n"); +void page_fault(struct regs *r) { + uint32_t faulting_address; + asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); + + int present = !(r->err_code & 0x1); + int rw = r->err_code & 0x2; + int us = r->err_code & 0x4; + int reserved = r->err_code & 0x8; + int id = r->err_code & 0x10; + + serial_write("Page fault! ( "); + if (present) serial_write("present "); + if (rw) serial_write("read-only "); + if (us) serial_write("user-mode "); + if (reserved) serial_write("reserved "); + serial_write(") at 0x"); + serial_write_hex(faulting_address); + serial_write(" - EIP: "); + serial_write_hex(r->eip); + serial_write("\n"); + panic("Page fault"); } -void page_init() { - current_vpage_dir = mk_vpage_dir(); - root_vpage_dir = current_vpage_dir; +static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) { + page_table_t *table = (page_table_t *) kmalloc_ap(sizeof(page_table_t), physAddr); + memory_set(table, 0, sizeof(page_directory_t)); - unsigned int i; - for (i = 0; i < 0xF0000000; i += PAGE_S) - vpage_map(root_vpage_dir, i, i); - - irq_install_handler(14, vpage_fault); - asm volatile ("cli"); - switch_vpage_dir(root_vpage_dir); -} - -void convert_vpage(vpage_dir_t *kdir) { int i; for (i = 0; i < 1024; i++) { - kdir->tables[i] = (page_table_t *) ((unsigned int) kdir->tables[i] | 4); - - if (((unsigned int) kdir->tables[i]) & 1) { - int j; - for (j = 0; j < 1024; j++) - kdir->tables[i]->pages[j].user = 1; - } + if (!src->pages[i].frame) + continue; + alloc_frame(&table->pages[i], 0, 0); + 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; + extern void copy_page_physical(int a, int b); + copy_page_physical(src->pages[i].frame * 0x1000, table->pages[i].frame * 0x1000); } + return table; } -void dump_page(vpage_dir_t *dir, unsigned int address) { - unsigned short id = address >> 22; - terminal_write_line(&"Index salt ="[(unsigned int) dir->tables[id]]); -} - -vpage_dir_t *copy_user_dir(vpage_dir_t *dir) { - unsigned int i; - - vpage_dir_t *copy = mk_vpage_dir(); - memory_copy(copy, root_vpage_dir, sizeof(vpage_dir_t)); - - for (i = 0; i < 1024; i++) { - if (((unsigned int) dir->tables[i]) & 4) { - //vga_fmt("Found a user page at index %d\n", i); - page_table_t *tab = (page_table_t *) ((unsigned int) dir->tables[i] & 0xFFFFF000); - //vga_fmt("Table at address %X maps to %X\n", (unsigned int) tab, i << 22); - //vga_fmt("Virtually mapped from %X\n", tab->pages[0].frame << 12); - - void *buffer = kmalloc_a(PAGE_S); - memory_copy(buffer, (void *) (tab->pages[0].frame << 12), PAGE_S); - vpage_map_user(copy, (unsigned int) buffer, (unsigned int) i << 22); +page_directory_t *clone_directory(page_directory_t *src) { + uint32_t phys; + page_directory_t *dir = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t), &phys); + memory_set(dir, 0, sizeof(page_directory_t)); + uint32_t offset = (uint32_t) dir->tablesPhysical - (uint32_t) dir; + dir->physicalAddr = phys + offset; + + for (int i = 0; i < 1024; i++) { + if (!src->tables[i]) + continue; + + if (kernel_directory->tables[i] == src->tables[i]) { + dir->tables[i] = src->tables[i]; + dir->tablesPhysical[i] = src->tablesPhysical[i]; + } else { + uint32_t phys; + dir->tables[i] = clone_table(src->tables[i], &phys); + dir->tablesPhysical[i] = phys | 0x07; } } - - return copy; -}
\ No newline at end of file + return dir; +} diff --git a/src/kernel/paging/paging.h b/src/kernel/paging/paging.h index 790dbee..51f407f 100644 --- a/src/kernel/paging/paging.h +++ b/src/kernel/paging/paging.h @@ -1,63 +1,64 @@ #ifndef MELVIX_PAGING_H #define MELVIX_PAGING_H -#define PAGE_S 0x400000 - -extern unsigned int *current_dir; -extern unsigned int *root_dir; - -typedef struct { - unsigned int present : 1; - unsigned int rw : 1; - unsigned int user : 1; - unsigned int accessed : 1; - unsigned int dirty : 1; - unsigned int unused : 7; - unsigned int frame : 20; +#include <stdint.h> +#include "../interrupts/interrupts.h" + +typedef struct page { + uint32_t present : 1; // Page present in memory + uint32_t rw : 1; // Read-only if clear, readwrite if set + uint32_t user : 1; // Supervisor level only if clear + uint32_t accessed : 1; // Has the page been accessed since last refresh? + uint32_t dirty : 1; // Has the page been written to since last refresh? + uint32_t unused : 7; // Amalgamation of unused and reserved bits + uint32_t frame : 20; // Frame address (shifted right 12 bits) } page_t; -typedef struct { +typedef struct page_table { page_t pages[1024]; } page_table_t; -typedef struct { +typedef struct page_directory { page_table_t *tables[1024]; - unsigned int tables_physical[1024]; - unsigned int physical_address; + uint32_t tablesPhysical[1024]; + uint32_t physicalAddr; } page_directory_t; -typedef struct { - page_table_t *tables[1024]; -} vpage_dir_t; - -extern vpage_dir_t *root_vpage_dir; - -#define EMPTY_TAB ((page_table_t*) 0x00000002) - -page_table_t *get_cr3(); - -unsigned int get_cr0(); - -void set_cr3(vpage_dir_t *dir); - -void set_cr0(unsigned int new_cr0); - -void switch_vpage_dir(vpage_dir_t *dir); - -vpage_dir_t *mk_vpage_dir(); - -page_table_t *mk_vpage_table(); - -void page_init(); - -void vpage_map(vpage_dir_t *cr3, unsigned int virt, unsigned int phys); - -void vpage_map_user(vpage_dir_t *cr3, unsigned int virt, unsigned int phys); - -void convert_vpage(vpage_dir_t *kdir); - -void dump_page(vpage_dir_t *dir, unsigned int address); - -vpage_dir_t *copy_user_dir(vpage_dir_t *dir); +/** + * Initialize the environment and enables paging + */ +void initialise_paging(); + +/** + * Load the page directory into the CR3 register + * @param new The page directory + */ +void switch_page_directory(page_directory_t *new); + +/** + * Get a specific page pointer + * @param address The page address + * @param make If 1 create the page first + * @param dir The page directory + * @return The page pointer + */ +page_t *get_page(uint32_t address, int make, page_directory_t *dir); + +/** + * Page fault handler + * @param r The IRQ registers + */ +void page_fault(struct regs *r); + +void alloc_frame(page_t *page, int is_kernel, int is_writeable); + +void free_frame(page_t *page); + +/** + * Copy/clone a page directory + * @param src The page directory + * @return A new page directory pointer + */ +page_directory_t *clone_directory(page_directory_t *src); #endif diff --git a/src/kernel/system.h b/src/kernel/system.h index 8cd4244..53e567d 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -121,7 +121,7 @@ static inline void panic(char *msg) { terminal_write_string("PANIC: "); terminal_write_string(msg); terminal_write_string(" - System Halted!"); - write_serial(msg); + serial_write(msg); loop: asm volatile ("hlt"); goto loop; |