summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpu/idt.S23
-rw-r--r--kernel/include/comus/cpu.h5
-rw-r--r--kernel/include/comus/procs.h2
-rw-r--r--kernel/include/comus/syscalls.h3
-rw-r--r--kernel/main.c13
-rw-r--r--kernel/memory/paging.c4
-rw-r--r--kernel/memory/physalloc.c12
-rw-r--r--kernel/memory/virtalloc.c14
-rw-r--r--kernel/procs.c7
-rw-r--r--kernel/syscall.c26
-rw-r--r--kernel/user.c4
11 files changed, 79 insertions, 34 deletions
diff --git a/kernel/cpu/idt.S b/kernel/cpu/idt.S
index 177d3b1..06c70a0 100644
--- a/kernel/cpu/idt.S
+++ b/kernel/cpu/idt.S
@@ -1,5 +1,5 @@
.global isr_stub_table
- .global isr_restore
+ .global syscall_return
.global awd
.extern idt_exception_handler
@@ -8,6 +8,7 @@
.extern idt_pic_mouse
.extern idt_pic_eoi
.extern syscall_handler
+ .extern current_pcb
.macro PUSHALL
pushq %rax
@@ -88,7 +89,7 @@ isr_stub_\num:
cld
movq %rsp, %rdi # top of stack
callq syscall_handler
- jmp isr_restore
+ jmp syscall_return
.endm
.macro PICGeneric num
@@ -419,12 +420,18 @@ isr_stub_table:
.code64
# isr restore
-isr_restore:
- movw $(0x20 | 3), %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
+syscall_return:
+ movq current_pcb, %rbx // return user stack
+ movq 0(%rbx), %rsp // esp
+ movq 8(%rbx), %rcx // pml4
+ movq (%rcx), %rcx
+ movq %rcx, %cr3
+
+ movw $(0x20 | 3), %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
POPALL
iretq
diff --git a/kernel/include/comus/cpu.h b/kernel/include/comus/cpu.h
index ffc1782..3669000 100644
--- a/kernel/include/comus/cpu.h
+++ b/kernel/include/comus/cpu.h
@@ -89,4 +89,9 @@ void cpu_feats(struct cpu_feat *feats);
*/
void cpu_print_regs(struct cpu_regs *regs);
+/**
+ * Return from a syscall handler back into userspace
+ */
+__attribute__((noreturn)) void syscall_return(void);
+
#endif /* cpu.h */
diff --git a/kernel/include/comus/procs.h b/kernel/include/comus/procs.h
index d105867..0150975 100644
--- a/kernel/include/comus/procs.h
+++ b/kernel/include/comus/procs.h
@@ -222,6 +222,6 @@ void schedule(struct pcb *pcb);
/**
* Select the next process to receive the CPU
*/
-void dispatch(void);
+__attribute__((noreturn)) void dispatch(void);
#endif /* procs.h */
diff --git a/kernel/include/comus/syscalls.h b/kernel/include/comus/syscalls.h
index 3b9ea70..0105104 100644
--- a/kernel/include/comus/syscalls.h
+++ b/kernel/include/comus/syscalls.h
@@ -27,9 +27,10 @@
#define SYS_sleep 14
#define SYS_brk 15
#define SYS_sbrk 16
+#define SYS_poweroff 17
// UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED!
-#define N_SYSCALLS 17
+#define N_SYSCALLS 18
// interrupt vector entry for system calls
#define VEC_SYSCALL 0x80
diff --git a/kernel/main.c b/kernel/main.c
index 4047a64..c15c38d 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -7,6 +7,7 @@
#include <comus/drivers/pci.h>
#include <comus/drivers/gpu.h>
#include <comus/drivers/ata.h>
+#include <comus/user.h>
#include <comus/fs.h>
#include <comus/procs.h>
#include <lib.h>
@@ -21,7 +22,7 @@ void kreport(void)
gpu_report();
}
-void main(long magic, volatile void *mboot)
+__attribute__((noreturn)) void main(long magic, volatile void *mboot)
{
// initalize idt and pic
cpu_init();
@@ -47,6 +48,12 @@ void main(long magic, volatile void *mboot)
// report system state
kreport();
- // halt
- kprintf("halting...\n");
+ // load init process
+ pcb_alloc(&init_pcb);
+ if (user_load(init_pcb, &fs_disks[0]))
+ panic("failed to load init");
+
+ // schedule and dispatch init
+ schedule(init_pcb);
+ dispatch();
}
diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c
index 8de1a24..b23e39b 100644
--- a/kernel/memory/paging.c
+++ b/kernel/memory/paging.c
@@ -704,8 +704,8 @@ volatile void *pgdir_alloc(void)
volatile void *pgdir_clone(volatile const void *old_pgdir, bool cow)
{
// TODO:
- (void) old_pgdir;
- (void) cow;
+ (void)old_pgdir;
+ (void)cow;
return NULL;
}
diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c
index 856a627..9fcbe8f 100644
--- a/kernel/memory/physalloc.c
+++ b/kernel/memory/physalloc.c
@@ -1,3 +1,4 @@
+#include "lib/kio.h"
#include <lib.h>
#include <comus/memory.h>
#include <comus/asm.h>
@@ -11,13 +12,13 @@ extern char kernel_end;
// between memory_start and kernel_start will be the bitmap
static uintptr_t memory_start = 0;
-static uint64_t *bitmap;
+static uint64_t *bitmap = NULL;
static uint64_t total_memory;
static uint64_t free_memory;
static uint64_t page_count;
static uint64_t segment_count;
struct memory_map phys_mmap;
-struct memory_segment *page_start;
+struct memory_segment *page_start = NULL;
static const char *segment_type_str[] = {
[SEG_TYPE_FREE] = "Free", [SEG_TYPE_RESERVED] = "Reserved",
@@ -84,6 +85,13 @@ void *alloc_phys_pages_exact(size_t pages)
if (pages < 1)
return NULL;
+ if (bitmap == NULL || page_start == NULL) {
+ // temporary bump allocator
+ void *addr = (void *)memory_start;
+ memory_start += PAGE_SIZE;
+ return addr;
+ }
+
size_t n_contiguous = 0;
size_t free_region_start = 0;
for (size_t i = 0; i < page_count; i++) {
diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c
index a077532..cbde9b4 100644
--- a/kernel/memory/virtalloc.c
+++ b/kernel/memory/virtalloc.c
@@ -79,7 +79,7 @@ static void free_node(struct virt_ctx *ctx, struct virt_addr_node *node)
void virtaddr_init(struct virt_ctx *ctx)
{
struct virt_addr_node init = {
- .start = 0x40005000, // map after paging pt
+ .start = 0x50000000,
.end = 0x1000000000000, // 48bit memory address max
.next = NULL,
.prev = NULL,
@@ -102,12 +102,14 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new)
memcpy(new, old, sizeof(struct virt_ctx));
// allocate new space
- new->alloc_nodes = kalloc(sizeof(struct virt_addr_node) * new->alloc_node_count);
+ new->alloc_nodes =
+ kalloc(sizeof(struct virt_addr_node) * new->alloc_node_count);
if (new->alloc_nodes == NULL)
return 1;
// update prev/next in new allocation space
- update_node_ptrs(old->alloc_nodes, new->alloc_nodes, old->alloc_node_count, new->alloc_node_count);
+ update_node_ptrs(old->alloc_nodes, new->alloc_nodes, old->alloc_node_count,
+ new->alloc_node_count);
// update bootstrap nodes
for (size_t i = 0; i < new->used_node_count; i++) {
@@ -117,8 +119,10 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new)
break;
// get prev
- prev = i > 0 ? &new->bootstrap_nodes[i-1] : NULL;
- next = i < BOOTSTRAP_VIRT_ALLOC_NODES - 1 ? &new->bootstrap_nodes[i+1] : NULL;
+ prev = i > 0 ? &new->bootstrap_nodes[i - 1] : NULL;
+ next = i < BOOTSTRAP_VIRT_ALLOC_NODES - 1 ?
+ &new->bootstrap_nodes[i + 1] :
+ NULL;
new->bootstrap_nodes[i].prev = prev;
new->bootstrap_nodes[i].next = next;
diff --git a/kernel/procs.c b/kernel/procs.c
index 9cde22f..c1bcc4f 100644
--- a/kernel/procs.c
+++ b/kernel/procs.c
@@ -35,7 +35,7 @@ struct pcb *init_pcb = NULL;
struct pcb ptable[N_PROCS];
/// next avaliable pid
-pid_t next_pid = 0;
+pid_t next_pid = 1;
static struct pcb *find_prev_wakeup(pcb_queue_t queue, struct pcb *pcb)
{
@@ -119,6 +119,7 @@ int pcb_alloc(struct pcb **pcb)
if (pcb_queue_pop(pcb_freelist, &tmp) != SUCCESS)
return E_NO_PCBS;
+ tmp->pid = next_pid++;
*pcb = tmp;
return SUCCESS;
}
@@ -461,7 +462,7 @@ void schedule(struct pcb *pcb)
panic("schedule insert fail");
}
-void dispatch(void)
+__attribute__((noreturn)) void dispatch(void)
{
assert(current_pcb == NULL, "dispatch: current process is not null");
@@ -472,4 +473,6 @@ void dispatch(void)
// set the process up for success
current_pcb->state = PROC_STATE_RUNNING;
current_pcb->ticks = 3; // ticks per process
+
+ syscall_return();
}
diff --git a/kernel/syscall.c b/kernel/syscall.c
index 7944f46..00e6afb 100644
--- a/kernel/syscall.c
+++ b/kernel/syscall.c
@@ -1,6 +1,6 @@
#include <comus/cpu.h>
#include <comus/syscalls.h>
-#include <comus/drivers/uart.h>
+#include <comus/drivers/acpi.h>
#include <comus/memory.h>
#include <comus/procs.h>
@@ -52,13 +52,22 @@ static int sys_write(void)
return nbytes;
}
+static int sys_poweroff(void)
+{
+ acpi_shutdown();
+ return 1;
+}
+
static int (*syscall_tbl[N_SYSCALLS])(void) = {
- [SYS_exit] = sys_exit, [SYS_waitpid] = NULL, [SYS_fork] = NULL,
- [SYS_exec] = NULL, [SYS_open] = NULL, [SYS_close] = NULL,
- [SYS_read] = NULL, [SYS_write] = sys_write, [SYS_getpid] = NULL,
- [SYS_getppid] = NULL, [SYS_gettime] = NULL, [SYS_getprio] = NULL,
- [SYS_setprio] = NULL, [SYS_kill] = NULL, [SYS_sleep] = NULL,
- [SYS_brk] = NULL, [SYS_sbrk] = NULL,
+ [SYS_exit] = sys_exit, [SYS_waitpid] = NULL,
+ [SYS_fork] = NULL, [SYS_exec] = NULL,
+ [SYS_open] = NULL, [SYS_close] = NULL,
+ [SYS_read] = NULL, [SYS_write] = sys_write,
+ [SYS_getpid] = NULL, [SYS_getppid] = NULL,
+ [SYS_gettime] = NULL, [SYS_getprio] = NULL,
+ [SYS_setprio] = NULL, [SYS_kill] = NULL,
+ [SYS_sleep] = NULL, [SYS_brk] = NULL,
+ [SYS_sbrk] = NULL, [SYS_poweroff] = sys_poweroff,
};
void syscall_handler(struct cpu_regs *regs)
@@ -91,7 +100,4 @@ void syscall_handler(struct cpu_regs *regs)
// save return value
current_pcb->regs->rax = ret;
-
- // switch back to process ctx
- mem_ctx_switch(current_pcb->memctx);
}
diff --git a/kernel/user.c b/kernel/user.c
index 592b35b..3c686a0 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -98,6 +98,10 @@ static int user_setup_stack(struct pcb *pcb)
int user_load(struct pcb *pcb, struct disk *disk)
{
+ // check inputs
+ if (pcb == NULL || disk == NULL)
+ return 1;
+
pcb->regs = NULL;
// allocate memory context