Created small static library to wrap system call ABI
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
nobase_include_HEADERS = types/status.h types/syscallid.h types/physaddr.h types/syscallarg.h
|
nobase_include_HEADERS = types/status.h types/syscallid.h types/physaddr.h \
|
||||||
|
types/syscallarg.h sys/syscalls.h types/pid.h types/oid.h
|
||||||
@@ -7,11 +7,13 @@
|
|||||||
#include "syscalls.h"
|
#include "syscalls.h"
|
||||||
#include "types/syscallid.h"
|
#include "types/syscallid.h"
|
||||||
#include "types/status.h"
|
#include "types/status.h"
|
||||||
|
#include "types/pid.h"
|
||||||
|
#include "types/oid.h"
|
||||||
#include <libmalloc/memmap.h>
|
#include <libmalloc/memmap.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define MAX_SYSCALL_ID 256
|
#define MAX_SYSCALL_ID 256
|
||||||
#define module_limit 8
|
#define MODULE_LIMIT 8
|
||||||
|
|
||||||
#define IO_OP 1 << 0
|
#define IO_OP 1 << 0
|
||||||
#define IO_SYNC 0 << 0
|
#define IO_SYNC 0 << 0
|
||||||
@@ -40,95 +42,48 @@ struct boot_info_t
|
|||||||
size_t memory_size;
|
size_t memory_size;
|
||||||
memory_map_t map;
|
memory_map_t map;
|
||||||
size_t module_count;
|
size_t module_count;
|
||||||
struct module_t modules[module_limit];
|
struct module_t modules[MODULE_LIMIT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct message_t
|
struct message_t
|
||||||
{
|
{
|
||||||
unsigned long sender;
|
pid_t sender;
|
||||||
unsigned long code;
|
unsigned long code;
|
||||||
unsigned long args[6];
|
unsigned long args[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum process_state_t
|
|
||||||
{
|
|
||||||
PROCESS_ACTIVE,
|
|
||||||
PROCESS_REQUESTING,
|
|
||||||
PROCESS_SENDING
|
|
||||||
};
|
|
||||||
|
|
||||||
struct process_t
|
|
||||||
{
|
|
||||||
unsigned long pid;
|
|
||||||
int priority;
|
|
||||||
physaddr_t page_table;
|
|
||||||
enum process_state_t state;
|
|
||||||
struct queue_t sending_queue;
|
|
||||||
struct queue_t message_queue;
|
|
||||||
struct message_t *message_buffer;
|
|
||||||
struct process_context_t *ctx;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct port_t
|
|
||||||
{
|
|
||||||
unsigned long id;
|
|
||||||
unsigned long owner_pid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct signal_action_t
|
|
||||||
{
|
|
||||||
unsigned long pid;
|
|
||||||
signal_handler_t func_ptr;
|
|
||||||
void (*trampoline_ptr)();
|
|
||||||
void *userdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct signal_context_t
|
|
||||||
{
|
|
||||||
unsigned long signal_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kernel_t
|
|
||||||
{
|
|
||||||
struct syscall_t syscall_table[MAX_SYSCALL_ID];
|
|
||||||
struct priority_queue_t priority_queue;
|
|
||||||
struct avltree_t *interrupt_handlers;
|
|
||||||
struct avltree_t *port_table;
|
|
||||||
struct avltree_t *process_table;
|
|
||||||
struct process_t *active_process;
|
|
||||||
int next_pid;
|
|
||||||
};
|
|
||||||
|
|
||||||
void kernel_initialize(struct boot_info_t *boot_info);
|
void kernel_initialize(struct boot_info_t *boot_info);
|
||||||
|
|
||||||
error_t set_syscall(int id, int arg_count, int pid, void *func_ptr);
|
error_t kernel_set_syscall(int id, int arg_count, pid_t pid, void *func_ptr);
|
||||||
|
|
||||||
size_t do_syscall(syscall_id_t id, syscall_arg_t arg1, syscall_arg_t arg2, syscall_arg_t arg3, void *pc, void *stack, unsigned long flags);
|
size_t kernel_do_syscall(syscall_id_t id, syscall_arg_t arg1, syscall_arg_t arg2, syscall_arg_t arg3, void *pc, void *stack, unsigned long flags);
|
||||||
|
|
||||||
error_t kernel_load_module(struct module_t *module);
|
error_t kernel_load_module(struct module_t *module);
|
||||||
|
|
||||||
unsigned long kernel_current_pid();
|
pid_t kernel_current_pid();
|
||||||
|
|
||||||
struct process_context_t *kernel_current_context();
|
struct process_context_t *kernel_current_context();
|
||||||
|
|
||||||
error_t kernel_store_active_context(struct process_context_t *context);
|
error_t kernel_store_active_context(struct process_context_t *context);
|
||||||
|
|
||||||
unsigned long kernel_spawn_process(void *program_entry, int priority, physaddr_t address_space);
|
pid_t kernel_spawn_process(void *program_entry, int priority, physaddr_t address_space);
|
||||||
|
|
||||||
struct process_context_t *kernel_advance_scheduler();
|
struct process_context_t *kernel_advance_scheduler();
|
||||||
|
|
||||||
error_t kernel_terminate_process(size_t process_id);
|
error_t kernel_terminate_process(pid_t process_id);
|
||||||
|
|
||||||
error_t kernel_create_port(unsigned long id);
|
error_t kernel_create_port(unsigned long id);
|
||||||
|
|
||||||
error_t kernel_remove_port(unsigned long id);
|
error_t kernel_remove_port(unsigned long id);
|
||||||
|
|
||||||
unsigned long kernel_get_port_owner(unsigned long id);
|
pid_t kernel_get_port_owner(unsigned long id);
|
||||||
|
|
||||||
error_t kernel_send_message(unsigned long recipient, struct message_t *message);
|
error_t kernel_send_message(unsigned long recipient, struct message_t *message);
|
||||||
|
|
||||||
error_t kernel_queue_message(unsigned long recipient, struct message_t *message);
|
error_t kernel_queue_message(unsigned long recipient, struct message_t *message);
|
||||||
|
|
||||||
|
int kernel_receive_message(struct message_t *buffer, int flags);
|
||||||
|
|
||||||
error_t kernel_register_interrupt_handler(unsigned long interrupt, signal_handler_t handler, void *userdata);
|
error_t kernel_register_interrupt_handler(unsigned long interrupt, signal_handler_t handler, void *userdata);
|
||||||
|
|
||||||
error_t kernel_remove_interrupt_handler(unsigned long interrupt);
|
error_t kernel_remove_interrupt_handler(unsigned long interrupt);
|
||||||
@@ -137,6 +92,10 @@ error_t kernel_execute_interrupt_handler(unsigned long interrupt);
|
|||||||
|
|
||||||
error_t kernel_signal_return();
|
error_t kernel_signal_return();
|
||||||
|
|
||||||
int receive_message(struct message_t *buffer, int flags);
|
error_t kernel_create_object(size_t size, unsigned long flags, oid_t *id);
|
||||||
|
|
||||||
void panic(const char *message) __attribute__ ((noreturn));
|
error_t kernel_attach_object(oid_t id, void *virt_addr);
|
||||||
|
|
||||||
|
error_t kernel_release_object(oid_t id);
|
||||||
|
|
||||||
|
void kernel_panic(const char *message) __attribute__ ((noreturn));
|
||||||
|
|||||||
65
include/sys/syscalls.h
Normal file
65
include/sys/syscalls.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef _QUARK_SYSCALLS_H
|
||||||
|
#define _QUARK_SYSCALLS_S
|
||||||
|
|
||||||
|
#include <types/syscallarg.h>
|
||||||
|
#include <types/syscallid.h>
|
||||||
|
#include <types/physaddr.h>
|
||||||
|
|
||||||
|
unsigned long _do_syscall(syscall_id_t id, syscall_arg_t arg1, syscall_arg_t arg2, syscall_arg_t arg3);
|
||||||
|
|
||||||
|
static inline int kprint(const char *s)
|
||||||
|
{
|
||||||
|
syscall_arg_t arg1;
|
||||||
|
syscall_arg_t arg2;
|
||||||
|
syscall_arg_t arg3;
|
||||||
|
arg1.ptr = (void*)s;
|
||||||
|
arg2.unsigned_int = 0UL;
|
||||||
|
arg3.signed_int = 0UL;
|
||||||
|
return (int) _do_syscall(SYSCALL_TEST, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int mmap(void *addr, unsigned long length, long flags)
|
||||||
|
{
|
||||||
|
syscall_arg_t arg1;
|
||||||
|
syscall_arg_t arg2;
|
||||||
|
syscall_arg_t arg3;
|
||||||
|
arg1.ptr = addr;
|
||||||
|
arg2.unsigned_int = length;
|
||||||
|
arg3.signed_int = flags;
|
||||||
|
return (int) _do_syscall(SYSCALL_MMAP, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int munmap(void *addr, unsigned long length)
|
||||||
|
{
|
||||||
|
syscall_arg_t arg1;
|
||||||
|
syscall_arg_t arg2;
|
||||||
|
syscall_arg_t arg3;
|
||||||
|
arg1.ptr = addr;
|
||||||
|
arg2.unsigned_int = length;
|
||||||
|
arg3.unsigned_int = 0UL;
|
||||||
|
return (int) _do_syscall(SYSCALL_MUNMAP, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int map_physical(void *addr, physaddr_t phys_addr, unsigned long length)
|
||||||
|
{
|
||||||
|
syscall_arg_t arg1;
|
||||||
|
syscall_arg_t arg2;
|
||||||
|
syscall_arg_t arg3;
|
||||||
|
arg1.ptr = addr;
|
||||||
|
arg2.unsigned_int = phys_addr;
|
||||||
|
arg3.unsigned_int = length;
|
||||||
|
return (int) _do_syscall(SYSCALL_MAP_PHYS, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int unmap_physical(void *addr, unsigned long length)
|
||||||
|
{
|
||||||
|
syscall_arg_t arg1;
|
||||||
|
syscall_arg_t arg2;
|
||||||
|
syscall_arg_t arg3;
|
||||||
|
arg1.ptr = addr;
|
||||||
|
arg2.unsigned_int = length;
|
||||||
|
arg3.unsigned_int = 0UL;
|
||||||
|
return (int) _do_syscall(SYSCALL_UNMAP_PHYS, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -28,20 +28,26 @@ struct syscall_t
|
|||||||
|
|
||||||
size_t test_syscall(syscall_arg_t str);
|
size_t test_syscall(syscall_arg_t str);
|
||||||
|
|
||||||
size_t mmap(syscall_arg_t location, syscall_arg_t length, syscall_arg_t flags);
|
size_t syscall_mmap(syscall_arg_t location, syscall_arg_t length, syscall_arg_t flags);
|
||||||
|
|
||||||
size_t munmap(syscall_arg_t location, syscall_arg_t length);
|
size_t syscall_munmap(syscall_arg_t location, syscall_arg_t length);
|
||||||
|
|
||||||
size_t map_physical(syscall_arg_t arg_addr, syscall_arg_t arg_phys_addr, syscall_arg_t arg_length);
|
size_t syscall_map_physical(syscall_arg_t arg_addr, syscall_arg_t arg_phys_addr, syscall_arg_t arg_length);
|
||||||
|
|
||||||
size_t unmap_physical(syscall_arg_t arg_addr, syscall_arg_t arg_length);
|
size_t syscall_unmap_physical(syscall_arg_t arg_addr, syscall_arg_t arg_length);
|
||||||
|
|
||||||
size_t terminate_self();
|
size_t syscall_terminate_self();
|
||||||
|
|
||||||
size_t send(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags);
|
size_t syscall_create_object();
|
||||||
|
|
||||||
size_t receive(syscall_arg_t buffer, syscall_arg_t flags);
|
size_t syscall_aquire_object();
|
||||||
|
|
||||||
size_t open_port(syscall_arg_t id);
|
size_t syscall_release_object();
|
||||||
|
|
||||||
size_t close_port(syscall_arg_t id);
|
size_t syscall_send(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags);
|
||||||
|
|
||||||
|
size_t syscall_receive(syscall_arg_t buffer, syscall_arg_t flags);
|
||||||
|
|
||||||
|
size_t syscall_open_port(syscall_arg_t id);
|
||||||
|
|
||||||
|
size_t syscall_close_port(syscall_arg_t id);
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ quark_kernel_LDADD = -lgcc -lmalloc
|
|||||||
quark_kernel_CFLAGS = -I$(top_srcdir)/include -I$(prefix)/include -ffreestanding -mgeneral-regs-only -O0 -Wall -ggdb
|
quark_kernel_CFLAGS = -I$(top_srcdir)/include -I$(prefix)/include -ffreestanding -mgeneral-regs-only -O0 -Wall -ggdb
|
||||||
quark_kernel_LDFLAGS = -L$(prefix)/lib -nostdlib
|
quark_kernel_LDFLAGS = -L$(prefix)/lib -nostdlib
|
||||||
|
|
||||||
|
lib_LIBRARIES = libquark-syscall.a
|
||||||
|
libquark_syscall_a_CFLAGS = -I$(top_srcdir)/include -I$(prefix)/include -ffreestanding -mgeneral-regs-only -O0 -Wall -ggdb
|
||||||
|
|
||||||
if x86
|
if x86
|
||||||
quark_kernel_SOURCES += x86/paging.c \
|
quark_kernel_SOURCES += x86/paging.c \
|
||||||
x86/putc.c \
|
x86/putc.c \
|
||||||
@@ -18,6 +21,7 @@ quark_kernel_SOURCES += x86/paging.c \
|
|||||||
x86/preempt.S \
|
x86/preempt.S \
|
||||||
x86/quark_x86.c \
|
x86/quark_x86.c \
|
||||||
x86/entry.S
|
x86/entry.S
|
||||||
|
libquark_syscall_a_SOURCES = x86/do_syscall.S
|
||||||
quark_kernel_LDFLAGS += -T x86/linker.ld
|
quark_kernel_LDFLAGS += -T x86/linker.ld
|
||||||
quark_kernel_DEPENDENCIES = x86/linker.ld
|
quark_kernel_DEPENDENCIES = x86/linker.ld
|
||||||
endif
|
endif
|
||||||
|
|||||||
170
src/kernel.c
170
src/kernel.c
@@ -13,7 +13,71 @@
|
|||||||
#include "types/status.h"
|
#include "types/status.h"
|
||||||
#include "types/syscallid.h"
|
#include "types/syscallid.h"
|
||||||
|
|
||||||
struct kernel_t kernel;
|
struct shared_object_t
|
||||||
|
{
|
||||||
|
physaddr_t phys_addr;
|
||||||
|
size_t size;
|
||||||
|
unsigned long access_flags;
|
||||||
|
unsigned long refcount;
|
||||||
|
struct avltree_t *users;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct shared_object_mapping_t
|
||||||
|
{
|
||||||
|
void *virt_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum process_state_t
|
||||||
|
{
|
||||||
|
PROCESS_ACTIVE,
|
||||||
|
PROCESS_REQUESTING,
|
||||||
|
PROCESS_SENDING
|
||||||
|
};
|
||||||
|
|
||||||
|
struct process_t
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
int priority;
|
||||||
|
physaddr_t page_table;
|
||||||
|
struct avltree_t *shared_objects;
|
||||||
|
enum process_state_t state;
|
||||||
|
struct queue_t sending_queue;
|
||||||
|
struct queue_t message_queue;
|
||||||
|
struct message_t *message_buffer;
|
||||||
|
struct process_context_t *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct port_t
|
||||||
|
{
|
||||||
|
unsigned long id;
|
||||||
|
pid_t owner_pid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct signal_action_t
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
signal_handler_t func_ptr;
|
||||||
|
void (*trampoline_ptr)();
|
||||||
|
void *userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct signal_context_t
|
||||||
|
{
|
||||||
|
unsigned long signal_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kernel_t
|
||||||
|
{
|
||||||
|
struct syscall_t syscall_table[MAX_SYSCALL_ID];
|
||||||
|
struct priority_queue_t priority_queue;
|
||||||
|
struct avltree_t *interrupt_handlers;
|
||||||
|
struct avltree_t *port_table;
|
||||||
|
struct avltree_t *object_table;
|
||||||
|
struct avltree_t *process_table;
|
||||||
|
struct process_t *active_process;
|
||||||
|
pid_t next_pid;
|
||||||
|
oid_t next_oid;
|
||||||
|
} kernel;
|
||||||
|
|
||||||
void kernel_initialize(struct boot_info_t *boot_info)
|
void kernel_initialize(struct boot_info_t *boot_info)
|
||||||
{
|
{
|
||||||
@@ -38,50 +102,52 @@ void kernel_initialize(struct boot_info_t *boot_info)
|
|||||||
memmap_insert_region(&boot_info->map, (physaddr_t)&_kernel_pstart, (physaddr_t)&_kernel_pend - (physaddr_t)&_kernel_pstart, M_UNAVAILABLE);
|
memmap_insert_region(&boot_info->map, (physaddr_t)&_kernel_pstart, (physaddr_t)&_kernel_pend - (physaddr_t)&_kernel_pstart, M_UNAVAILABLE);
|
||||||
if(initialize_page_map(&boot_info->map, (physaddr_t*)&_kernel_end, boot_info->memory_size, page_size))
|
if(initialize_page_map(&boot_info->map, (physaddr_t*)&_kernel_end, boot_info->memory_size, page_size))
|
||||||
{
|
{
|
||||||
panic("Failed to initialize page allocator.");
|
kernel_panic("Failed to initialize page allocator.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(kminit(page_map_end(), 0xFFC00000 - (size_t)page_map_end()))
|
if(kminit(page_map_end(), 0xFFC00000 - (size_t)page_map_end()))
|
||||||
{
|
{
|
||||||
panic("Failed to initialize heap.");
|
kernel_panic("Failed to initialize heap.");
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel.active_process = NULL;
|
kernel.active_process = NULL;
|
||||||
kernel.next_pid = 1;
|
kernel.next_pid = 1;
|
||||||
|
kernel.next_oid = 1;
|
||||||
kernel.process_table = NULL;
|
kernel.process_table = NULL;
|
||||||
kernel.port_table = NULL;
|
kernel.port_table = NULL;
|
||||||
|
kernel.object_table = NULL;
|
||||||
if(construct_priority_queue(&kernel.priority_queue, 512) != ENONE)
|
if(construct_priority_queue(&kernel.priority_queue, 512) != ENONE)
|
||||||
{
|
{
|
||||||
panic("Failed to construct priority queue.");
|
kernel_panic("Failed to construct priority queue.");
|
||||||
}
|
}
|
||||||
memset(kernel.syscall_table, 0, sizeof(struct syscall_t) * MAX_SYSCALL_ID);
|
memset(kernel.syscall_table, 0, sizeof(struct syscall_t) * MAX_SYSCALL_ID);
|
||||||
set_syscall(SYSCALL_TEST, 1, 0, test_syscall);
|
kernel_set_syscall(SYSCALL_TEST, 1, 0, test_syscall);
|
||||||
set_syscall(SYSCALL_MMAP, 3, 0, mmap);
|
kernel_set_syscall(SYSCALL_MMAP, 3, 0, syscall_mmap);
|
||||||
set_syscall(SYSCALL_MUNMAP, 2, 0, munmap);
|
kernel_set_syscall(SYSCALL_MUNMAP, 2, 0, syscall_munmap);
|
||||||
set_syscall(SYSCALL_MAP_PHYS, 3, 0, map_physical);
|
kernel_set_syscall(SYSCALL_MAP_PHYS, 3, 0, syscall_map_physical);
|
||||||
set_syscall(SYSCALL_UNMAP_PHYS, 2, 0, unmap_physical);
|
kernel_set_syscall(SYSCALL_UNMAP_PHYS, 2, 0, syscall_unmap_physical);
|
||||||
set_syscall(SYSCALL_SEND, 3, 0, send);
|
kernel_set_syscall(SYSCALL_SEND, 3, 0, syscall_send);
|
||||||
set_syscall(SYSCALL_RECEIVE, 2, 0, receive);
|
kernel_set_syscall(SYSCALL_RECEIVE, 2, 0, syscall_receive);
|
||||||
set_syscall(SYSCALL_OPEN_PORT, 1, 0, open_port);
|
kernel_set_syscall(SYSCALL_OPEN_PORT, 1, 0, syscall_open_port);
|
||||||
set_syscall(SYSCALL_CLOSE_PORT, 1, 0, close_port);
|
kernel_set_syscall(SYSCALL_CLOSE_PORT, 1, 0, syscall_close_port);
|
||||||
for(int i = 0; i < boot_info->module_count; i++)
|
for(int i = 0; i < boot_info->module_count; i++)
|
||||||
{
|
{
|
||||||
if(kernel_load_module(&boot_info->modules[i]) != ENONE)
|
if(kernel_load_module(&boot_info->modules[i]) != ENONE)
|
||||||
{
|
{
|
||||||
panic("Failed to load modules.");
|
kernel_panic("Failed to load modules.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(initialize_interrupts() != ENONE)
|
if(initialize_interrupts() != ENONE)
|
||||||
{
|
{
|
||||||
panic("Failed to initialize interrupts.");
|
kernel_panic("Failed to initialize interrupts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_enable();
|
irq_enable();
|
||||||
load_context(kernel_advance_scheduler());
|
load_context(kernel_advance_scheduler());
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t set_syscall(int id, int arg_count, int pid, void *func_ptr)
|
error_t kernel_set_syscall(int id, int arg_count, pid_t pid, void *func_ptr)
|
||||||
{
|
{
|
||||||
if(id < 0 || id > MAX_SYSCALL_ID)
|
if(id < 0 || id > MAX_SYSCALL_ID)
|
||||||
{
|
{
|
||||||
@@ -110,7 +176,7 @@ error_t set_syscall(int id, int arg_count, int pid, void *func_ptr)
|
|||||||
return ENONE;
|
return ENONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t do_syscall(syscall_id_t id, syscall_arg_t arg1, syscall_arg_t arg2, syscall_arg_t arg3, void *pc, void *stack, unsigned long flags)
|
size_t kernel_do_syscall(syscall_id_t id, syscall_arg_t arg1, syscall_arg_t arg2, syscall_arg_t arg3, void *pc, void *stack, unsigned long flags)
|
||||||
{
|
{
|
||||||
if(id < 0 || id > MAX_SYSCALL_ID)
|
if(id < 0 || id > MAX_SYSCALL_ID)
|
||||||
{
|
{
|
||||||
@@ -162,7 +228,7 @@ error_t kernel_load_module(struct module_t *module)
|
|||||||
{
|
{
|
||||||
physaddr_t module_address_space = create_address_space();
|
physaddr_t module_address_space = create_address_space();
|
||||||
if(module_address_space == ENOMEM) {
|
if(module_address_space == ENOMEM) {
|
||||||
panic("failed to create address space for module: out of memory");
|
kernel_panic("failed to create address space for module: out of memory");
|
||||||
}
|
}
|
||||||
paging_load_address_space(module_address_space);
|
paging_load_address_space(module_address_space);
|
||||||
void *const load_base = (void*)0x80000000;
|
void *const load_base = (void*)0x80000000;
|
||||||
@@ -173,9 +239,9 @@ error_t kernel_load_module(struct module_t *module)
|
|||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
panic("ran out of memory while mapping module");
|
kernel_panic("ran out of memory while mapping module");
|
||||||
case EOUTOFBOUNDS:
|
case EOUTOFBOUNDS:
|
||||||
panic("got out-of-bounds error while mapping module");
|
kernel_panic("got out-of-bounds error while mapping module");
|
||||||
}
|
}
|
||||||
load_offset += page_size;
|
load_offset += page_size;
|
||||||
|
|
||||||
@@ -184,9 +250,9 @@ error_t kernel_load_module(struct module_t *module)
|
|||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
panic("ran out of memory while reading ELF file");
|
kernel_panic("ran out of memory while reading ELF file");
|
||||||
case EOUTOFBOUNDS:
|
case EOUTOFBOUNDS:
|
||||||
panic("got out-of-bounds error while reading ELF file");
|
kernel_panic("got out-of-bounds error while reading ELF file");
|
||||||
}
|
}
|
||||||
void *module_entry = ((struct elf_file_header_t*)load_base)->entry;
|
void *module_entry = ((struct elf_file_header_t*)load_base)->entry;
|
||||||
printf("loaded module with entry point %08x\n", (unsigned int)module_entry);
|
printf("loaded module with entry point %08x\n", (unsigned int)module_entry);
|
||||||
@@ -197,9 +263,9 @@ error_t kernel_load_module(struct module_t *module)
|
|||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
panic("ran out of memory while unmapping module");
|
kernel_panic("ran out of memory while unmapping module");
|
||||||
case EOUTOFBOUNDS:
|
case EOUTOFBOUNDS:
|
||||||
panic("got out-of-bounds error while unmapping module");
|
kernel_panic("got out-of-bounds error while unmapping module");
|
||||||
}
|
}
|
||||||
load_offset += page_size;
|
load_offset += page_size;
|
||||||
}
|
}
|
||||||
@@ -213,7 +279,7 @@ error_t kernel_load_module(struct module_t *module)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long kernel_current_pid()
|
pid_t kernel_current_pid()
|
||||||
{
|
{
|
||||||
if(kernel.active_process == NULL)
|
if(kernel.active_process == NULL)
|
||||||
{
|
{
|
||||||
@@ -237,7 +303,7 @@ struct process_context_t *kernel_current_context()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long kernel_spawn_process(void *program_entry, int priority, physaddr_t address_space)
|
pid_t kernel_spawn_process(void *program_entry, int priority, physaddr_t address_space)
|
||||||
{
|
{
|
||||||
struct process_t *new_process = (struct process_t*) kmalloc(sizeof(struct process_t));
|
struct process_t *new_process = (struct process_t*) kmalloc(sizeof(struct process_t));
|
||||||
if(new_process == NULL)
|
if(new_process == NULL)
|
||||||
@@ -286,12 +352,12 @@ struct process_context_t *kernel_advance_scheduler()
|
|||||||
printf("entering process %08x cr3=%08x ctx=%08x sched=%i.\n", kernel.active_process->pid, kernel.active_process->page_table, kernel.active_process->ctx, kernel.priority_queue.size);
|
printf("entering process %08x cr3=%08x ctx=%08x sched=%i.\n", kernel.active_process->pid, kernel.active_process->page_table, kernel.active_process->ctx, kernel.priority_queue.size);
|
||||||
return kernel.active_process->ctx;
|
return kernel.active_process->ctx;
|
||||||
}
|
}
|
||||||
panic("no processes available to enter!");
|
kernel_panic("no processes available to enter!");
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t kernel_terminate_process(size_t process_id)
|
error_t kernel_terminate_process(pid_t pid)
|
||||||
{
|
{
|
||||||
struct process_t *process = avl_get(kernel.process_table, process_id);
|
struct process_t *process = avl_get(kernel.process_table, pid);
|
||||||
if(process == NULL)
|
if(process == NULL)
|
||||||
{
|
{
|
||||||
return EDOESNTEXIST;
|
return EDOESNTEXIST;
|
||||||
@@ -300,7 +366,7 @@ error_t kernel_terminate_process(size_t process_id)
|
|||||||
{
|
{
|
||||||
kernel.active_process = NULL;
|
kernel.active_process = NULL;
|
||||||
}
|
}
|
||||||
kernel.process_table = avl_remove(kernel.process_table, process_id);
|
kernel.process_table = avl_remove(kernel.process_table, pid);
|
||||||
priorityqueue_remove(&kernel.priority_queue, process);
|
priorityqueue_remove(&kernel.priority_queue, process);
|
||||||
for(struct message_t *msg = queue_get_next(&process->message_queue); msg != NULL; msg = queue_get_next(&process->message_queue))
|
for(struct message_t *msg = queue_get_next(&process->message_queue); msg != NULL; msg = queue_get_next(&process->message_queue))
|
||||||
{
|
{
|
||||||
@@ -361,7 +427,7 @@ error_t kernel_remove_port(unsigned long id)
|
|||||||
return ENONE;
|
return ENONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long kernel_get_port_owner(unsigned long id)
|
pid_t kernel_get_port_owner(unsigned long id)
|
||||||
{
|
{
|
||||||
struct port_t *port = avl_get(kernel.port_table, id);
|
struct port_t *port = avl_get(kernel.port_table, id);
|
||||||
if(port == NULL)
|
if(port == NULL)
|
||||||
@@ -423,7 +489,7 @@ error_t kernel_queue_message(unsigned long recipient, struct message_t *message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int receive_message(struct message_t *buffer, int flags)
|
int kernel_receive_message(struct message_t *buffer, int flags)
|
||||||
{
|
{
|
||||||
if(kernel.active_process->message_queue.count > 0)
|
if(kernel.active_process->message_queue.count > 0)
|
||||||
{
|
{
|
||||||
@@ -513,13 +579,49 @@ error_t kernel_signal_return()
|
|||||||
context_stack_pop_struct(kernel.active_process->ctx, kernel.active_process->ctx, sizeof(*kernel.active_process->ctx));
|
context_stack_pop_struct(kernel.active_process->ctx, kernel.active_process->ctx, sizeof(*kernel.active_process->ctx));
|
||||||
if(kernel.active_process->state == PROCESS_REQUESTING)
|
if(kernel.active_process->state == PROCESS_REQUESTING)
|
||||||
{
|
{
|
||||||
receive_message(kernel.active_process->message_buffer, 0);
|
kernel_receive_message(kernel.active_process->message_buffer, 0);
|
||||||
load_context(kernel.active_process->ctx);
|
load_context(kernel.active_process->ctx);
|
||||||
}
|
}
|
||||||
return ENONE;
|
return ENONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void panic(const char *message)
|
error_t kernel_create_object(size_t size, unsigned long flags, oid_t *id)
|
||||||
|
{
|
||||||
|
physaddr_t phys_addr = reserve_pages(size);
|
||||||
|
if(phys_addr == ENOMEM)
|
||||||
|
{
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct shared_object_t *obj = kmalloc(sizeof(struct shared_object_t));
|
||||||
|
if(obj == NULL)
|
||||||
|
{
|
||||||
|
free_pages(phys_addr, size);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->phys_addr = phys_addr;
|
||||||
|
obj->size = size;
|
||||||
|
obj->access_flags = flags;
|
||||||
|
obj->refcount = 0;
|
||||||
|
obj->users = NULL;
|
||||||
|
kernel.object_table = avl_insert(kernel.object_table, kernel.next_oid, obj);
|
||||||
|
*id = kernel.next_oid;
|
||||||
|
kernel.next_oid++;
|
||||||
|
return ENONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t kernel_attach_object(oid_t id, void *virt_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t kernel_release_object(oid_t id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_panic(const char *message)
|
||||||
{
|
{
|
||||||
printf("panic: %s", message);
|
printf("panic: %s", message);
|
||||||
asm("cli");
|
asm("cli");
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ size_t test_syscall(syscall_arg_t str)
|
|||||||
return 17;
|
return 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mmap(syscall_arg_t arg_location, syscall_arg_t arg_length, syscall_arg_t arg_flags)
|
size_t syscall_mmap(syscall_arg_t arg_location, syscall_arg_t arg_length, syscall_arg_t arg_flags)
|
||||||
{
|
{
|
||||||
unsigned long location = arg_location.unsigned_int;
|
unsigned long location = arg_location.unsigned_int;
|
||||||
unsigned long length = arg_length.unsigned_int;
|
unsigned long length = arg_length.unsigned_int;
|
||||||
@@ -42,7 +42,7 @@ size_t mmap(syscall_arg_t arg_location, syscall_arg_t arg_length, syscall_arg_t
|
|||||||
status = map_page((void*)(location + n), frame, PAGE_USERMODE | PAGE_RW);
|
status = map_page((void*)(location + n), frame, PAGE_USERMODE | PAGE_RW);
|
||||||
if(status != ENONE && free_page(frame) != ENONE)
|
if(status != ENONE && free_page(frame) != ENONE)
|
||||||
{
|
{
|
||||||
panic("critical error reached during mmap.");
|
kernel_panic("critical error reached during mmap.");
|
||||||
}
|
}
|
||||||
n += page_size;
|
n += page_size;
|
||||||
}
|
}
|
||||||
@@ -51,14 +51,14 @@ size_t mmap(syscall_arg_t arg_location, syscall_arg_t arg_length, syscall_arg_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(status != ENONE && munmap(arg_location, arg_length) != ENONE)
|
if(status != ENONE && syscall_munmap(arg_location, arg_length) != ENONE)
|
||||||
{
|
{
|
||||||
panic("critical error reached during mmap.");
|
kernel_panic("critical error reached during mmap.");
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t munmap(syscall_arg_t arg_location, syscall_arg_t arg_length)
|
size_t syscall_munmap(syscall_arg_t arg_location, syscall_arg_t arg_length)
|
||||||
{
|
{
|
||||||
unsigned long location = arg_location.unsigned_int;
|
unsigned long location = arg_location.unsigned_int;
|
||||||
unsigned long length = arg_length.unsigned_int;
|
unsigned long length = arg_length.unsigned_int;
|
||||||
@@ -88,7 +88,7 @@ size_t munmap(syscall_arg_t arg_location, syscall_arg_t arg_length)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t map_physical(syscall_arg_t arg_addr, syscall_arg_t arg_phys_addr, syscall_arg_t arg_length)
|
size_t syscall_map_physical(syscall_arg_t arg_addr, syscall_arg_t arg_phys_addr, syscall_arg_t arg_length)
|
||||||
{
|
{
|
||||||
void *addr = arg_addr.ptr;
|
void *addr = arg_addr.ptr;
|
||||||
physaddr_t frame = arg_phys_addr.unsigned_int;
|
physaddr_t frame = arg_phys_addr.unsigned_int;
|
||||||
@@ -105,7 +105,7 @@ size_t map_physical(syscall_arg_t arg_addr, syscall_arg_t arg_phys_addr, syscall
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t unmap_physical(syscall_arg_t arg_addr, syscall_arg_t arg_length)
|
size_t syscall_unmap_physical(syscall_arg_t arg_addr, syscall_arg_t arg_length)
|
||||||
{
|
{
|
||||||
void *addr = arg_addr.ptr;
|
void *addr = arg_addr.ptr;
|
||||||
unsigned long length = arg_length.unsigned_int;
|
unsigned long length = arg_length.unsigned_int;
|
||||||
@@ -121,12 +121,12 @@ size_t unmap_physical(syscall_arg_t arg_addr, syscall_arg_t arg_length)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t terminate_self()
|
size_t syscall_terminate_self()
|
||||||
{
|
{
|
||||||
return kernel_terminate_process(kernel_current_pid());
|
return kernel_terminate_process(kernel_current_pid());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t send(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags)
|
size_t syscall_send(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags)
|
||||||
{
|
{
|
||||||
unsigned long op_type = flags.unsigned_int & IO_OP;
|
unsigned long op_type = flags.unsigned_int & IO_OP;
|
||||||
unsigned long dest_type = flags.unsigned_int & IO_RECIPIENT_TYPE;
|
unsigned long dest_type = flags.unsigned_int & IO_RECIPIENT_TYPE;
|
||||||
@@ -154,17 +154,17 @@ size_t send(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t receive(syscall_arg_t buffer, syscall_arg_t flags)
|
size_t syscall_receive(syscall_arg_t buffer, syscall_arg_t flags)
|
||||||
{
|
{
|
||||||
return receive_message(buffer.ptr, flags.unsigned_int);
|
return kernel_receive_message(buffer.ptr, flags.unsigned_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t open_port(syscall_arg_t id)
|
size_t syscall_open_port(syscall_arg_t id)
|
||||||
{
|
{
|
||||||
return kernel_create_port(id.unsigned_int);
|
return kernel_create_port(id.unsigned_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t close_port(syscall_arg_t id)
|
size_t syscall_close_port(syscall_arg_t id)
|
||||||
{
|
{
|
||||||
return kernel_remove_port(id.unsigned_int);
|
return kernel_remove_port(id.unsigned_int);
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/x86/do_syscall.S
Normal file
19
src/x86/do_syscall.S
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
.global _do_syscall
|
||||||
|
.type _do_syscall, @function
|
||||||
|
_do_syscall:
|
||||||
|
push %ebp
|
||||||
|
mov %esp, %ebp
|
||||||
|
push %esi
|
||||||
|
push %edi
|
||||||
|
push %ebx
|
||||||
|
mov 0x08(%ebp), %eax
|
||||||
|
mov 0x0C(%ebp), %ebx
|
||||||
|
mov 0x10(%ebp), %ecx
|
||||||
|
mov 0x14(%ebp), %edx
|
||||||
|
int $0x80
|
||||||
|
pop %ebx
|
||||||
|
pop %edi
|
||||||
|
pop %esi
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
.size _do_syscall, . - _do_syscall
|
||||||
@@ -20,7 +20,7 @@ isr_syscall:
|
|||||||
mov %ax, %es
|
mov %ax, %es
|
||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
call do_syscall
|
call kernel_do_syscall
|
||||||
mov %ebp, %esp
|
mov %ebp, %esp
|
||||||
mov $0x23, %cx
|
mov $0x23, %cx
|
||||||
mov %cx, %ds
|
mov %cx, %ds
|
||||||
|
|||||||
Reference in New Issue
Block a user