diff --git a/.gitignore b/.gitignore index 4f70696..e30ca3b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ quark-kernel autom4te.cache/ .deps .dirstamp -.vscode +#.vscode aclocal.m4 ar-lib compile diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..dbe0e06 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,45 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "~/.quark/include" + ], + "defines": [], + "compilerPath": "/opt/cross/bin/i686-elf-gcc", + "cStandard": "c11", + "cppStandard": "c++11", + "intelliSenseMode": "linux-gcc-x86", + "compilerArgs": [ + "-ffreestanding", + "-nostdlib" + ] + }, + { + "name": "i686-cross", + "includePath": [ + "/home/nathan/Documents/projects/quark-os/quark-kernel/**", + "/opt/quark-os/rootfs/include/", + "${workspaceFolder}/include" + ], + "defines": [], + "compilerPath": "/opt/cross/bin/i686-elf-gcc", + "cppStandard": "c++14", + "intelliSenseMode": "linux-gcc-x86", + "compilerArgs": [ + "-ffreestanding ", + "-nostdlib" + ], + "cStandard": "c11", + "mergeConfigurations": false, + "browse": { + "path": [ + "${workspaceFolder}/**" + ], + "limitSymbolsToIncludedHeaders": true + } + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4a3e936 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,37 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "/opt/quark-os/rootfs/apps/quark-kernel", + "args": [], + "stopAtEntry": true, + "stopAtConnect": true, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": true, + "MIMode": "gdb", + "miDebuggerServerAddress": "localhost:1234", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }/*, + { + "text": "-target-select remote localhost:1234", + "ignoreFailures": false + }*/ + ], + "preLaunchTask": "Launch QEMU (i386)" + /*"debugServerPath": "/bin/qemu-system-i386", + "debugServerArgs": "-hda /opt/quark-os/quark.img -serial stdio -s -S", + "serverLaunchTimeout": 2000*/ + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..041c45d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,28 @@ +{ + "files.exclude": { + "**/*.o": true, + "**/ar-lib": true, + "**/Makefile": true, + "**/*.in": true, + "**/stamp-h1": true, + "**/*.a": true, + "aclocal.m4": true, + "compile": true, + "config.log": true, + "config.status": true, + "configure*": true, + "depcomp": true, + "install-sh": true, + "missing": true, + "**/.deps": true, + "autom4te.cache": true, + "**/quark-kernel": true + }, + "C_Cpp.default.cStandard": "c11", + "files.associations": { + "memmap.h": "c", + "pid.h": "c", + "sighandler.h": "c", + "string.h": "c" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..b20ce60 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,27 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "make", + "type": "shell", + "command": "PATH=\"$PATH:/opt/cross/bin\" make", + "problemMatcher": ["$gcc"], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Launch QEMU (i386)", + "type": "shell", + "command": "qemu-system-i386 -hda /opt/quark-os/quark.img -serial stdio -s -S", + "isBackground": true, + "group": { + "kind": "test", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/include/Makefile.am b/include/Makefile.am index 4aa1946..1b6fc62 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,3 +1,3 @@ nobase_include_HEADERS = types/status.h types/syscallid.h types/physaddr.h \ types/syscallarg.h sys/syscalls.h types/pid.h types/oid.h \ - types/sigaction.h \ No newline at end of file + types/sigaction.h types/message.h \ No newline at end of file diff --git a/include/addressspace.h b/include/addressspace.h index 1df81bc..f502171 100644 --- a/include/addressspace.h +++ b/include/addressspace.h @@ -11,6 +11,10 @@ typedef struct address_space_t address_space_t *address_space_construct(); +void address_space_switch(address_space_t *address_space); +address_space_t *address_space_release(address_space_t *address_space); + +void address_space_destroy(address_space_t *address_space); #endif \ No newline at end of file diff --git a/include/kernel.h b/include/kernel.h index 544941d..7ff694d 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -6,6 +6,8 @@ #include "mmgr.h" #include "syscalls.h" #include "addressspace.h" +#include "process.h" +#include "types/message.h" #include "types/syscallid.h" #include "types/status.h" #include "types/pid.h" @@ -45,15 +47,12 @@ struct boot_info_t struct module_t modules[MODULE_LIMIT]; }; -struct message_t -{ - pid_t sender; - unsigned long code; - unsigned long args[6]; -}; - void kernel_initialize(struct boot_info_t *boot_info); +process_t *kernel_get_process(pid_t pid); + +process_t *kernel_get_active_process(); + error_t kernel_set_syscall(int id, int arg_count, void *func_ptr); 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); @@ -70,6 +69,8 @@ pid_t kernel_spawn_process(void *program_entry, int priority, address_space_t *a struct process_context_t *kernel_advance_scheduler(); +void kernel_schedule_process(process_t *process); + error_t kernel_terminate_process(pid_t process_id); error_t kernel_create_port(unsigned long id); @@ -78,10 +79,6 @@ error_t kernel_remove_port(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_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); diff --git a/include/mmgr.h b/include/mmgr.h index aaca95d..b162019 100644 --- a/include/mmgr.h +++ b/include/mmgr.h @@ -1,5 +1,6 @@ #pragma once +#include "sharedobject.h" #include "platform/paging.h" #include "types/physaddr.h" #include "types/status.h" @@ -102,6 +103,15 @@ physaddr_t current_address_space(); */ error_t map_region(void *page, physaddr_t frame, size_t size, int flags); +/** + * @brief Maps a shared object into virtual memory. + * + * @param location + * @param object + * @return + */ +error_t map_object(void *location, shared_object_t *object); + /** * @brief Unmaps a region in virtual memory. All pages which contain some part * of the region specified will be unmapped. diff --git a/include/process.h b/include/process.h index ef4dee1..09b2d04 100644 --- a/include/process.h +++ b/include/process.h @@ -1,11 +1,13 @@ #ifndef QUARK_PROCESS_H #define QUARK_PROCESS_H +#include "types/message.h" #include "types/pid.h" #include "types/physaddr.h" #include "types/status.h" #include "queue.h" #include "addressspace.h" +#include "sharedobject.h" typedef enum process_state_t { @@ -21,7 +23,6 @@ typedef struct process_t address_space_t *address_space; struct avltree_t *shared_objects; process_state_t state; - struct queue_t sending_queue; struct queue_t message_queue; struct message_t *message_buffer; struct process_context_t *ctx; @@ -29,4 +30,10 @@ typedef struct process_t process_t *process_construct(pid_t pid, void *entry, void *stack, int priority, address_space_t *address_space); +error_t process_queue_message(process_t *process, message_t *msg); + +error_t process_store_object(process_t *process, int id, void *location); + +void *process_get_object(process_t *process, int id); + #endif \ No newline at end of file diff --git a/include/sharedobject.h b/include/sharedobject.h index 98bb052..9252f26 100644 --- a/include/sharedobject.h +++ b/include/sharedobject.h @@ -4,14 +4,13 @@ #include "types/physaddr.h" #include -struct shared_object_t +typedef struct shared_object_t { physaddr_t phys_addr; size_t size; unsigned long access_flags; unsigned long refcount; - struct avltree_t *users; -}; +} shared_object_t; struct shared_object *create_shared_object(size_t size, unsigned long flags); diff --git a/include/sys/syscalls.h b/include/sys/syscalls.h index 8ba9804..e5272e4 100644 --- a/include/sys/syscalls.h +++ b/include/sys/syscalls.h @@ -42,9 +42,9 @@ static inline int map_anon(void *addr, size_t length, long flags) * @param length * @return */ -static inline int unmap_anon(void *addr, size_t length) +static inline int unmap_anon(void *addr) { - return _do_syscall(SYSCALL_UNMAP_ANON, addr, length); + return _do_syscall(SYSCALL_UNMAP_ANON, addr); } /** diff --git a/include/syscalls.h b/include/syscalls.h index ad9dab0..098336f 100644 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -22,7 +22,6 @@ struct syscall_t { bool defined; int arg_count; - int process_id; union { syscall_ptr_0_t func_ptr_0; @@ -47,7 +46,7 @@ int syscall_map_anon(syscall_arg_t location, syscall_arg_t length, syscall_arg_t /** * */ -int syscall_unmap_anon(syscall_arg_t location, syscall_arg_t length); +int syscall_unmap_anon(syscall_arg_t location); /** * diff --git a/include/types/message.h b/include/types/message.h new file mode 100644 index 0000000..f96f8a8 --- /dev/null +++ b/include/types/message.h @@ -0,0 +1,13 @@ +#ifndef QUARK_MESSAGE_H +#define QUARK_MESSAGE_H + +#include + +typedef struct message_t +{ + pid_t sender; + unsigned long code; + unsigned long args[6]; +} message_t; + +#endif \ No newline at end of file diff --git a/include/types/signalid.h b/include/types/signalid.h new file mode 100644 index 0000000..043babd --- /dev/null +++ b/include/types/signalid.h @@ -0,0 +1,10 @@ +#ifndef QUARK_SIGNALID_H +#define QUARK_SIGNALID_H + +typedef enum signalid_t +{ + SIG_KILL = 1, + SIG_STOP +} signalid_t; + +#endif \ No newline at end of file diff --git a/src/addressspace.c b/src/addressspace.c index eaf6db8..a11fef6 100644 --- a/src/addressspace.c +++ b/src/addressspace.c @@ -19,4 +19,26 @@ address_space_t *address_space_construct() as->refcount = 0; return as; -} \ No newline at end of file +} + +void address_space_switch(address_space_t *address_space) +{ + paging_load_address_space(address_space->page_table); +} + +address_space_t *address_space_release(address_space_t *address_space) +{ + address_space->refcount--; + if(address_space->refcount <= 0) + { + address_space_destroy(address_space); + return NULL; + } + return address_space; +} + +void address_space_destroy(address_space_t *address_space) +{ + // TODO: Not implemented. + kfree(address_space); +} diff --git a/src/kernel.c b/src/kernel.c index 9649e7d..982e798 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -36,22 +36,6 @@ void *syscall_table[] = { (void*)syscall_signal_raise }; -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 -{ - pid_t pid; - oid_t oid; - void *virt_addr; -}; - struct port_t { unsigned long id; @@ -120,7 +104,7 @@ void kernel_initialize(struct boot_info_t *boot_info) memset(kernel.syscall_table, 0, sizeof(struct syscall_t) * MAX_SYSCALL_ID); kernel_set_syscall(SYSCALL_TEST, 1, test_syscall); kernel_set_syscall(SYSCALL_MAP_ANON, 3, syscall_map_anon); - kernel_set_syscall(SYSCALL_UNMAP_ANON, 2, syscall_unmap_anon); + kernel_set_syscall(SYSCALL_UNMAP_ANON, 1, syscall_unmap_anon); kernel_set_syscall(SYSCALL_MAP_PHYS, 3, syscall_map_physical); kernel_set_syscall(SYSCALL_UNMAP_PHYS, 2, syscall_unmap_physical); kernel_set_syscall(SYSCALL_OPEN_PORT, 1, syscall_open_port); @@ -154,6 +138,16 @@ void kernel_initialize(struct boot_info_t *boot_info) load_context(kernel_advance_scheduler()); } +process_t *kernel_get_process(pid_t pid) +{ + return avl_get(kernel.process_table, pid); +} + +process_t *kernel_get_active_process() +{ + return kernel.active_process; +} + error_t kernel_set_syscall(int id, int arg_count, void *func_ptr) { if(id < 0 || id > MAX_SYSCALL_ID) @@ -216,7 +210,7 @@ error_t kernel_load_module(struct module_t *module) if(module_address_space == NULL) { kernel_panic("failed to create address space for module: out of memory"); } - paging_load_address_space(module_address_space->page_table); + address_space_switch(module_address_space); void *const load_base = (void*)0x80000000; physaddr_t p = module->start & ~(page_size - 1); map_region(load_base, p, module->end - p, PAGE_RW); @@ -308,13 +302,21 @@ struct process_context_t *kernel_advance_scheduler() kernel.active_process = priorityqueue_extract_min(&kernel.priority_queue); if(kernel.active_process != NULL) { - paging_load_address_space(kernel.active_process->address_space->page_table); + address_space_switch(kernel.active_process->address_space); printf("entering process %08x cr3=%08x ctx=%08x sched=%i.\n", kernel.active_process->pid, kernel.active_process->address_space->page_table, kernel.active_process->ctx, kernel.priority_queue.size); return kernel.active_process->ctx; } kernel_panic("no processes available to enter!"); } +void kernel_schedule_process(process_t *process) +{ + if(priorityqueue_insert(&kernel.priority_queue, process, process->priority)) + { + kernel_panic("Failed to schedule process!"); + } +} + error_t kernel_terminate_process(pid_t pid) { struct process_t *process = avl_get(kernel.process_table, pid); @@ -332,12 +334,6 @@ error_t kernel_terminate_process(pid_t pid) { kfree(msg); } - for(struct process_t *sender = queue_get_next(&process->sending_queue); sender != NULL; sender = queue_get_next(&process->sending_queue)) - { - sender->state = PROCESS_ACTIVE; - set_context_return(sender->ctx, EEXITED); - priorityqueue_insert(&kernel.priority_queue, sender, sender->priority); - } kfree(process->ctx); kfree(process); return ENONE; @@ -400,55 +396,6 @@ pid_t kernel_get_port_owner(unsigned long id) } } -error_t kernel_send_message(unsigned long recipient, struct message_t *message) -{ - struct process_t *dest = avl_get(kernel.process_table, recipient); - if(dest == NULL) - { - return EDOESNTEXIST; - } - else if(dest->message_buffer != NULL && dest->state == PROCESS_REQUESTING) - { - printf("Sending message directly from %i to %i\n", kernel.active_process->pid, dest->pid); - struct message_t kernel_buffer; - memcpy(&kernel_buffer, message, sizeof(struct message_t)); - kernel_buffer.sender = kernel.active_process->pid; - paging_load_address_space(dest->address_space->page_table); - memcpy(dest->message_buffer, &kernel_buffer, sizeof(struct message_t)); - paging_load_address_space(kernel.active_process->address_space->page_table); - dest->message_buffer = NULL; - dest->state = PROCESS_ACTIVE; - set_context_return(dest->ctx, ENONE); - priorityqueue_insert(&kernel.priority_queue, dest, dest->priority); - return ENONE; - } - else - { - return EBUSY; - } -} - -error_t kernel_queue_message(unsigned long recipient, struct message_t *message) -{ - struct process_t *dest = avl_get(kernel.process_table, recipient); - if(dest != NULL) - { - printf("Queueing message from %i to %i\n", kernel.active_process->pid, dest->pid); - struct message_t *queued_msg = kmalloc(sizeof(struct message_t)); - if(queued_msg == NULL) - { - return ENOMEM; - } - memcpy(queued_msg, message, sizeof(struct message_t)); - queue_insert(&dest->message_queue, queued_msg); - return ENONE; - } - else - { - return EDOESNTEXIST; - } -} - int kernel_receive_message(struct message_t *buffer, int flags) { if(kernel.active_process->message_queue.count > 0) @@ -512,7 +459,7 @@ error_t kernel_execute_interrupt_handler(unsigned long interrupt) return EDOESNTEXIST; } - paging_load_address_space(process->address_space->page_table); + address_space_switch(process->address_space); struct signal_context_t siginfo = { .signal_id = interrupt @@ -527,7 +474,7 @@ error_t kernel_execute_interrupt_handler(unsigned long interrupt) priorityqueue_insert(&kernel.priority_queue, process, process->priority); } - paging_load_address_space(kernel.active_process->address_space->page_table); + address_space_switch(kernel.active_process->address_space); return ENONE; } @@ -564,7 +511,6 @@ error_t kernel_create_object(size_t size, unsigned long flags, oid_t *id) 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++; diff --git a/src/process.c b/src/process.c index 07964a4..4aaa9e3 100644 --- a/src/process.c +++ b/src/process.c @@ -1,7 +1,9 @@ #include "process.h" #include "heap.h" +#include "mmgr.h" #include "platform/context.h" #include "string.h" +#include "avltree.h" process_t *process_construct(pid_t pid, void *entry, void *stack, int priority, address_space_t *address_space) { @@ -30,10 +32,39 @@ process_t *process_construct(pid_t pid, void *entry, void *stack, int priority, new_process->pid = pid; new_process->address_space = address_space; new_process->address_space->refcount++; + new_process->shared_objects = NULL; new_process->state = PROCESS_ACTIVE; new_process->message_buffer = NULL; new_process->ctx = initial_context; - queue_construct(&new_process->sending_queue); queue_construct(&new_process->message_queue); return new_process; +} + +error_t process_queue_message(process_t *process, message_t *msg) +{ + return queue_insert(&process->message_queue, msg); +} + +error_t process_receive_message(process_t *process, message_t *buffer) +{ + if(process->message_queue.count == 0) + { + return EDOESNTEXIST; + } + + message_t *queued_message = queue_get_next(&process->message_queue); + memcpy(buffer, queued_message, sizeof(message_t)); + kfree(queued_message); + return ENONE; +} + +error_t process_store_object(process_t *process, int id, void *location) +{ + process->shared_objects = avl_insert(process->shared_objects, id, location); + return ENONE; +} + +void *process_get_object(process_t *process, int id) +{ + return avl_get(process->shared_objects, id); } \ No newline at end of file diff --git a/src/sharedobject.c b/src/sharedobject.c index ddcb715..e8e2698 100644 --- a/src/sharedobject.c +++ b/src/sharedobject.c @@ -22,7 +22,6 @@ struct shared_object *create_shared_object(size_t size, unsigned long flags) obj->size = size; obj->access_flags = flags; obj->refcount = 0; - obj->users = NULL; return obj; } @@ -31,7 +30,6 @@ void destroy_shared_object(struct shared_object_t *obj) if(obj != NULL) { free_pages(obj->phys_addr); - avl_clear(obj->users); kfree(obj); } } \ No newline at end of file diff --git a/src/syscalls.c b/src/syscalls.c index 13fa788..db9f64b 100644 --- a/src/syscalls.c +++ b/src/syscalls.c @@ -2,6 +2,10 @@ #include "kernel.h" #include "mmgr.h" #include "stdio.h" +#include "process.h" +#include "sharedobject.h" +#include "system.h" +#include "heap.h" #include "platform/context.h" #include "types/status.h" @@ -50,34 +54,23 @@ int syscall_map_anon(syscall_arg_t arg_location, syscall_arg_t arg_length, sysca return ENONE; } -int syscall_unmap_anon(syscall_arg_t arg_location, syscall_arg_t arg_length) +int syscall_unmap_anon(syscall_arg_t arg_location) { - unsigned long location = arg_location.unsigned_int; - unsigned long length = arg_length.unsigned_int; - if(location % page_size != 0 || length % page_size != 0) + void *addr = arg_location.ptr; + if((size_t)addr % page_size != 0) { return EINVALIDARG; } - else if(location == 0) + else if(addr == NULL) { return ENULLPTR; } - size_t n = 0; - int status = ENONE; - while(n < length && status == ENONE) + else if(addr >= _kernel_start) { - int type = page_type((void*)(location + n)); - physaddr_t frame; - if(type & PAGE_PRESENT) - { - frame = unmap_page((void*)(location + n)); - if(type & PAGE_ANON) - { - status = free_page(frame); - } - } + return EPERM; } - return status; + unmap_region(arg_location.ptr, free_pages(physical_address(arg_location.ptr))); + return ENONE; } int syscall_map_physical(syscall_arg_t arg_addr, syscall_arg_t arg_phys_addr, syscall_arg_t arg_length) @@ -125,35 +118,80 @@ int syscall_close_port(syscall_arg_t id) int syscall_send_pid(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; - if((flags.unsigned_int & ~(IO_OP | IO_RECIPIENT_TYPE)) != 0 || dest_type >= IO_MAILBOX) + if(message.ptr == NULL) { - printf("Invalid flags on send()\n"); - return EINVALIDARG; + return ENULLPTR; } - if(dest_type == IO_PORT) + + process_t *process = kernel_get_process(recipient.unsigned_int); + if(process == NULL) { - recipient.unsigned_int = kernel_get_port_owner(recipient.unsigned_int); - if(recipient.unsigned_int == 0) - { - return EDOESNTEXIST; - } + return EEXITED; } - error_t status = kernel_send_message(recipient.unsigned_int, message.ptr); - if(status == EBUSY/* && op_type == IO_ASYNC*/) + + message_t *buffer = kmalloc(sizeof(message_t)); + if(buffer == NULL) { - return kernel_queue_message(recipient.unsigned_int, message.ptr); + return ENOMEM; + } + memcpy(buffer, message.ptr, sizeof(message_t)); + buffer->sender = kernel_current_pid(); + + address_space_switch(process->address_space); + int status = process_queue_message(process, buffer); + address_space_switch(kernel_get_active_process()->address_space); + if(status == ENOMEM) + { + kfree(buffer); + kernel_terminate_process(recipient.unsigned_int); + return EEXITED; } else { - return status; + return ENONE; } } int syscall_send_port(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags) { - return ENOSYSCALL; + if(message.ptr == NULL) + { + return ENULLPTR; + } + + pid_t recipient_pid = kernel_get_port_owner(recipient.unsigned_int); + if(recipient_pid == 0) + { + return EDOESNTEXIST; + } + + process_t *process = kernel_get_process(recipient_pid); + if(process == NULL) + { + return EEXITED; + } + + message_t *buffer = kmalloc(sizeof(message_t)); + if(buffer == NULL) + { + return ENOMEM; + } + memcpy(buffer, message.ptr, sizeof(message_t)); + buffer->sender = kernel_current_pid(); + + address_space_switch(process->address_space); + int status = process_queue_message(process, buffer); + address_space_switch(kernel_get_active_process()->address_space); + if(status == ENOMEM) + { + kfree(buffer); + kernel_terminate_process(recipient_pid); + return EEXITED; + } + else + { + return ENONE; + } } int syscall_receive(syscall_arg_t buffer, syscall_arg_t flags) @@ -163,8 +201,21 @@ int syscall_receive(syscall_arg_t buffer, syscall_arg_t flags) int syscall_create_object(void *location, size_t size, int flags) { - - return ENOSYSCALL; + shared_object_t *object = create_shared_object(size, flags); + if(object == NULL) + { + return ENOMEM; + } + + if(map_region(location, object->phys_addr, object->size, object->access_flags)) + { + destroy_shared_object(object); + return ENOMEM; + } + + object->refcount++; + process_store_object(kernel_get_active_process(), 0, location); + return ENONE; } int syscall_aquire_object(oid_t id, void *location)