Added IPC skeleton

This commit is contained in:
2025-05-07 18:53:41 +02:00
parent 2cd84b5e89
commit 2b4beae3c5
10 changed files with 182 additions and 35 deletions
+51
View File
@@ -0,0 +1,51 @@
#ifndef _IPC_H
#define _IPC_H
#include <kernel.h>
/*
* Message contents
*/
// Basic data
struct msg_uint8 { uint8_t data[56]; };
struct msg_uint16 { uint16_t data[28]; };
struct msg_uint32 { uint32_t data[14]; };
struct msg_uint64 { uint64_t data[7]; };
/*
* Message content types
*/
enum {
MSG_UINT8,
MSG_UINT16,
MSG_UINT32,
MSG_UINT64,
};
/*
* Message struct
*/
typedef struct {
pid_t sender;
uint32_t type;
union {
struct msg_uint8 m_uint8;
struct msg_uint16 m_uint16;
struct msg_uint32 m_uint32;
struct msg_uint64 m_uint64;
// Makes sure that ipc_msg_t is at least 64 bytes
uint8_t size[56];
};
} ipc_msg_t __align(16);
// Compile time check that ipc_msg_t is 64 bytes
typedef int __ASSERT_ipc_msg_t[(sizeof(ipc_msg_t) == 64) ? 1 : -1];
/*
* IPC handlers
*/
int ipc_send(pid_t dst, ipc_msg_t* msg);
int ipc_recv(pid_t src, ipc_msg_t* msg);
#endif
+8
View File
@@ -30,6 +30,9 @@ typedef char* va_list;
/*
* Utility macros
*/
#define STATIC_ASSERT(_cond, _msg)\
typedef int static_assert_##_msg[(_cond) ? 1 : -1]
#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
#define BIT(_n) (1UL << (_n))
#define BIT_MASK(_n) (BIT(_n) - 1)
@@ -84,6 +87,11 @@ typedef int32_t intptr_t;
#define true 1
#define false 0
/*
* System types
*/
typedef uint32_t pid_t;
/*
* Linker defined values
*/
+10 -3
View File
@@ -2,14 +2,21 @@
#define _SYSCALL_H
#include <kernel.h>
#include <ipc.h>
#include <isr.h>
#define SYSCALL_MAX 2
#define SYS_EXIT 0
#define SYS_TEST 1
#define SYSCALL_MAX 16
enum {
SYS_SEND,
SYS_RECV,
};
int syscall_init(void);
void syscall_register(size_t idx, void* handler);
void syscall_handler(struct isr_int_frame* iframe);
// Syscall handlers
int sys_send(pid_t dst, ipc_msg_t* msg);
int sys_recv(pid_t src, ipc_msg_t* msg);
#endif
+9 -8
View File
@@ -9,6 +9,7 @@ enum {
TASK_STATE_DEAD,
TASK_STATE_IDLE,
TASK_STATE_READY,
TASK_STATE_RECV,
};
/*
@@ -30,7 +31,7 @@ enum {
* task.s which uses hardcoded offsets.
*/
struct task {
size_t id;
pid_t id;
size_t kstack_pointer;
size_t kstack_bottom;
@@ -58,13 +59,13 @@ extern struct task* task_first;
extern struct task* task_current;
int task_init(void);
void task_create(size_t id, uint32_t eip, int kernel_task, uint32_t* pagedir, int argc, char** argv);
void task_kill(size_t id);
void task_set_user_heap(struct task* task, size_t heap_end);
struct task* task_get(size_t id);
uint8_t task_get_state(size_t id);
void task_set_state(size_t id, uint8_t state);
size_t task_create_id(void);
void task_create(pid_t id, uint32_t eip, int kernel_task, uint32_t* pagedir, int argc, char** argv);
void task_kill(pid_t id);
void task_set_user_heap(pid_t id, size_t heap_end);
struct task* task_get(pid_t id);
uint8_t task_get_state(pid_t id);
void task_set_state(pid_t id, uint8_t state);
pid_t task_create_id(void);
// Defined in task.s
extern void task_switch(struct task* old, struct task* new);
+16
View File
@@ -0,0 +1,16 @@
#include <kernel.h>
#include <ipc.h>
int ipc_send(pid_t dst, ipc_msg_t* msg) {
(void)dst;
(void)msg;
return 0;
}
int ipc_recv(pid_t src, ipc_msg_t* msg) {
(void)src;
(void)msg;
return 0;
}
-4
View File
@@ -36,10 +36,6 @@ void kmain(void* ptr, uint32_t magic) {
if (syscall_init() != 0) panic("Failed to initialize syscalls.");
if (task_init() != 0) panic("Failed to initialize tasking.");
char* s = "Hello, World!";
__asm__ volatile("int $0x80" :: "a"(SYS_TEST), "b"(s));
// TODO: Interprocess communication
// TODO: Load & run /sbin/init
// We don't want to halt
+14 -11
View File
@@ -1,5 +1,6 @@
#include <kernel.h>
#include <task.h>
#include <ipc.h>
#include <tty.h>
#include <syscall.h>
@@ -7,24 +8,26 @@
// Syscall table
void* syscalls[SYSCALL_MAX] = { 0 };
void sys_exit(int code) {
debugf("[syscall] Task #%d exited with code %d.\n", task_current->id, code);
task_kill(task_current->id);
}
void sys_test(char* msg) {
debugf("[syscall] Test: %s\n", msg);
}
int syscall_init(void) {
syscall_register(SYS_EXIT, (void*)sys_exit);
syscall_register(SYS_TEST, (void*)sys_test);
syscall_register(SYS_SEND, (void*)sys_send);
syscall_register(SYS_RECV, (void*)sys_recv);
debugf("[syscall] Initiated syscalls!\n");
return 0;
}
int sys_send(pid_t dst, ipc_msg_t* msg) {
msg->sender = task_current->id;
debugf("[syscall] Task #%d sent a message to Task #%d.\n", msg->sender, dst);
return ipc_send(dst, msg);
}
int sys_recv(pid_t src, ipc_msg_t* msg) {
debugf("[syscall] Task #%d is receiving a message from Task #%d.\n", task_current->id, src);
return 0;
}
void syscall_register(size_t idx, void* handler) {
if (idx > SYSCALL_MAX) {
debugf("[syscall] Failed to register syscall #%d.\n", idx);
+10 -8
View File
@@ -32,7 +32,7 @@ int task_init(void) {
return 0;
}
void task_create(size_t id, uint32_t eip, int kernel_task, uint32_t* pagedir, int argc, char** argv) {
void task_create(pid_t id, uint32_t eip, int kernel_task, uint32_t* pagedir, int argc, char** argv) {
cli();
uint32_t kstack = (uint32_t)kmalloc(0x1000 - 16) + (0x1000 - 16);
@@ -129,7 +129,7 @@ void task_create(size_t id, uint32_t eip, int kernel_task, uint32_t* pagedir, in
pag_set_pagedir(old_pagedir);
}
void task_kill(size_t id) {
void task_kill(pid_t id) {
cli();
struct task* current = task_first;
@@ -174,7 +174,9 @@ void task_kill(size_t id) {
sti();
}
void task_set_user_heap(struct task* task, size_t heap_end) {
void task_set_user_heap(pid_t id, size_t heap_end) {
struct task* task = task_get(id);
if (heap_end <= task->heap_start) {
debugf("[task] Task %d tried to shrink heap bellow 0.\n", task->id);
task_kill(task->id);
@@ -212,7 +214,7 @@ void task_set_user_heap(struct task* task, size_t heap_end) {
task->heap_end = heap_end;
}
struct task* task_get(size_t id) {
struct task* task_get(pid_t id) {
struct task* find = task_first;
while (find != NULL) {
if (find->id == id) break;
@@ -222,22 +224,22 @@ struct task* task_get(size_t id) {
return find;
}
uint8_t task_get_state(size_t id) {
uint8_t task_get_state(pid_t id) {
struct task* t = task_get(id);
if (t == NULL) return TASK_STATE_DEAD;
return t->state;
}
void task_set_state(size_t id, uint8_t state) {
void task_set_state(pid_t id, uint8_t state) {
struct task* t = task_get(id);
if (t == NULL) return;
t->state = state;
}
size_t task_create_id(void) {
pid_t task_create_id(void) {
struct task* current = task_first;
size_t max = current->id;
pid_t max = current->id;
current = current->next;
while (current != NULL) {
if (max < current->id) max = current->id;