diff options
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/features/load.c | 18 | ||||
-rw-r--r-- | kernel/features/mm.c (renamed from kernel/features/memory.c) | 10 | ||||
-rw-r--r-- | kernel/features/proc.c | 20 | ||||
-rw-r--r-- | kernel/features/syscall.c | 2 | ||||
-rw-r--r-- | kernel/inc/mm.h (renamed from kernel/inc/memory.h) | 7 | ||||
-rw-r--r-- | kernel/inc/proc.h | 8 | ||||
-rw-r--r-- | kernel/main.c | 2 |
8 files changed, 50 insertions, 19 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 6763185..2db201b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -10,7 +10,7 @@ COBJS = main.o \ drivers/ide.o \ drivers/timer.o \ drivers/rtl8139.o \ - features/memory.o \ + features/mm.o \ features/fs.o \ features/load.o \ features/proc.o \ diff --git a/kernel/features/load.c b/kernel/features/load.c index 8a4aae3..610abf8 100644 --- a/kernel/features/load.c +++ b/kernel/features/load.c @@ -3,14 +3,19 @@ #include <fs.h> #include <load.h> #include <mem.h> +#include <mm.h> #include <str.h> +#define PROC_STACK_SIZE 0x4000 + void proc_load(struct proc *proc, void *data) { - u32 stack = (u32)malloc(0x2000) + 0x1000; + u32 stack; + memory_alloc(proc->page_dir, PROC_STACK_SIZE, MEMORY_CLEAR, &stack); + u32 ptr = stack + PROC_STACK_SIZE - 1; - proc->regs.ebp = (u32)stack; - proc->regs.useresp = (u32)stack; + proc->regs.ebp = (u32)ptr; + proc->regs.useresp = (u32)ptr; proc->regs.eip = (u32)data; proc->entry = (u32)data; } @@ -19,12 +24,13 @@ int bin_load(const char *path, struct proc *proc) { struct stat s = { 0 }; vfs_stat(path, &s); - char *data = malloc(s.size); - if (!vfs_read(path, data, 0, s.size)) + u32 data; + memory_alloc(proc->page_dir, PAGE_ALIGN_UP(s.size), MEMORY_CLEAR, &data); + if (!vfs_read(path, (void *)data, 0, s.size)) return 1; strcpy(proc->name, path); - proc_load(proc, data); + proc_load(proc, (void *)data); return 0; } diff --git a/kernel/features/memory.c b/kernel/features/mm.c index 7813c56..ccc2727 100644 --- a/kernel/features/memory.c +++ b/kernel/features/mm.c @@ -5,7 +5,7 @@ #include <cpu.h> #include <def.h> #include <mem.h> -#include <memory.h> +#include <mm.h> #include <print.h> @@ -369,6 +369,11 @@ void memory_dir_switch(struct page_dir *dir) paging_switch_dir(virtual_to_physical(&kernel_dir, (u32)dir)); } +struct page_dir *memory_kernel_dir(void) +{ + return &kernel_dir; +} + void memory_initialize(struct mem_info *mem_info) { for (u32 i = 0; i < 256; i++) { @@ -413,6 +418,9 @@ void memory_initialize(struct mem_info *mem_info) memory_map_identity(&kernel_dir, memory_range_around_address(HEAP_START, HEAP_INIT_SIZE), MEMORY_NONE); + // TODO: Map something, idk? Triple fault prevention? + memory_map_identity(&kernel_dir, memory_range_around_address(0x7000, 0x1000), MEMORY_NONE); + // Unmap NULL byte/page virtual_free(&kernel_dir, memory_range(0, PAGE_SIZE)); physical_set_used(0, 1); diff --git a/kernel/features/proc.c b/kernel/features/proc.c index cdbe8b1..bbe675e 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -6,6 +6,7 @@ #include <fs.h> #include <load.h> #include <mem.h> +#include <mm.h> #include <print.h> #include <proc.h> #include <stack.h> @@ -57,6 +58,7 @@ void scheduler(struct regs *regs) } memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs)); + memory_dir_switch(((struct proc *)current->data)->page_dir); if (regs->cs != GDT_USER_CODE_OFFSET) { regs->gs = GDT_USER_DATA_OFFSET; @@ -103,7 +105,7 @@ u8 proc_super(void) { struct proc *proc = proc_current(); if (proc) - return proc->super; + return proc->priv == PROC_PRIV_ROOT || proc->priv == PROC_PRIV_KERNEL; else if (current_pid == 0) return 1; // Kernel has super permissions else @@ -237,14 +239,19 @@ end: p->state = PROC_SLEEPING; } -struct proc *proc_make(void) +struct proc *proc_make(enum proc_priv priv) { struct proc *proc = zalloc(sizeof(*proc)); proc->pid = current_pid++; - proc->super = 0; + proc->priv = priv; proc->messages = stack_new(); proc->state = PROC_RUNNING; + if (priv == PROC_PRIV_KERNEL) + proc->page_dir = memory_kernel_dir(); + else + proc->page_dir = memory_dir_create(); + if (current) list_add(proc_list, proc); @@ -465,20 +472,20 @@ void proc_init(void) vfs_mount(dev, "/proc/"); // Idle proc - struct proc *kernel_proc = proc_make(); + struct proc *kernel_proc = proc_make(PROC_PRIV_NONE); void (*func)(void) = kernel_idle; proc_load(kernel_proc, *(void **)&func); strcpy(kernel_proc->name, "idle"); kernel_proc->state = PROC_SLEEPING; idle_proc = list_add(proc_list, kernel_proc); - struct node *new = list_add(proc_list, proc_make()); + // Init proc (root) + struct node *new = list_add(proc_list, proc_make(PROC_PRIV_ROOT)); bin_load("/bin/init", new->data); current = new; _eip = ((struct proc *)new->data)->regs.eip; _esp = ((struct proc *)new->data)->regs.useresp; - ((struct proc *)new->data)->super = 1; u32 argc = 2; char **argv = malloc(sizeof(*argv) * (argc + 1)); @@ -491,6 +498,7 @@ void proc_init(void) printf("Jumping to userspace!\n"); proc_jump_userspace(); + memory_dir_switch(((struct proc *)new->data)->page_dir); while (1) { }; } diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 61c7479..b3e69e0 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -62,7 +62,7 @@ static void syscall_handler(struct regs *r) } case SYS_EXEC: { char *path = (char *)r->ebx; - struct proc *proc = proc_make(); + struct proc *proc = proc_make(PROC_PRIV_NONE); r->eax = (u32)bin_load(path, proc); u32 argc = 3; // TODO: Add argc evaluator char **argv = malloc(sizeof(*argv) * (argc + 1)); diff --git a/kernel/inc/memory.h b/kernel/inc/mm.h index 812b052..00d9e4b 100644 --- a/kernel/inc/memory.h +++ b/kernel/inc/mm.h @@ -18,6 +18,8 @@ #define PAGE_COUNT 1024 #define PAGE_ALIGN(x) ((x) + PAGE_SIZE - ((x) % PAGE_SIZE)) #define PAGE_ALIGNED(x) ((x) % PAGE_SIZE == 0) +#define PAGE_ALIGN_UP(x) (((x) % PAGE_SIZE == 0) ? (x) : (x) + PAGE_SIZE - ((x) % PAGE_SIZE)) +#define PAGE_ALIGN_DOWN(x) ((x) - ((x) % PAGE_SIZE)) union page_table_entry { struct PACKED { @@ -77,4 +79,9 @@ struct memory_range { u32 size; }; +struct page_dir *memory_dir_create(void); +void memory_dir_switch(struct page_dir *dir); +void memory_alloc(struct page_dir *dir, u32 size, u32 flags, u32 *out); +struct page_dir *memory_kernel_dir(void); + #endif diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h index 272a3ac..de4eb84 100644 --- a/kernel/inc/proc.h +++ b/kernel/inc/proc.h @@ -9,7 +9,7 @@ #include <stack.h> #include <sys.h> -#define PROC_QUANTUM 10 // Milliseconds or something // TODO +#define PROC_QUANTUM 42 // Milliseconds or something // TODO #define EFLAGS_ALWAYS 0x2 // Always one #define EFLAGS_INTERRUPTS 0x200 // Enable interrupts @@ -23,6 +23,7 @@ #define STREAM_MAX_SIZE 4096 enum stream_defaults { STREAM_IN, STREAM_OUT, STREAM_ERR, STREAM_LOG, STREAM_UNKNOWN = -1 }; +enum proc_priv { PROC_PRIV_NONE, PROC_PRIV_ROOT, PROC_PRIV_KERNEL }; enum proc_state { PROC_RUNNING, PROC_SLEEPING }; enum proc_wait_type { PROC_WAIT_DEV, PROC_WAIT_MSG }; @@ -47,9 +48,10 @@ struct stream { struct proc { u32 pid; u32 entry; - u8 super; + u8 priv; char name[32]; struct stream streams[4]; + struct page_dir *page_dir; struct regs regs; struct proc_wait wait; // dev_id enum proc_state state; @@ -67,6 +69,6 @@ void proc_yield(struct regs *r); void proc_clear_quantum(void); void proc_enable_waiting(u32 id, enum proc_wait_type type); void proc_wait_for(u32 id, enum proc_wait_type type, u32 func_ptr); -struct proc *proc_make(void); +struct proc *proc_make(enum proc_priv priv); #endif diff --git a/kernel/main.c b/kernel/main.c index 16ae619..b46db0d 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -7,7 +7,7 @@ #include <interrupts.h> #include <keyboard.h> #include <load.h> -#include <memory.h> +#include <mm.h> #include <mouse.h> #include <net.h> #include <pci.h> |