summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-04-11 17:22:00 +0200
committerAnton Kling <anton@kling.gg>2024-04-11 17:23:39 +0200
commitca082f686fd2dc7ee6f0284421f6212d6d4acee8 (patch)
tree493b1047661174816f0d1d300952e40e2846b24b /kernel
parente25a47fcc4db09ab9b845a691297da67243e6049 (diff)
bug fixes
Diffstat (limited to 'kernel')
-rw-r--r--kernel/arch/i386/mmu.c24
-rw-r--r--kernel/cpu/syscall.c2
-rw-r--r--kernel/fs/ext2.c5
-rw-r--r--kernel/fs/shm.c14
-rw-r--r--kernel/includes/mmu.h7
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;