summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/cpu/syscall.c55
-rw-r--r--kernel/includes/syscalls.h5
-rw-r--r--kernel/ipc.c95
-rw-r--r--kernel/ipc.h26
-rw-r--r--kernel/libc/exit/assert.c4
-rw-r--r--kernel/libc/include/assert.h8
-rw-r--r--kernel/sched/scheduler.c14
-rw-r--r--kernel/sched/scheduler.h4
-rw-r--r--kernel/syscalls/ipc.c18
-rw-r--r--userland/libc/include/syscall.h5
11 files changed, 214 insertions, 22 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 0778cb3..a36e84c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -1,6 +1,6 @@
CC="i686-sb-gcc"
AS="i686-sb-as"
-OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o
+OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o ipc.o syscalls/ipc.o
CFLAGS = -O3 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL
INCLUDE=-I./includes/ -I../include/ -I./libc/include/
diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c
index 9aecc42..5fd6828 100644
--- a/kernel/cpu/syscall.c
+++ b/kernel/cpu/syscall.c
@@ -114,24 +114,45 @@ int syscall_openpty(SYS_OPENPTY_PARAMS *args) {
}
void (*syscall_functions[])() = {
- (void(*))syscall_open, (void(*))syscall_read,
- (void(*))syscall_write, (void(*))syscall_pread,
- (void(*))syscall_pwrite, (void(*))syscall_fork,
- (void(*))syscall_exec, (void(*))syscall_getpid,
- (void(*))syscall_exit, (void(*))syscall_wait,
- (void(*))syscall_brk, (void(*))syscall_sbrk,
- (void(*))syscall_pipe, (void(*))syscall_dup2,
- (void(*))syscall_close, (void(*))syscall_openpty,
- (void(*))syscall_poll, (void(*))syscall_mmap,
- (void(*))syscall_accept, (void(*))syscall_bind,
- (void(*))syscall_socket, (void(*))syscall_shm_open,
- (void(*))syscall_ftruncate, (void(*))syscall_stat,
- (void(*))syscall_msleep, (void(*))syscall_uptime,
- (void(*))syscall_mkdir, (void(*))syscall_recvfrom,
- (void(*))syscall_sendto, (void(*))syscall_kill,
- (void(*))syscall_sigaction, (void(*))syscall_chdir,
- (void(*))syscall_getcwd, (void(*))syscall_isatty,
+ (void(*))syscall_open,
+ (void(*))syscall_read,
+ (void(*))syscall_write,
+ (void(*))syscall_pread,
+ (void(*))syscall_pwrite,
+ (void(*))syscall_fork,
+ (void(*))syscall_exec,
+ (void(*))syscall_getpid,
+ (void(*))syscall_exit,
+ (void(*))syscall_wait,
+ (void(*))syscall_brk,
+ (void(*))syscall_sbrk,
+ (void(*))syscall_pipe,
+ (void(*))syscall_dup2,
+ (void(*))syscall_close,
+ (void(*))syscall_openpty,
+ (void(*))syscall_poll,
+ (void(*))syscall_mmap,
+ (void(*))syscall_accept,
+ (void(*))syscall_bind,
+ (void(*))syscall_socket,
+ (void(*))syscall_shm_open,
+ (void(*))syscall_ftruncate,
+ (void(*))syscall_stat,
+ (void(*))syscall_msleep,
+ (void(*))syscall_uptime,
+ (void(*))syscall_mkdir,
+ (void(*))syscall_recvfrom,
+ (void(*))syscall_sendto,
+ (void(*))syscall_kill,
+ (void(*))syscall_sigaction,
+ (void(*))syscall_chdir,
+ (void(*))syscall_getcwd,
+ (void(*))syscall_isatty,
(void(*))syscall_randomfill,
+ (void(*))syscall_ipc_register_endpoint,
+ (void(*))syscall_ipc_read,
+ (void(*))syscall_ipc_write,
+ (void(*))syscall_ipc_write_to_process,
};
void syscall_function_handler(u32 eax, u32 arg1, u32 arg2, u32 arg3, u32 arg4,
diff --git a/kernel/includes/syscalls.h b/kernel/includes/syscalls.h
index 7b2a966..46218ce 100644
--- a/kernel/includes/syscalls.h
+++ b/kernel/includes/syscalls.h
@@ -8,6 +8,11 @@
#include <typedefs.h>
#include <types.h>
+int syscall_ipc_register_endpoint(u32 endpoint);
+int syscall_ipc_read(u8 *buffer, u32 length, u32 *sender_pid);
+int syscall_ipc_write(int ipc_id, u8 *buffer, u32 length);
+int syscall_ipc_write_to_process(int pid, u8 *buffer, u32 length);
+
typedef struct SYS_ACCEPT_PARAMS {
int socket;
struct sockaddr *address;
diff --git a/kernel/ipc.c b/kernel/ipc.c
new file mode 100644
index 0000000..3422cc7
--- /dev/null
+++ b/kernel/ipc.c
@@ -0,0 +1,95 @@
+#include <assert.h>
+#include <ipc.h>
+#include <math.h>
+#include <sched/scheduler.h>
+#include <stdbool.h>
+#include <string.h>
+
+struct IpcEndpoint {
+ u8 in_use;
+ u32 pid;
+};
+
+struct IpcEndpoint ipc_endpoints[100];
+
+bool ipc_register_endpoint(u32 endpoint) {
+ if (endpoint >= 100)
+ return false;
+ if (ipc_endpoints[endpoint].in_use)
+ return false;
+ ipc_endpoints[endpoint].in_use = 1;
+ ipc_endpoints[endpoint].pid = get_current_task()->pid;
+ return true;
+}
+
+bool ipc_endpoint_to_pid(u32 endpoint, u32 *pid) {
+ if (endpoint >= 100)
+ return false;
+ if (!ipc_endpoints[endpoint].in_use)
+ return false;
+ *pid = ipc_endpoints[endpoint].pid;
+ return true;
+}
+
+int ipc_get_mailbox(u32 id, struct IpcMailbox **out) {
+ process_t *p;
+ if (!get_task_from_pid(id, &p))
+ return 0;
+ *out = &p->ipc_mailbox;
+ return 1;
+}
+
+int ipc_read(u8 *buffer, u32 length, u32 *sender_pid) {
+ struct IpcMailbox *handler = &get_current_task()->ipc_mailbox;
+
+ u32 read_ptr = handler->read_ptr;
+ struct IpcMessage *ipc_message = NULL;
+ for (;;) {
+ ipc_message = &handler->data[read_ptr];
+ if (!ipc_message->is_used) {
+ asm("sti");
+ continue;
+ }
+ break;
+ }
+ ipc_message->is_used = 0;
+ // TODO: Verify sender_pid is a valid address
+ if (sender_pid)
+ *sender_pid = ipc_message->sender_pid;
+
+ u32 len = min(length, ipc_message->size);
+ memcpy(buffer, ipc_message->buffer, len);
+
+ // Update read_ptr
+ read_ptr++;
+ if (read_ptr >= IPC_NUM_DATA)
+ read_ptr = 0;
+ handler->read_ptr = read_ptr;
+ return len;
+}
+
+int ipc_write_to_process(int pid, u8 *buffer, u32 length) {
+ struct IpcMailbox *handler;
+ assert(ipc_get_mailbox(pid, &handler));
+
+ u32 write_ptr = handler->write_ptr;
+ struct IpcMessage *ipc_message = &handler->data[write_ptr];
+ ipc_message->is_used = 1;
+ u32 len = min(IPC_BUFFER_SIZE, length);
+ ipc_message->sender_pid = get_current_task()->pid;
+ ipc_message->size = len;
+ memcpy(ipc_message->buffer, buffer, len);
+
+ // Update write_ptr
+ write_ptr++;
+ if (write_ptr >= IPC_NUM_DATA)
+ write_ptr = 0;
+ handler->write_ptr = write_ptr;
+ return len;
+}
+
+int ipc_write(int endpoint, u8 *buffer, u32 length) {
+ u32 pid;
+ assert(ipc_endpoint_to_pid(endpoint, &pid));
+ return ipc_write_to_process(pid, buffer, length);
+}
diff --git a/kernel/ipc.h b/kernel/ipc.h
new file mode 100644
index 0000000..cfa9e6d
--- /dev/null
+++ b/kernel/ipc.h
@@ -0,0 +1,26 @@
+#ifndef IPC_H
+#define IPC_H
+#include <stdbool.h>
+#include <typedefs.h>
+
+#define IPC_BUFFER_SIZE 4096
+#define IPC_NUM_DATA 32
+
+struct IpcMessage {
+ u8 is_used;
+ u32 sender_pid;
+ u32 size;
+ u8 buffer[IPC_BUFFER_SIZE];
+};
+
+struct IpcMailbox {
+ u32 read_ptr;
+ u32 write_ptr;
+ struct IpcMessage data[IPC_NUM_DATA];
+};
+
+bool ipc_register_endpoint(u32 endpoint);
+int ipc_write_to_process(int pid, u8 *buffer, u32 length);
+int ipc_write(int ipc_id, u8 *buffer, u32 length);
+int ipc_read(u8 *buffer, u32 length, u32 *sender_pid);
+#endif
diff --git a/kernel/libc/exit/assert.c b/kernel/libc/exit/assert.c
index b48773a..3351249 100644
--- a/kernel/libc/exit/assert.c
+++ b/kernel/libc/exit/assert.c
@@ -1,12 +1,12 @@
#include <assert.h>
#include <log.h>
#include <stdio.h>
-#include <log.h>
-void aFailed(char *f, int l) {
+__attribute__((__noreturn__)) void aFailed(char *f, int l) {
kprintf("Assert failed\n");
kprintf("%s : %d\n", f, l);
dump_backtrace(10);
+ asm("hlt");
for (;;)
;
}
diff --git a/kernel/libc/include/assert.h b/kernel/libc/include/assert.h
index 90a0be4..d6525f0 100644
--- a/kernel/libc/include/assert.h
+++ b/kernel/libc/include/assert.h
@@ -1,10 +1,16 @@
#include <log.h>
#include <stdio.h>
+// This infinite loop is needed for GCC to understand that
+// aFailed does not return. No clue why the attribute does
+// help solve the issue.
#define assert(expr) \
{ \
- if (!(expr)) \
+ if (!(expr)) { \
aFailed(__FILE__, __LINE__); \
+ for (;;) \
+ ; \
+ } \
}
#define ASSERT_BUT_FIXME_PROPOGATE(expr) \
diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c
index 7d13277..ccc5956 100644
--- a/kernel/sched/scheduler.c
+++ b/kernel/sched/scheduler.c
@@ -17,7 +17,19 @@ u32 next_pid = 0;
extern u32 read_eip(void);
-process_t *get_current_task(void) { return current_task; }
+process_t *get_current_task(void) {
+ return current_task;
+}
+
+bool get_task_from_pid(u32 pid, process_t **out) {
+ for (process_t *tmp = ready_queue; tmp; tmp = tmp->next) {
+ if (tmp->pid == pid) {
+ *out = tmp;
+ return true;
+ }
+ }
+ return false;
+}
void set_signal_handler(int sig, void (*handler)(int)) {
if (sig >= 20 || sig < 0)
diff --git a/kernel/sched/scheduler.h b/kernel/sched/scheduler.h
index f57a319..17e5d56 100644
--- a/kernel/sched/scheduler.h
+++ b/kernel/sched/scheduler.h
@@ -3,8 +3,10 @@
#include <fs/ext2.h>
#include <fs/vfs.h>
#include <halts.h>
+#include <ipc.h>
#include <mmu.h>
#include <signal.h>
+#include <stdbool.h>
#define MAX_PATH 256
#define KEYBOARD_HALT 0
@@ -41,6 +43,7 @@ struct Process {
u32 signal_handler_stack;
void *signal_handlers[20];
PageDirectory *cr3;
+ struct IpcMailbox ipc_mailbox;
vfs_fd_t *file_descriptors[100];
vfs_inode_t *read_halt_inode[100];
vfs_inode_t *write_halt_inode[100];
@@ -59,6 +62,7 @@ struct Process {
int dead;
};
+bool get_task_from_pid(u32 pid, process_t **out);
process_t *get_current_task(void);
int get_free_fd(process_t *p, int allocate);
void free_process(void);
diff --git a/kernel/syscalls/ipc.c b/kernel/syscalls/ipc.c
new file mode 100644
index 0000000..b6947d1
--- /dev/null
+++ b/kernel/syscalls/ipc.c
@@ -0,0 +1,18 @@
+#include <ipc.h>
+#include <syscalls.h>
+
+int syscall_ipc_register_endpoint(u32 id) {
+ return ipc_register_endpoint(id);
+}
+
+int syscall_ipc_read(u8 *buffer, u32 length, u32 *sender_pid) {
+ return ipc_read(buffer, length, sender_pid);
+}
+
+int syscall_ipc_write_to_process(int pid, u8 *buffer, u32 length) {
+ return ipc_write_to_process(pid, buffer, length);
+}
+
+int syscall_ipc_write(int endpoint, u8 *buffer, u32 length) {
+ return ipc_write(endpoint, buffer, length);
+}
diff --git a/userland/libc/include/syscall.h b/userland/libc/include/syscall.h
index 7a3b50d..b50c061 100644
--- a/userland/libc/include/syscall.h
+++ b/userland/libc/include/syscall.h
@@ -41,6 +41,11 @@
#define SYS_ISATTY 33
#define SYS_RANDOMFILL 34
+#define SYS_IPC_REGISTER_ENDPOINT 35
+#define SYS_IPC_READ 36
+#define SYS_IPC_WRITE 37
+#define SYS_IPC_WRITE_TO_PROCESS 38
+
int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx,
uint32_t esi, uint32_t edi);
int s_syscall(int sys);