Created small static library to wrap system call ABI
This commit is contained in:
@@ -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_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
|
||||
quark_kernel_SOURCES += x86/paging.c \
|
||||
x86/putc.c \
|
||||
@@ -17,7 +20,8 @@ quark_kernel_SOURCES += x86/paging.c \
|
||||
x86/load_context.S \
|
||||
x86/preempt.S \
|
||||
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_DEPENDENCIES = x86/linker.ld
|
||||
endif
|
||||
|
||||
170
src/kernel.c
170
src/kernel.c
@@ -13,7 +13,71 @@
|
||||
#include "types/status.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)
|
||||
{
|
||||
@@ -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);
|
||||
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()))
|
||||
{
|
||||
panic("Failed to initialize heap.");
|
||||
kernel_panic("Failed to initialize heap.");
|
||||
}
|
||||
|
||||
kernel.active_process = NULL;
|
||||
kernel.next_pid = 1;
|
||||
kernel.next_oid = 1;
|
||||
kernel.process_table = NULL;
|
||||
kernel.port_table = NULL;
|
||||
kernel.object_table = NULL;
|
||||
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);
|
||||
set_syscall(SYSCALL_TEST, 1, 0, test_syscall);
|
||||
set_syscall(SYSCALL_MMAP, 3, 0, mmap);
|
||||
set_syscall(SYSCALL_MUNMAP, 2, 0, munmap);
|
||||
set_syscall(SYSCALL_MAP_PHYS, 3, 0, map_physical);
|
||||
set_syscall(SYSCALL_UNMAP_PHYS, 2, 0, unmap_physical);
|
||||
set_syscall(SYSCALL_SEND, 3, 0, send);
|
||||
set_syscall(SYSCALL_RECEIVE, 2, 0, receive);
|
||||
set_syscall(SYSCALL_OPEN_PORT, 1, 0, open_port);
|
||||
set_syscall(SYSCALL_CLOSE_PORT, 1, 0, close_port);
|
||||
kernel_set_syscall(SYSCALL_TEST, 1, 0, test_syscall);
|
||||
kernel_set_syscall(SYSCALL_MMAP, 3, 0, syscall_mmap);
|
||||
kernel_set_syscall(SYSCALL_MUNMAP, 2, 0, syscall_munmap);
|
||||
kernel_set_syscall(SYSCALL_MAP_PHYS, 3, 0, syscall_map_physical);
|
||||
kernel_set_syscall(SYSCALL_UNMAP_PHYS, 2, 0, syscall_unmap_physical);
|
||||
kernel_set_syscall(SYSCALL_SEND, 3, 0, syscall_send);
|
||||
kernel_set_syscall(SYSCALL_RECEIVE, 2, 0, syscall_receive);
|
||||
kernel_set_syscall(SYSCALL_OPEN_PORT, 1, 0, syscall_open_port);
|
||||
kernel_set_syscall(SYSCALL_CLOSE_PORT, 1, 0, syscall_close_port);
|
||||
for(int i = 0; i < boot_info->module_count; i++)
|
||||
{
|
||||
if(kernel_load_module(&boot_info->modules[i]) != ENONE)
|
||||
{
|
||||
panic("Failed to load modules.");
|
||||
kernel_panic("Failed to load modules.");
|
||||
}
|
||||
}
|
||||
|
||||
if(initialize_interrupts() != ENONE)
|
||||
{
|
||||
panic("Failed to initialize interrupts.");
|
||||
kernel_panic("Failed to initialize interrupts.");
|
||||
}
|
||||
|
||||
irq_enable();
|
||||
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)
|
||||
{
|
||||
@@ -110,7 +176,7 @@ error_t set_syscall(int id, int arg_count, int pid, void *func_ptr)
|
||||
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)
|
||||
{
|
||||
@@ -162,7 +228,7 @@ error_t kernel_load_module(struct module_t *module)
|
||||
{
|
||||
physaddr_t module_address_space = create_address_space();
|
||||
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);
|
||||
void *const load_base = (void*)0x80000000;
|
||||
@@ -173,9 +239,9 @@ error_t kernel_load_module(struct module_t *module)
|
||||
switch(status)
|
||||
{
|
||||
case ENOMEM:
|
||||
panic("ran out of memory while mapping module");
|
||||
kernel_panic("ran out of memory while mapping module");
|
||||
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;
|
||||
|
||||
@@ -184,9 +250,9 @@ error_t kernel_load_module(struct module_t *module)
|
||||
switch(status)
|
||||
{
|
||||
case ENOMEM:
|
||||
panic("ran out of memory while reading ELF file");
|
||||
kernel_panic("ran out of memory while reading ELF file");
|
||||
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;
|
||||
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)
|
||||
{
|
||||
case ENOMEM:
|
||||
panic("ran out of memory while unmapping module");
|
||||
kernel_panic("ran out of memory while unmapping module");
|
||||
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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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));
|
||||
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);
|
||||
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)
|
||||
{
|
||||
return EDOESNTEXIST;
|
||||
@@ -300,7 +366,7 @@ error_t kernel_terminate_process(size_t process_id)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
@@ -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));
|
||||
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);
|
||||
}
|
||||
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);
|
||||
asm("cli");
|
||||
|
||||
@@ -11,7 +11,7 @@ size_t test_syscall(syscall_arg_t str)
|
||||
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 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);
|
||||
if(status != ENONE && free_page(frame) != ENONE)
|
||||
{
|
||||
panic("critical error reached during mmap.");
|
||||
kernel_panic("critical error reached during mmap.");
|
||||
}
|
||||
n += page_size;
|
||||
}
|
||||
@@ -51,14 +51,14 @@ size_t mmap(syscall_arg_t arg_location, syscall_arg_t arg_length, syscall_arg_t
|
||||
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;
|
||||
}
|
||||
|
||||
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 length = arg_length.unsigned_int;
|
||||
@@ -88,7 +88,7 @@ size_t munmap(syscall_arg_t arg_location, syscall_arg_t arg_length)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
size_t terminate_self()
|
||||
size_t syscall_terminate_self()
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
|
||||
size_t close_port(syscall_arg_t id)
|
||||
size_t syscall_close_port(syscall_arg_t id)
|
||||
{
|
||||
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, %fs
|
||||
mov %ax, %gs
|
||||
call do_syscall
|
||||
call kernel_do_syscall
|
||||
mov %ebp, %esp
|
||||
mov $0x23, %cx
|
||||
mov %cx, %ds
|
||||
|
||||
Reference in New Issue
Block a user