Working on reorganizing kernel.c

This commit is contained in:
2023-12-16 09:51:02 -06:00
parent df90bd7313
commit cbc1752e73
20 changed files with 363 additions and 139 deletions

2
.gitignore vendored
View File

@@ -6,7 +6,7 @@ quark-kernel
autom4te.cache/ autom4te.cache/
.deps .deps
.dirstamp .dirstamp
.vscode #.vscode
aclocal.m4 aclocal.m4
ar-lib ar-lib
compile compile

45
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -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
}

37
.vscode/launch.json vendored Normal file
View File

@@ -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*/
}
]
}

28
.vscode/settings.json vendored Normal file
View File

@@ -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"
}
}

27
.vscode/tasks.json vendored Normal file
View File

@@ -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
}
}
]
}

View File

@@ -1,3 +1,3 @@
nobase_include_HEADERS = types/status.h types/syscallid.h types/physaddr.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 \ types/syscallarg.h sys/syscalls.h types/pid.h types/oid.h \
types/sigaction.h types/sigaction.h types/message.h

View File

@@ -11,6 +11,10 @@ typedef struct address_space_t
address_space_t *address_space_construct(); 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 #endif

View File

@@ -6,6 +6,8 @@
#include "mmgr.h" #include "mmgr.h"
#include "syscalls.h" #include "syscalls.h"
#include "addressspace.h" #include "addressspace.h"
#include "process.h"
#include "types/message.h"
#include "types/syscallid.h" #include "types/syscallid.h"
#include "types/status.h" #include "types/status.h"
#include "types/pid.h" #include "types/pid.h"
@@ -45,15 +47,12 @@ struct boot_info_t
struct module_t modules[MODULE_LIMIT]; 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); 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); 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); 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(); 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_terminate_process(pid_t process_id);
error_t kernel_create_port(unsigned long 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); 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); 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);

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "sharedobject.h"
#include "platform/paging.h" #include "platform/paging.h"
#include "types/physaddr.h" #include "types/physaddr.h"
#include "types/status.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); 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 * @brief Unmaps a region in virtual memory. All pages which contain some part
* of the region specified will be unmapped. * of the region specified will be unmapped.

View File

