Working on reorganizing kernel.c
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,7 +6,7 @@ quark-kernel
|
||||
autom4te.cache/
|
||||
.deps
|
||||
.dirstamp
|
||||
.vscode
|
||||
#.vscode
|
||||
aclocal.m4
|
||||
ar-lib
|
||||
compile
|
||||
|
||||
45
.vscode/c_cpp_properties.json
vendored
Normal file
45
.vscode/c_cpp_properties.json
vendored
Normal 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
37
.vscode/launch.json
vendored
Normal 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
28
.vscode/settings.json
vendored
Normal 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
27
.vscode/tasks.json
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
types/sigaction.h types/message.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
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -4,14 +4,13 @@
|
||||
#include "types/physaddr.h"
|
||||
#include <stddef.h>
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
13
include/types/message.h
Normal file
13
include/types/message.h
Normal 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
10
include/types/signalid.h
Normal 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
|
||||
@@ -19,4 +19,26 @@ address_space_t *address_space_construct()
|
||||
|
||||
as->refcount = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
100
src/kernel.c
100
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++;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
125
src/syscalls.c
125
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)
|
||||
|
||||
Reference in New Issue
Block a user