diff options
author | Anton Kling <anton@kling.gg> | 2024-04-11 17:22:00 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-04-11 17:23:39 +0200 |
commit | ca082f686fd2dc7ee6f0284421f6212d6d4acee8 (patch) | |
tree | 493b1047661174816f0d1d300952e40e2846b24b /kernel | |
parent | e25a47fcc4db09ab9b845a691297da67243e6049 (diff) |
bug fixes
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/arch/i386/mmu.c | 24 | ||||
-rw-r--r-- | kernel/cpu/syscall.c | 2 | ||||
-rw-r--r-- | kernel/fs/ext2.c | 5 | ||||
-rw-r--r-- | kernel/fs/shm.c | 14 | ||||
-rw-r--r-- | kernel/includes/mmu.h | 7 |
5 files changed, 27 insertions, 25 deletions
diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c index 7147c74..53b2156 100644 --- a/kernel/arch/i386/mmu.c +++ b/kernel/arch/i386/mmu.c @@ -8,7 +8,6 @@ #define INDEX_FROM_BIT(a) (a / (32)) #define OFFSET_FROM_BIT(a) (a % (32)) -#define PAGE_SIZE ((uintptr_t)0x1000) #define PAGE_ALLOCATE 1 #define PAGE_NO_ALLOCATE 0 @@ -107,6 +106,7 @@ Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, Page *p = &directory->tables[table_index]->pages[address % 1024]; if (create_new_page) { p->present = 0; + p->user = set_user; } return &directory->tables[table_index]->pages[address % 1024]; } @@ -120,19 +120,6 @@ void mmu_free_pages(void *a, u32 n) { } } -void *next_page(void *ptr) { - uintptr_t a = (uintptr_t)ptr; - return (void *)(a + (PAGE_SIZE - ((u32)a & (PAGE_SIZE - 1)))); -} - -void *align_page(void *a) { - if ((uintptr_t)a & (PAGE_SIZE - 1)) { - return next_page(a); - } - - return a; -} - u32 first_free_frame(void) { u32 i = 1; for (; i < INDEX_FROM_BIT(num_array_frames * 32); i++) { @@ -329,7 +316,13 @@ int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags, pd = (pd) ? pd : get_active_pagedirectory(); size_t num_pages = n / 0x1000; for (size_t i = 0; i <= num_pages; i++) { - Page *p = get_page((void *)(ptr + i * 0x1000), pd, PAGE_ALLOCATE, 1); + Page *p = get_page((void *)(ptr + i * 0x1000), pd, 0, 0); + if (p && p->present) { + p->rw = (flags & MMU_FLAG_RW); + p->user = !(flags & MMU_FLAG_KERNEL); + continue; + } + p = get_page((void *)(ptr + i * 0x1000), pd, PAGE_ALLOCATE, 1); assert(p); int rw = (flags & MMU_FLAG_RW); int kernel = (flags & MMU_FLAG_KERNEL); @@ -338,6 +331,7 @@ int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags, return 0; } } + flush_tlb(); return 1; } diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c index 6789628..d3da640 100644 --- a/kernel/cpu/syscall.c +++ b/kernel/cpu/syscall.c @@ -110,8 +110,6 @@ int syscall_getpid(void) { return current_task->pid; } -void *align_page(void *a); - int syscall_brk(void *addr) { void *end = current_task->data_segment_end; if (!mmu_allocate_region(end, addr - end, MMU_FLAG_RW, NULL)) { diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index e815e79..9a3560f 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -1,6 +1,7 @@ #include <assert.h> #include <fs/ext2.h> #include <fs/vfs.h> +#include <math.h> #include <string.h> #include <sys/stat.h> #include <typedefs.h> @@ -251,8 +252,8 @@ int ext2_read_dir(int dir_inode, u8 *buffer, size_t len, size_t offset) { u8 *p = (u8 *)&tmp_entry; size_t l = sizeof(struct dirent); - l = (len < l) ? len : l; - memcpy(buffer, p, l); + l = min(len - rc, l); + memcpy(buffer + rc, p, l); len -= l; rc += l; } diff --git a/kernel/fs/shm.c b/kernel/fs/shm.c index 7eec825..2a2995b 100644 --- a/kernel/fs/shm.c +++ b/kernel/fs/shm.c @@ -54,9 +54,17 @@ vfs_vm_object_t *shm_get_vm_object(u64 length, u64 offset, vfs_fd_t *fd) { int shm_ftruncate(vfs_fd_t *fd, size_t length) { vfs_vm_object_t *p = fd->inode->internal_object; + if (p->real_pointer) { + u8 *mem_region = p->real_pointer; + mmu_free_address_range(mem_region, align_page(p->size), NULL); + } + + p->real_pointer = mmu_find_unallocated_virtual_range(NULL, length); + mmu_allocate_region(p->real_pointer, length, MMU_FLAG_RW, NULL); p->size = length; - p->real_pointer = krealloc(p->real_pointer, length + 0x2000); - p->virtual_object = align_page(p->real_pointer); + + p->virtual_object = p->real_pointer; + int n = (uintptr_t)align_page((void *)(u32)length) / 0x1000; p->object = krealloc(p->object, sizeof(void *) * n); for (int i = 0; i < n; i++) { @@ -72,8 +80,6 @@ int shm_open(const char *name, int oflag, mode_t mode) { vfs_vm_object_t *internal_object = hashmap_get_entry(shared_memory_objects, name); if (!internal_object) { - // if (!(oflag & O_CREAT)) - // return -EMFILE; internal_object = kcalloc(1, sizeof(vfs_vm_object_t)); hashmap_add_entry(shared_memory_objects, name, internal_object, NULL, 0); } diff --git a/kernel/includes/mmu.h b/kernel/includes/mmu.h index 9a27c5b..43814d5 100644 --- a/kernel/includes/mmu.h +++ b/kernel/includes/mmu.h @@ -9,8 +9,11 @@ typedef u8 mmu_flags; #define MMU_FLAG_RW (1 << 0) #define MMU_FLAG_KERNEL (1 << 1) -void *next_page(void *a); -void *align_page(void *a); +#define PAGE_SIZE ((uintptr_t)0x1000) +#define next_page(_ptr) \ + ((_ptr) + (PAGE_SIZE - (((uintptr_t)_ptr) & (PAGE_SIZE - 1)))) +#define align_page(_ptr) \ + (((((uintptr_t)_ptr) & (PAGE_SIZE - 1)) > 0) ? next_page((_ptr)) : (_ptr)) typedef struct Page { u32 present : 1; |