diff --git a/Kernel/Core/Ipc.c b/Kernel/Core/Ipc.c new file mode 100644 index 0000000..2642d66 --- /dev/null +++ b/Kernel/Core/Ipc.c @@ -0,0 +1,46 @@ +#include "Ipc.h" +#include "Process.h" +#include "Panic.h" +#include "../Memory/MemOps.h" + +void IpcSendMessage(uint32_t target_pid, IpcMessage* msg) { + ASSERT(msg != NULL); + + Process* target = GetProcessByPid(target_pid); + if (!target) { + // Handle error: target process not found + return; + } + + MessageQueue* queue = &target->ipc_queue; + if (queue->count >= MAX_MESSAGES) { + // Handle error: queue is full + return; + } + + FastMemcpy(&queue->messages[queue->tail], msg, sizeof(IpcMessage)); + queue->tail = (queue->tail + 1) % MAX_MESSAGES; + queue->count++; + + if (target->state == PROC_BLOCKED) { + target->state = PROC_READY; + } +} + +int IpcReceiveMessage(IpcMessage* msg_buffer) { + ASSERT(msg_buffer != NULL); + + Process* current = GetCurrentProcess(); + MessageQueue* queue = ¤t->ipc_queue; + + while (queue->count == 0) { + current->state = PROC_BLOCKED; + Yield(); + } + + FastMemcpy(msg_buffer, &queue->messages[queue->head], sizeof(IpcMessage)); + queue->head = (queue->head + 1) % MAX_MESSAGES; + queue->count--; + + return 0; // Success +} diff --git a/Kernel/Core/Ipc.h b/Kernel/Core/Ipc.h new file mode 100644 index 0000000..18305cb --- /dev/null +++ b/Kernel/Core/Ipc.h @@ -0,0 +1,35 @@ +#ifndef IPC_H +#define IPC_H + +#include "stdint.h" + +#define MAX_MESSAGES 16 // Max messages per process queue + +// Extensible message types +typedef enum { + IPC_TYPE_DATA, + IPC_TYPE_NOTIFICATION, + // Future types can be added here +} IpcMessageType; + +typedef struct { + uint32_t sender_pid; + IpcMessageType type; + uint64_t size; + union { + char data[256]; // For general data + uint64_t value; // For notifications or simple values + } payload; +} IpcMessage; + +typedef struct { + IpcMessage messages[MAX_MESSAGES]; + uint32_t head; + uint32_t tail; + uint32_t count; +} MessageQueue; + +void IpcSendMessage(uint32_t target_pid, IpcMessage* msg); +int IpcReceiveMessage(IpcMessage* msg_buffer); + +#endif diff --git a/Kernel/Core/Kernel.h b/Kernel/Core/Kernel.h index 804f9ce..7b2cdb7 100644 --- a/Kernel/Core/Kernel.h +++ b/Kernel/Core/Kernel.h @@ -1,5 +1,6 @@ #ifndef KERNEL_H #define KERNEL_H +#include "stdint.h" extern int CurrentLine; extern int CurrentColumn; void ClearScreen(); diff --git a/Kernel/Core/Panic.h b/Kernel/Core/Panic.h index daa2c36..ada93ad 100644 --- a/Kernel/Core/Panic.h +++ b/Kernel/Core/Panic.h @@ -7,11 +7,12 @@ void __attribute__((noreturn)) Panic(const char* message); void __attribute__((noreturn)) PanicWithCode(const char* message, uint64_t error_code); -#define STRINGIFY(x) #x +#define STRINGIFY_HELPER(x) #x +#define STRINGIFY(x) STRINGIFY_HELPER(x) #define ASSERT(condition) \ do { \ if (!(condition)) { \ - Panic("Assertion failed: " #condition " at " __FILE__ ":" STRINGIFY(__LINE__); \ + Panic("Assertion failed: " #condition " at " __FILE__ ":" STRINGIFY(__LINE__)); \ } \ } while(0) diff --git a/Kernel/Core/stdint.h b/Kernel/Core/stdint.h index 24aa78e..87de4b6 100644 --- a/Kernel/Core/stdint.h +++ b/Kernel/Core/stdint.h @@ -5,6 +5,8 @@ #ifndef VOIDFRAME_STDINT_H #define VOIDFRAME_STDINT_H +#define NULL ((void*)0) + typedef unsigned char uint8_t; _Static_assert(sizeof(uint8_t) == 1, "sizeof(uint8_t) != 1"); diff --git a/Kernel/Drivers/Cpu.c b/Kernel/Drivers/Cpu.c index e5a9319..94b13e9 100644 --- a/Kernel/Drivers/Cpu.c +++ b/Kernel/Drivers/Cpu.c @@ -1,8 +1,9 @@ #include "Cpu.h" - +#include "../Core/Panic.h" static CpuFeatures cpu_features = {0}; static void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { + ASSERT(eax != NULL && ebx != NULL && ecx != NULL && edx != NULL); asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf)); } diff --git a/Kernel/Drivers/Cpu.h b/Kernel/Drivers/Cpu.h index e7160cb..b8cd037 100644 --- a/Kernel/Drivers/Cpu.h +++ b/Kernel/Drivers/Cpu.h @@ -2,7 +2,6 @@ #define CPU_H #include "stdint.h" - typedef struct { uint8_t sse:1; uint8_t sse2:1; diff --git a/Kernel/Drivers/Interrupts.c b/Kernel/Drivers/Interrupts.c index cacf3b5..b859759 100644 --- a/Kernel/Drivers/Interrupts.c +++ b/Kernel/Drivers/Interrupts.c @@ -68,6 +68,7 @@ static void FastDisplayTicks(uint64_t ticks) { // The C-level interrupt handler void InterruptHandler(struct Registers* regs) { + ASSERT(regs != NULL); if (regs->interrupt_number == 32) { tick_count++; // FastDisplayTicks(tick_count); // Re-enabled diff --git a/Kernel/Memory/MemOps.c b/Kernel/Memory/MemOps.c index 7a65971..aae0533 100644 --- a/Kernel/Memory/MemOps.c +++ b/Kernel/Memory/MemOps.c @@ -1,7 +1,9 @@ #include "MemOps.h" #include "Cpu.h" +#include "../Core/Panic.h" void* FastMemset(void* dest, int value, uint64_t size) { + ASSERT(dest != NULL); CpuFeatures* features = GetCpuFeatures(); uint8_t* d = (uint8_t*)dest; @@ -34,6 +36,7 @@ void* FastMemset(void* dest, int value, uint64_t size) { } void* FastMemcpy(void* dest, const void* src, uint64_t size) { + ASSERT(dest != NULL && src != NULL); CpuFeatures* features = GetCpuFeatures(); uint8_t* d = (uint8_t*)dest; const uint8_t* s = (const uint8_t*)src; @@ -58,6 +61,7 @@ void* FastMemcpy(void* dest, const void* src, uint64_t size) { } void FastZeroPage(void* page) { + ASSERT(page != NULL); CpuFeatures* features = GetCpuFeatures(); if (features->sse2) { diff --git a/Kernel/Process/Process.c b/Kernel/Process/Process.c index 5a14e3c..de94ebc 100644 --- a/Kernel/Process/Process.c +++ b/Kernel/Process/Process.c @@ -4,8 +4,7 @@ #include "Panic.h" #include "Io.h" #include "../Memory/MemOps.h" - -#define NULL ((void*)0) +#include "../Core/Ipc.h" #define offsetof(type, member) ((uint64_t)&(((type*)0)->member)) static Process processes[MAX_PROCESSES]; @@ -121,7 +120,7 @@ uint32_t CreateProcess(void (*entry_point)(void)) { } void ProcessExitStub() { - PrintKernel("[KERNEL] Process returned from its main function. This is an error!\n"); + PrintKernel("[KERNEL] Process returned from its main function. -FATAL EXECPTION-\n"); PrintKernel("Terminating process PID: "); PrintKernelInt(GetCurrentProcess()->pid); PrintKernel("\n"); @@ -177,6 +176,11 @@ uint32_t CreateSecureProcess(void (*entry_point)(void), uint8_t privilege) { processes[slot].priority = (privilege == PROC_PRIV_SYSTEM) ? 10 : 100; processes[slot].is_user_mode = (privilege != PROC_PRIV_SYSTEM); + // Initialize IPC queue + processes[slot].ipc_queue.head = 0; + processes[slot].ipc_queue.tail = 0; + processes[slot].ipc_queue.count = 0; + // Create the token init_token(&processes[slot].token, creator->pid, privilege, new_pid); @@ -198,6 +202,7 @@ uint32_t CreateSecureProcess(void (*entry_point)(void), uint8_t privilege) { } void ScheduleFromInterrupt(struct Registers* regs) { + ASSERT(regs != NULL); if (process_count <= 1) return; // Save current context diff --git a/Kernel/Process/Process.h b/Kernel/Process/Process.h index 2b4972d..3375344 100644 --- a/Kernel/Process/Process.h +++ b/Kernel/Process/Process.h @@ -2,6 +2,7 @@ #define PROCESS_H #include "stdint.h" +#include "../Core/Ipc.h" #define MAX_PROCESSES 64 #define STACK_SIZE 4096 @@ -48,6 +49,7 @@ typedef struct { uint8_t privilege_level; uint8_t _padding; SecurityToken token; + MessageQueue ipc_queue; ProcessContext context; } Process; diff --git a/Kernel/Process/UserMode.c b/Kernel/Process/UserMode.c index 350b994..98e88c8 100644 --- a/Kernel/Process/UserMode.c +++ b/Kernel/Process/UserMode.c @@ -5,6 +5,7 @@ #include "Panic.h" void JumpToUserMode(void (*user_function)(void)) { + ASSERT(user_function != NULL); // Allocate user stack void* user_stack = AllocPage(); if (!user_stack) { @@ -32,6 +33,7 @@ void JumpToUserMode(void (*user_function)(void)) { } void CreateUserProcess(void (*user_function)(void)) { + ASSERT(user_function != NULL); // Create process but mark it as user mode uint32_t pid = CreateProcess(user_function); if (pid > 0) { diff --git a/Kernel/System/Syscall.c b/Kernel/System/Syscall.c index 95e70f2..81c79d3 100644 --- a/Kernel/System/Syscall.c +++ b/Kernel/System/Syscall.c @@ -4,11 +4,12 @@ #include "Idt.h" #include "Panic.h" #include "../Memory/MemOps.h" // For FastMemcpy +#include "../Core/Ipc.h" #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) extern void SyscallEntry(void); -uint64_t SyscallHandler(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3) { +uint64_t Syscall(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3) { Process* current = GetCurrentProcess(); if (unlikely(!current)) { Panic("Syscall from invalid process"); @@ -49,6 +50,15 @@ uint64_t SyscallHandler(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint case SYS_GETPID: return current ? current->pid : -1; + + case SYS_IPC_SEND: + // arg1 = target_pid, arg2 = message + IpcSendMessage((uint32_t)arg1, (IpcMessage*)arg2); + return 0; + + case SYS_IPC_RECV: + // arg1 = message_buffer + return IpcReceiveMessage((IpcMessage*)arg1); default: return -1; diff --git a/Kernel/System/Syscall.h b/Kernel/System/Syscall.h index 9af12b5..4b3eeaa 100644 --- a/Kernel/System/Syscall.h +++ b/Kernel/System/Syscall.h @@ -8,12 +8,14 @@ #define SYS_WRITE 2 #define SYS_READ 3 #define SYS_GETPID 4 +#define SYS_IPC_SEND 5 +#define SYS_IPC_RECV 6 #define SYSCALL_INTERRUPT_VECTOR 0x80 #define IDT_INTERRUPT_GATE_KERNEL 0x8E #define SYSCALL_SEGMENT_SELECTOR 0x08 #define MAX_SYSCALL_BUFFER_SIZE 4096 // System call handler void SyscallInit(void); -uint64_t SyscallHandler(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3); +uint64_t Syscall(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3); #endif \ No newline at end of file diff --git a/Kernel/System/SyscallEntry.asm b/Kernel/System/SyscallEntry.asm index fe550ae..2a64875 100644 --- a/Kernel/System/SyscallEntry.asm +++ b/Kernel/System/SyscallEntry.asm @@ -1,6 +1,6 @@ bits 64 -extern SyscallHandler +extern Syscall global SyscallEntry @@ -28,7 +28,7 @@ SyscallEntry: mov rdx, rcx ; arg2 mov rcx, r8 ; arg3 - call SyscallHandler + call Syscall ; Return value in rax is already set diff --git a/meson.build b/meson.build index 8ae1147..1794ab4 100644 --- a/meson.build +++ b/meson.build @@ -63,6 +63,7 @@ c_sources = [ 'Kernel/Drivers/Interrupts.c', 'Kernel/Drivers/Pic.c', 'Kernel/Drivers/Cpu.c', + 'Kernel/Core/Ipc.c' ] # Build include flags