@@ -1,11 +1,13 @@
#ifndef QUARK_PROCESS_H #ifndef QUARK_PROCESS_H
#define QUARK_PROCESS_H #define QUARK_PROCESS_H
#include "types/message.h"
#include "types/pid.h" #include "types/pid.h"
#include "types/physaddr.h" #include "types/physaddr.h"
#include "types/status.h" #include "types/status.h"
#include "queue.h" #include "queue.h"
#include "addressspace.h" #include "addressspace.h"
#include "sharedobject.h"
typedef enum process_state_t typedef enum process_state_t
{ {
@@ -21,7 +23,6 @@ typedef struct process_t
address_space_t *address_space; address_space_t *address_space;
struct avltree_t *shared_objects; struct avltree_t *shared_objects;
process_state_t state; process_state_t state;
struct queue_t sending_queue;
struct queue_t message_queue; struct queue_t message_queue;
struct message_t *message_buffer; struct message_t *message_buffer;
struct process_context_t *ctx; 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); 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 #endif

View File

@@ -4,14 +4,13 @@
#include "types/physaddr.h" #include "types/physaddr.h"
#include <stddef.h> #include <stddef.h>
struct shared_object_t typedef struct shared_object_t
{ {
physaddr_t phys_addr; physaddr_t phys_addr;
size_t size; size_t size;
unsigned long access_flags; unsigned long access_flags;
unsigned long refcount; unsigned long refcount;
struct avltree_t *users; } shared_object_t;
};
struct shared_object *create_shared_object(size_t size, unsigned long flags); struct shared_object *create_shared_object(size_t size, unsigned long flags);

View File

@@ -42,9 +42,9 @@ static inline int map_anon(void *addr, size_t length, long flags)
* @param length * @param length
* @return * @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);
} }
/** /**

View File

@@ -22,7 +22,6 @@ struct syscall_t
{ {
bool defined; bool defined;
int arg_count; int arg_count;
int process_id;
union union
{ {
syscall_ptr_0_t func_ptr_0; 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);
/** /**
* *

13
include/types/message.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef QUARK_MESSAGE_H
#define QUARK_MESSAGE_H
#include <types/pid.h>
typedef struct message_t
{
pid_t sender;
unsigned long code;
unsigned long args[6];
} message_t;
#endif

10
include/types/signalid.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef QUARK_SIGNALID_H
#define QUARK_SIGNALID_H
typedef enum signalid_t
{
SIG_KILL = 1,
SIG_STOP
} signalid_t;
#endif

View File

@@ -20,3 +20,25 @@ address_space_t *address_space_construct()
as->refcount = 0; as->refcount = 0;
return as; return as;
} }
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);
}

View File

@@ -36,22 +36,6 @@ void *syscall_table[] = {
(void*)syscall_signal_raise (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 struct port_t
{ {
unsigned long id; 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); memset(kernel.syscall_table, 0, sizeof(struct syscall_t) * MAX_SYSCALL_ID);
kernel_set_syscall(SYSCALL_TEST, 1, test_syscall); kernel_set_syscall(SYSCALL_TEST, 1, test_syscall);
kernel_set_syscall(SYSCALL_MAP_ANON, 3, syscall_map_anon); 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_MAP_PHYS, 3, syscall_map_physical);
kernel_set_syscall(SYSCALL_UNMAP_PHYS, 2, syscall_unmap_physical); kernel_set_syscall(SYSCALL_UNMAP_PHYS, 2, syscall_unmap_physical);
kernel_set_syscall(SYSCALL_OPEN_PORT, 1, syscall_open_port); 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()); 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) error_t kernel_set_syscall(int id, int arg_count, void *func_ptr)
{ {
if(id < 0 || id > MAX_SYSCALL_ID) 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) { if(module_address_space == NULL) {
kernel_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->page_table); address_space_switch(module_address_space);
void *const load_base = (void*)0x80000000; void *const load_base = (void*)0x80000000;
physaddr_t p = module->start & ~(page_size - 1); physaddr_t p = module->start & ~(page_size - 1);
map_region(load_base, p, module->end - p, PAGE_RW); 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); kernel.active_process = priorityqueue_extract_min(&kernel.priority_queue);
if(kernel.active_process != NULL) 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); 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; return kernel.active_process->ctx;
} }
kernel_panic("no processes available to enter!"); 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) error_t kernel_terminate_process(pid_t pid)
{ {
struct process_t *process = avl_get(kernel.process_table, 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); 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->ctx);
kfree(process); kfree(process);
return ENONE; 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) 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)
@@ -512,7 +459,7 @@ error_t kernel_execute_interrupt_handler(unsigned long interrupt)
return EDOESNTEXIST; return EDOESNTEXIST;
} }
paging_load_address_space(process->address_space->page_table); address_space_switch(process->address_space);
struct signal_context_t siginfo = { struct signal_context_t siginfo = {
.signal_id = interrupt .signal_id = interrupt
@@ -527,7 +474,7 @@ error_t kernel_execute_interrupt_handler(unsigned long interrupt)
priorityqueue_insert(&kernel.priority_queue, process, process->priority); 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; return ENONE;
} }
@@ -564,7 +511,6 @@ error_t kernel_create_object(size_t size, unsigned long flags, oid_t *id)
obj->size = size; obj->size = size;
obj->access_flags = flags; obj->access_flags = flags;
obj->refcount = 0; obj->refcount = 0;
obj->users = NULL;
kernel.object_table = avl_insert(kernel.object_table, kernel.next_oid, obj); kernel.object_table = avl_insert(kernel.object_table, kernel.next_oid, obj);
*id = kernel.next_oid; *id = kernel.next_oid;
kernel.next_oid++; kernel.next_oid++;

View File

@@ -1,7 +1,9 @@
#include "process.h" #include "process.h"
#include "heap.h" #include "heap.h"
#include "mmgr.h"
#include "platform/context.h" #include "platform/context.h"
#include "string.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) 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->pid = pid;
new_process->address_space = address_space; new_process->address_space = address_space;
new_process->address_space->refcount++; new_process->address_space->refcount++;
new_process->shared_objects = NULL;
new_process->state = PROCESS_ACTIVE; new_process->state = PROCESS_ACTIVE;
new_process->message_buffer = NULL; new_process->message_buffer = NULL;
new_process->ctx = initial_context; new_process->ctx = initial_context;
queue_construct(&new_process->sending_queue);
queue_construct(&new_process->message_queue); queue_construct(&new_process->message_queue);
return new_process; 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);
}

View File

@@ -22,7 +22,6 @@ struct shared_object *create_shared_object(size_t size, unsigned long flags)
obj->size = size; obj->size = size;
obj->access_flags = flags; obj->access_flags = flags;
obj->refcount = 0; obj->refcount = 0;
obj->users = NULL;
return obj; return obj;
} }
@@ -31,7 +30,6 @@ void destroy_shared_object(struct shared_object_t *obj)
if(obj != NULL) if(obj != NULL)
{ {
free_pages(obj->phys_addr); free_pages(obj->phys_addr);
avl_clear(obj->users);
kfree(obj); kfree(obj);
} }
} }

View File

@@ -2,6 +2,10 @@
#include "kernel.h" #include "kernel.h"
#include "mmgr.h" #include "mmgr.h"
#include "stdio.h" #include "stdio.h"
#include "process.h"
#include "sharedobject.h"
#include "system.h"
#include "heap.h"
#include "platform/context.h" #include "platform/context.h"
#include "types/status.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; 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; void *addr = arg_location.ptr;
unsigned long length = arg_length.unsigned_int; if((size_t)addr % page_size != 0)
if(location % page_size != 0 || length % page_size != 0)
{ {
return EINVALIDARG; return EINVALIDARG;
} }
else if(location == 0) else if(addr == NULL)
{ {
return ENULLPTR; return ENULLPTR;
} }
size_t n = 0; else if(addr >= _kernel_start)
int status = ENONE;
while(n < length && status == ENONE)
{ {
int type = page_type((void*)(location + n)); return EPERM;
physaddr_t frame;
if(type & PAGE_PRESENT)
{
frame = unmap_page((void*)(location + n));
if(type & PAGE_ANON)
{
status = free_page(frame);
}
}
} }
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) 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) 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; if(message.ptr == NULL)
unsigned long dest_type = flags.unsigned_int & IO_RECIPIENT_TYPE;
if((flags.unsigned_int & ~(IO_OP | IO_RECIPIENT_TYPE)) != 0 || dest_type >= IO_MAILBOX)
{ {
printf("Invalid flags on send()\n"); return ENULLPTR;
return EINVALIDARG;
} }
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); return EEXITED;
if(recipient.unsigned_int == 0)
{
return EDOESNTEXIST;
}
} }
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 else
{ {
return status; return ENONE;
} }
} }
int syscall_send_port(syscall_arg_t recipient, syscall_arg_t message, syscall_arg_t flags) 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) 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) int syscall_create_object(void *location, size_t size, int flags)
{ {
shared_object_t *object = create_shared_object(size, flags);
if(object == NULL)
{
return ENOMEM;
}
return ENOSYSCALL; 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) int syscall_aquire_object(oid_t id, void *location)