aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/fs/elf.c60
-rw-r--r--src/kernel/interrupts/isr.c2
-rw-r--r--src/kernel/io/io.c5
-rw-r--r--src/kernel/io/io.h1
-rw-r--r--src/kernel/memory/paging.c12
-rw-r--r--src/kernel/memory/paging.h2
-rw-r--r--src/kernel/syscall/actions/sys_wait.c4
-rw-r--r--src/kernel/tasks/process.c62
-rw-r--r--src/kernel/tasks/process.h5
-rw-r--r--src/kernel/tasks/userspace.asm4
-rw-r--r--src/kernel/tasks/userspace.c59
-rw-r--r--src/kernel/tasks/userspace.h17
-rw-r--r--src/userspace/programs/init.c2
13 files changed, 93 insertions, 142 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c
index 7b95c3b..f6cdecb 100644
--- a/src/kernel/fs/elf.c
+++ b/src/kernel/fs/elf.c
@@ -34,7 +34,6 @@ struct process *elf_load(char *path)
}
struct elf_header *header = (struct elf_header *)file;
- struct elf_program_header *program_header = (void *)header + header->phoff;
if (!is_elf(header)) {
warn("File not valid: %s", path);
@@ -44,35 +43,46 @@ struct process *elf_load(char *path)
}
struct process *proc = process_make_new();
- strcpy(proc->name, path);
- proc->registers.eip = header->entry;
+ paging_switch_dir(proc->cr3);
- //paging_switch_directory(proc->cr3);
- u32 stk = (u32)valloc(PAGE_SIZE);
+ u32 image_low = 0xFFFFFFFF;
+ u32 image_high = 0;
- proc->registers.useresp = 0x40000000 - (PAGE_SIZE / 2);
- proc->registers.ebp = proc->registers.useresp;
- proc->registers.esp = proc->registers.useresp;
- //paging_map_user(stk, 0x40000000 - PAGE_SIZE);
+ // Parse ELF
+ for (u32 i = 0; i < header->shentsize * header->shnum; i += header->shentsize) {
+ struct elf_section_header *sh = (void *)header + (header->shoff + i);
+ if (sh->addr != 0) {
+ log("%x", sh->addr);
+ for (u32 j = 0; j < sh->size; j += PAGE_SIZE) {
+ paging_frame_alloc(paging_get_page(sh->addr + j, proc->cr3));
+ invlpg(sh->addr + j);
+ j += PAGE_SIZE;
+ }
- for (int i = 0; i < header->phnum; i++, program_header++) {
- switch (program_header->type) {
- case 0:
- break;
- case 1: {
- u32 loc = (u32)valloc(PAGE_SIZE);
- //paging_map_user(loc, program_header->vaddr);
- memcpy((void *)program_header->vaddr,
- ((void *)((u32)file) + program_header->offset),
- program_header->filesz);
- assert(program_header->filesz <= PAGE_SIZE);
- break;
- }
- default:
- warn("Unknown header type");
+ if (sh->type == 8) // Is .bss
+ memset(sh->addr, 0, sh->size);
+ else
+ memcpy(sh->addr, header + sh->offset, sh->size);
+
+ if (sh->addr < image_low)
+ image_low = sh->addr;
+
+ if (sh->addr + sh->size > image_high)
+ image_high = sh->addr + sh->size;
}
}
- /* paging_switch_directory(page_tables); */
+ // Stack
+ struct page_table_entry *stack_page = paging_get_page(0x400000, proc->cr3);
+ paging_frame_alloc(stack_page);
+ stack_page->writable = 1;
+ invlpg(0x400000);
+
+ strcpy(proc->name, path);
+ proc->brk = image_high;
+ proc->regs.eip = header->entry;
+ proc->regs.esp = 0x401000;
+ proc->regs.useresp = 0x401000;
+
return proc;
} \ No newline at end of file
diff --git a/src/kernel/interrupts/isr.c b/src/kernel/interrupts/isr.c
index 73e24a3..ae72a0f 100644
--- a/src/kernel/interrupts/isr.c
+++ b/src/kernel/interrupts/isr.c
@@ -128,7 +128,7 @@ void fault_handler(struct regs *r)
if (current_proc != NULL) {
warn("%s: Suspending process %s with ID %d", message, current_proc->name,
current_proc->pid);
- memcpy(&current_proc->registers, r, sizeof(struct regs));
+ memcpy(&current_proc->regs, r, sizeof(struct regs));
process_suspend(current_proc->pid);
process_force_switch();
} else {
diff --git a/src/kernel/io/io.c b/src/kernel/io/io.c
index af5f008..1ef82b6 100644
--- a/src/kernel/io/io.c
+++ b/src/kernel/io/io.c
@@ -98,6 +98,11 @@ void cr0_set(u32 cr0)
asm volatile("movl %%eax, %%cr0" ::"a"(cr0));
}
+void invlpg(u32 addr)
+{
+ asm volatile("invlpg (%0)" ::"r"(addr) : "memory");
+}
+
void serial_install()
{
outb(0x3f8 + 1, 0x00);
diff --git a/src/kernel/io/io.h b/src/kernel/io/io.h
index ce3c72b..9274dfb 100644
--- a/src/kernel/io/io.h
+++ b/src/kernel/io/io.h
@@ -55,6 +55,7 @@ u32 cr3_get();
void cr3_set(u32 cr3);
u32 cr0_get();
void cr0_set(u32 cr0);
+void invlpg(u32 addr);
/**
* Initialize the serial conenction
diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c
index 1d9f6b1..e2c48b8 100644
--- a/src/kernel/memory/paging.c
+++ b/src/kernel/memory/paging.c
@@ -1,5 +1,6 @@
#include <io/io.h>
#include <lib/lib.h>
+#include <memory/alloc.h>
#include <memory/mmap.h>
#include <memory/paging.h>
#include <stdint.h>
@@ -27,9 +28,16 @@ void paging_install()
kernel_page_directory->entries[0].writable = 1;
kernel_page_directory->entries[0].address = SHIFT((u32)page_table);
- paging_switch_directory((u32)kernel_page_directory);
+ paging_switch_dir((u32)kernel_page_directory);
paging_enable();
info("Installed paging");
+
+ // Test mallocing
+ u32 *c = malloc(2048);
+ c[42] = 0x4242;
+ assert(c[42] == 0x4242);
+ free(c);
+ info("Malloc test succeeded!");
}
void paging_disable()
@@ -48,7 +56,7 @@ void paging_enable()
paging_enabled = 1;
}
-void paging_switch_directory(u32 dir)
+void paging_switch_dir(u32 dir)
{
cr3_set(dir);
}
diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h
index ac0dbfa..af7d4a2 100644
--- a/src/kernel/memory/paging.h
+++ b/src/kernel/memory/paging.h
@@ -49,7 +49,7 @@ struct page_dir {
void paging_install();
void paging_enable();
void paging_disable();
-void paging_switch_directory(u32 dir);
+void paging_switch_dir(u32 dir);
struct page_table_entry *paging_get_page(u32 address, struct page_dir *page_dir);
void paging_frame_alloc(struct page_table_entry *page);
diff --git a/src/kernel/syscall/actions/sys_wait.c b/src/kernel/syscall/actions/sys_wait.c
index 01deef3..23d4639 100644
--- a/src/kernel/syscall/actions/sys_wait.c
+++ b/src/kernel/syscall/actions/sys_wait.c
@@ -4,7 +4,7 @@
u32 sys_wait(u32 pid, u32 *status, u32 options)
{
- if (pid > 0)
- return process_wait_pid(pid, status);
+ /* if (pid > 0) */
+ /* return process_wait_pid(pid, status); */
return -1;
} \ No newline at end of file
diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c
index 0b13b6b..a4c1c79 100644
--- a/src/kernel/tasks/process.c
+++ b/src/kernel/tasks/process.c
@@ -8,7 +8,6 @@
#include <stdint.h>
#include <system.h>
#include <tasks/process.h>
-#include <tasks/userspace.h>
#include <timer/timer.h>
u32 pid = 0;
@@ -36,7 +35,7 @@ void scheduler(struct regs *regs)
}
serial_put('+');
- memcpy(&current_proc->registers, regs, sizeof(struct regs));
+ memcpy(&current_proc->regs, regs, sizeof(struct regs));
timer_handler(regs);
@@ -55,10 +54,18 @@ void scheduler(struct regs *regs)
}
}
- memcpy(regs, &current_proc->registers, sizeof(struct regs));
- paging_switch_directory(current_proc->cr3);
+ memcpy(regs, &current_proc->regs, sizeof(struct regs));
+ paging_switch_dir(current_proc->cr3);
+ if (regs->cs != 0x1B) {
+ regs->gs = 0x23;
+ regs->fs = 0x23;
+ regs->es = 0x23;
+ regs->ds = 0x23;
+ regs->cs = 0x1B;
+ regs->ss = 0x23;
+ }
+
locked = 0;
- cli();
}
void process_force_switch()
@@ -68,6 +75,9 @@ void process_force_switch()
//scheduler(regs);
}
+u32 hl_cr3;
+u32 hl_eip;
+u32 hl_esp;
void process_init(struct process *proc)
{
log("Initializing process %d", pid);
@@ -78,7 +88,15 @@ void process_init(struct process *proc)
current_proc = root;
irq_install_handler(0, scheduler);
- userspace_enter(proc);
+
+ hl_eip = proc->regs.eip;
+ hl_esp = proc->regs.esp;
+ //paging_switch_dir(proc->cr3);
+
+ debug("Jumping to userspace!");
+ extern void userspace_jump();
+ userspace_jump();
+ panic("This should not happen!");
}
// Only for debugging purposes
@@ -113,25 +131,6 @@ u32 process_spawn(struct process *process)
return process->pid;
}
-u32 process_wait_pid(u32 pid, u32 *status)
-{
- struct process *i = current_proc->next;
-
- while (i != NULL) {
- if (i->pid == pid) {
- if (i->state == PROC_ASLEEP) {
- *status = i->registers.ebx;
- return i->pid;
- } else {
- return WAIT_OKAY;
- }
- }
- i = i->next;
- }
-
- return WAIT_ERROR;
-}
-
void process_suspend(u32 pid)
{
debug("Suspending process %d", pid);
@@ -175,15 +174,20 @@ struct process *process_from_pid(u32 pid)
return PID_NOT_FOUND;
}
+void no_entry()
+{
+ panic("No entry point given!");
+}
+
struct process *process_make_new()
{
debug("Making new process %d", pid);
struct process *proc = (struct process *)valloc(sizeof(struct process));
- proc->registers.cs = 0x1B;
- proc->registers.ds = 0x23;
- proc->registers.ss = 0x23;
+ proc->regs.cs = 0x1B;
+ proc->regs.ds = 0x23;
+ proc->regs.ss = 0x23;
+ proc->regs.eip = no_entry;
proc->cr3 = paging_make_dir();
- proc->brk = 0x50000000;
proc->pid = pid++;
return proc;
}
diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h
index 5c72e64..493dbe5 100644
--- a/src/kernel/tasks/process.h
+++ b/src/kernel/tasks/process.h
@@ -14,7 +14,7 @@ struct mmap {
struct process {
u32 cr3;
- struct regs registers;
+ struct regs regs;
u32 pid;
char name[256];
@@ -35,9 +35,6 @@ u32 process_spawn(struct process *process);
void process_suspend(u32 pid);
void process_wake(u32 pid);
-u32 process_wait_gid(u32 gid, u32 *status);
-u32 process_wait_pid(u32 pid, u32 *status);
-
struct process *process_from_pid(u32 pid);
void process_init(struct process *proc);
diff --git a/src/kernel/tasks/userspace.asm b/src/kernel/tasks/userspace.asm
index ebdcf26..6881bdf 100644
--- a/src/kernel/tasks/userspace.asm
+++ b/src/kernel/tasks/userspace.asm
@@ -1,9 +1,9 @@
-global jump_userspace
+global userspace_jump
extern hl_cr3
extern hl_esp
extern hl_eip
-jump_userspace:
+userspace_jump:
mov ax, 0x23
mov ds, ax
mov es, ax
diff --git a/src/kernel/tasks/userspace.c b/src/kernel/tasks/userspace.c
deleted file mode 100644
index 3164965..0000000
--- a/src/kernel/tasks/userspace.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <interrupts/interrupts.h>
-#include <io/io.h>
-#include <lib/lib.h>
-#include <memory/paging.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <system.h>
-#include <tasks/process.h>
-#include <tasks/userspace.h>
-
-struct process *proc_bottom = NULL;
-
-u32 hl_cr3;
-u32 hl_eip;
-u32 hl_esp;
-
-u32 spawn_child(struct process *child)
-{
- return (u32)-1;
-}
-
-void userspace_enter(struct process *proc)
-{
- proc_bottom = proc;
- hl_eip = proc->registers.eip;
- hl_esp = proc->registers.esp;
- paging_switch_directory(proc->cr3);
-
- //debug("Jumping to userspace!");
- jump_userspace();
-}
-
-void single_yield(struct process *proc, struct regs *regs)
-{
- memcpy(&proc_bottom->registers, regs, sizeof(struct regs));
-
- if (proc == proc_bottom)
- panic("Can't return from parent process");
-
- proc->next = proc_bottom;
- proc_bottom = proc;
-
- memcpy(regs, &proc->registers, sizeof(struct regs));
- paging_switch_directory(proc->cr3);
-}
-
-u32 single_exit(struct regs *regs)
-{
- u32 hold = regs->ebx;
- proc_bottom = proc_bottom->next;
-
- if (proc_bottom == NULL)
- panic("Return from process with no parent");
-
- memcpy(regs, &proc_bottom->registers, sizeof(struct regs));
- paging_switch_directory(proc_bottom->cr3);
-
- return hold;
-} \ No newline at end of file
diff --git a/src/kernel/tasks/userspace.h b/src/kernel/tasks/userspace.h
deleted file mode 100644
index d66ba54..0000000
--- a/src/kernel/tasks/userspace.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef MELVIX_USERSPACE_H
-#define MELVIX_USERSPACE_H
-
-#include <interrupts/interrupts.h>
-#include <stdint.h>
-#include <tasks/process.h>
-
-u32 spawn_child(struct process *child);
-
-void userspace_enter(struct process *proc);
-
-void single_yield(struct process *proc, struct regs *regs);
-u32 single_exit(struct regs *regs);
-
-extern void jump_userspace();
-
-#endif \ No newline at end of file
diff --git a/src/userspace/programs/init.c b/src/userspace/programs/init.c
index 51aea63..8e5887f 100644
--- a/src/userspace/programs/init.c
+++ b/src/userspace/programs/init.c
@@ -21,6 +21,8 @@ int interrupts_enabled()
void main()
{
+ while (1) {
+ };
if (get_pid() != 1) {
printf("Wrong PID!\n");
exit(1);