diff --git a/build.bat b/build.bat index 2032d36..2b05089 100644 --- a/build.bat +++ b/build.bat @@ -20,6 +20,7 @@ mkdir "obj\syscall" 2>nul mkdir "obj\win32" 2>nul mkdir "obj\posix" 2>nul mkdir "obj\drivers" 2>nul +mkdir "obj\init" 2>nul mkdir "obj\shell" 2>nul mkdir "obj\video" 2>nul mkdir "bin" 2>nul @@ -112,6 +113,16 @@ cl %CFLAGS% /I"%SRC%\usb" /c /Fo"obj\drivers\usb.obj" "%SRC%\drivers\usb\usb.c" link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:"bin\usb.sys" /ENTRY:DriverEntry ^ bin\hal.lib bin\kernel.lib obj\libc.obj obj\drivers\usb.obj || exit /b 1 +:: ---- Compile init ---- +echo Compiling init... +for %%f in (%SRC%\shell\*.c) do ( + cl %CFLAGS% /c /Fo"obj\shell\%%~nf.obj" "%%f" || exit /b 1 +) + +:: ---- Link init.exe ---- +link %LFLAGS% /SUBSYSTEM:NATIVE /ENTRY:_start ^ + /OUT:"bin\init.exe" /PDB:"bin\init.pdb" bin\syscall.lib obj\libc.obj obj\init\init.obj || exit /b 1 + :: ---- Compile shell ---- echo Compiling shell... for %%f in (%SRC%\shell\*.c) do ( @@ -168,11 +179,13 @@ copy /y "bin\ide.sys" "%DEST%\drivers\" copy /y "bin\ahci.sys" "%DEST%\drivers\" copy /y "bin\fat32.sys" "%DEST%\drivers\" copy /y "bin\usb.sys" "%DEST%\drivers\" +copy /y "bin\init.exe" "%DEST%\" copy /y "bin\shell.exe" "%DEST%\" copy /y "bin\video.exe" "%DEST%\" copy /y "%SRC%\boot.ini" "%DEST%\" copy /y "%SRC%\drivers\drivers.ini" "%DEST%\drivers\" if exist "%SRC%\video\bink2w64.dll" copy /y "%SRC%\video\bink2w64.dll" "%DEST%\" +if exist "video.bk2" copy /y "video.bk2" "%DEST%\" :: ---- Unmount disk image ---- echo Unmounting disk.vhd... diff --git a/code/boot.ini b/code/boot.ini index 7c91c2e..c9d8d68 100644 --- a/code/boot.ini +++ b/code/boot.ini @@ -1,4 +1,4 @@ [kernel] debug = 1 [init] -commandline = shell.exe +commandline = init.exe diff --git a/code/init/init.c b/code/init/init.c new file mode 100644 index 0000000..a2cc8df --- /dev/null +++ b/code/init/init.c @@ -0,0 +1,40 @@ +// init.c - first user-mode process +#include +#include +#include + +// --------------------------------------------------------------------------- +// Syscall stubs +// --------------------------------------------------------------------------- +extern uint32_t SysCreateProcess(const char* path, uint32_t* handleOut, + const char* cmdline); +extern uint32_t SysCloseHandle(uint32_t handle); +extern void SysDebugPrint(const char* str); +extern uint32_t SysWaitForProcess(uint32_t handle); +extern void SysExitProcess(int code); +extern void SysYield(void); + +#define STATUS_SUCCESS 0u + +void _start() +{ + uint32_t h = 0; + uint32_t s = 0; + + SysDebugPrint("[init] starting shell\n"); + s = SysCreateProcess("shell.exe", &h, NULL); + if (s != STATUS_SUCCESS) { + SysDebugPrint("[init] FATAL: failed to start shell.exe\n"); + SysExitProcess(1); + } + + SysDebugPrint("[init] waiting for shell\n"); + s = SysWaitForProcess(h); + if (s != STATUS_SUCCESS) + SysDebugPrint("[init] WARNING: SysWaitForProcess returned error\n"); + SysCloseHandle(h); + + SysDebugPrint("[init] done\n"); + + SysExitProcess(0); +} diff --git a/code/kernel/ke_debug.c b/code/kernel/ke_debug.c index 5ec84d7..9736988 100644 --- a/code/kernel/ke_debug.c +++ b/code/kernel/ke_debug.c @@ -55,7 +55,7 @@ __declspec(dllexport) _Noreturn void KePanic(const char *fmt, ...) { } // KePrintConsole - write user-visible console text in white-on-black. -// Used by SYS_WRITE_CONSOLE so user programs get a distinct colour from +// Used by SYS_WRITE_CONSOLE so user programs get a distinct color from // kernel debug output (green) and panic output (red). __declspec(dllexport) void KePrintConsole(const char* buf, size_t len) { if (!buf || !PrintChar) return; diff --git a/code/kernel/ke_process.c b/code/kernel/ke_process.c index 7ec5efd..c2366fd 100644 --- a/code/kernel/ke_process.c +++ b/code/kernel/ke_process.c @@ -174,3 +174,20 @@ OBJECT* KeLookupHandle(PROCESS* process, uint32_t handle) { KeReleaseSpinlock(&process->HandleLock, flags); return obj; } + +PROCESS* KeGetProcessById(uint32_t pid) { + uintptr_t flags = KeAcquireSpinlock(&gProcessListLock); + LIST_ENTRY* head = &gProcessList; + LIST_ENTRY* node = head->Fwd; + while (node != head) { + PROCESS* p = CONTAINING_RECORD(node, PROCESS, GlobalLink); + if (p->ProcessId == pid) { + ObReferenceObject(&p->Header); + KeReleaseSpinlock(&gProcessListLock, flags); + return p; + } + node = node->Fwd; + } + KeReleaseSpinlock(&gProcessListLock, flags); + return (PROCESS*)0; +} diff --git a/code/kernel/ke_process.h b/code/kernel/ke_process.h index 4ddfc70..e662c22 100644 --- a/code/kernel/ke_process.h +++ b/code/kernel/ke_process.h @@ -55,3 +55,5 @@ OBJECT* KeLookupHandle(PROCESS* process, uint32_t handle); /* Return the global process list head (kernel-internal). */ LIST_ENTRY* KeGetProcessList(void); PROCESS* KeGetCurrentProcess(void); +/* Find a live process by its ProcessId. Bumps refcount; caller must ObDereferenceObject. */ +PROCESS* KeGetProcessById(uint32_t pid); diff --git a/code/kernel/ke_syscall.c b/code/kernel/ke_syscall.c index 18ef615..fee118d 100644 --- a/code/kernel/ke_syscall.c +++ b/code/kernel/ke_syscall.c @@ -664,7 +664,50 @@ static uint64_t SyscallKbReadScancode(uint64_t a0, uint64_t a1, uint64_t a2, } // --------------------------------------------------------------------------- -// SYS_GET_TICK (38) -> uint64_t milliseconds +// SYS_KB_GET_MODIFIERS (43) -> uint32_t +// --------------------------------------------------------------------------- +static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a0; (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + if (!gHal) return 0; + return (uint64_t)gHal->Keyboard.GetModifiers(); +} + +// --------------------------------------------------------------------------- +// SYS_MOUSE_POLL (44) -> 1 or 0 +// --------------------------------------------------------------------------- +static uint64_t SyscallMousePoll(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a0; (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + if (!gHal) return 0; + return gHal->Mouse.Poll() ? 1u : 0u; +} + +// --------------------------------------------------------------------------- +// SYS_MOUSE_READ (45) a0=*dx a1=*dy a2=*buttons -> 1 or 0 +// --------------------------------------------------------------------------- +static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a3; (void)a4; (void)a5; + if (!gHal) return 0; + return gHal->Mouse.Read((int*)(uintptr_t)a0, + (int*)(uintptr_t)a1, + (uint8_t*)(uintptr_t)a2) ? 1u : 0u; +} + +// --------------------------------------------------------------------------- +// SYS_MOUSE_GET_POS (46) a0=*x a1=*y +// --------------------------------------------------------------------------- +static uint64_t SyscallMouseGetPos(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a2; (void)a3; (void)a4; (void)a5; + if (!gHal) return 0; + gHal->Mouse.GetPosition((int*)(uintptr_t)a0, (int*)(uintptr_t)a1); + return 0; +} + +// --------------------------------------------------------------------------- +// SYS_GET_TICK (47) -> uint64_t milliseconds // --------------------------------------------------------------------------- static uint64_t SyscallGetTick(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { @@ -931,6 +974,173 @@ static uint64_t SyscallGetProcessPid(uint64_t a0, uint64_t a1, uint64_t a2, return STATUS_SUCCESS; } +// =========================================================================== +// Named Queue Registry +// +// A flat, fixed-size table of { name -> QUEUE* } pairs protected by a +// spinlock. The registry holds one reference to each published queue for +// the lifetime of the entry, so the queue object cannot be destroyed while +// it is registered even if every process closes its own handle to it. +// +// Limits: NAMED_QUEUE_MAX names, each up to NAMED_QUEUE_NAME_MAX bytes. +// These are generous for the intended usage (a handful of system servers). +// =========================================================================== + +#define NAMED_QUEUE_MAX 16 +#define NAMED_QUEUE_NAME_MAX 64 + +typedef struct { + char Name[NAMED_QUEUE_NAME_MAX]; + QUEUE* Queue; // NULL = slot free; non-NULL = occupied + uint32_t PublisherPid; // ProcessId of whoever called SysPublishQueue +} NAMED_QUEUE_ENTRY; + +static NAMED_QUEUE_ENTRY gNamedQueues[NAMED_QUEUE_MAX]; +static SPINLOCK gNamedQueueLock; + +// --------------------------------------------------------------------------- +// SYS_PUBLISH_QUEUE (55) a0=*name a1=queueHandle +// +// Registers the queue identified by 'queueHandle' under 'name'. +// Fails with STATUS_ALREADY_EXISTS if the name is already taken. +// The registry bumps the queue's refcount so it outlives the handle. +// --------------------------------------------------------------------------- +static uint64_t SyscallPublishQueue(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a2; (void)a3; (void)a4; (void)a5; + + const char* name = (const char*)(uintptr_t)a0; + if (!name || !name[0]) return STATUS_INVALID_PARAMETER; + + // Resolve the handle to a QUEUE object. HandleToObject bumps the + // refcount by one; we keep that ref in the registry slot. + QUEUE* q = (QUEUE*)HandleToObject((uint32_t)a1, ObjectTypeQueue); + if (!q) return STATUS_INVALID_HANDLE; + + uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock); + + // Reject duplicate names. + for (int i = 0; i < NAMED_QUEUE_MAX; i++) { + if (gNamedQueues[i].Queue && + strncmp(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX) == 0) { + KeReleaseSpinlock(&gNamedQueueLock, flags); + ObDereferenceObject(&q->Header); // drop the ref we just took + return STATUS_ALREADY_EXISTS; + } + } + + // Find a free slot. + for (int i = 0; i < NAMED_QUEUE_MAX; i++) { + if (!gNamedQueues[i].Queue) { + strncpy(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX - 1); + gNamedQueues[i].Name[NAMED_QUEUE_NAME_MAX - 1] = '\0'; + gNamedQueues[i].Queue = q; // ref transferred to registry + gNamedQueues[i].PublisherPid = KeGetCurrentProcess()->ProcessId; + KeReleaseSpinlock(&gNamedQueueLock, flags); + return STATUS_SUCCESS; + } + } + + KeReleaseSpinlock(&gNamedQueueLock, flags); + ObDereferenceObject(&q->Header); // no room - drop the ref + return STATUS_NO_MEMORY; +} + +// --------------------------------------------------------------------------- +// SYS_OPEN_NAMED_QUEUE (56) a0=*name a1=*handleOut +// +// Looks up 'name' in the registry and allocates a handle to the queue in the +// calling process's handle table. Returns STATUS_NOT_FOUND if no match. +// Callers that race against the publisher should retry on NOT_FOUND. +// --------------------------------------------------------------------------- +static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a2; (void)a3; (void)a4; (void)a5; + + const char* name = (const char*)(uintptr_t)a0; + uint32_t* handleOut = (uint32_t*)(uintptr_t)a1; + if (!name || !name[0] || !handleOut) return STATUS_INVALID_PARAMETER; + + uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock); + + QUEUE* q = NULL; + for (int i = 0; i < NAMED_QUEUE_MAX; i++) { + if (gNamedQueues[i].Queue && + strncmp(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX) == 0) { + q = gNamedQueues[i].Queue; + ObReferenceObject(&q->Header); // one ref for the new handle + break; + } + } + + KeReleaseSpinlock(&gNamedQueueLock, flags); + + if (!q) return STATUS_NOT_FOUND; + + // AllocHandleForCurrent consumes the ref we just bumped. + // On failure it calls ObDereferenceObject internally. + return AllocHandleForCurrent(&q->Header, handleOut); +} + +// --------------------------------------------------------------------------- +// SYS_QUEUE_DUPLICATE (61) a0=handle a1=targetPid a2=*handleOut +// +// Looks up the QUEUE behind 'handle' in the CALLER's table, then allocates +// a new handle for the same object in the TARGET process's table. +// Both processes share the same underlying QUEUE (refcount bumped). +// The caller's own handle is unchanged. +// --------------------------------------------------------------------------- +static uint64_t SyscallQueueDuplicate(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a3; (void)a4; (void)a5; + if (!a2) return STATUS_INVALID_PARAMETER; + + QUEUE* q = (QUEUE*)HandleToObject((uint32_t)a0, ObjectTypeQueue); + if (!q) return STATUS_NOT_FOUND; + + PROCESS* target = KeGetProcessById((uint32_t)a1); + if (!target) { + ObDereferenceObject(&q->Header); + return STATUS_NOT_FOUND; + } + + uint32_t newHandle = 0; + KSTATUS s = KeAllocateHandle(target, &q->Header, &newHandle); + ObDereferenceObject(&target->Header); + ObDereferenceObject(&q->Header); + if (!KSUCCESS(s)) return s; + + *(uint32_t*)(uintptr_t)a2 = newHandle; + return STATUS_SUCCESS; +} + +// --------------------------------------------------------------------------- +// SYS_NAMED_QUEUE_OWNER_PID (62) a0=*name a1=*pidOut +// +// Returns the ProcessId of whoever published the named queue. +// Lets a client get the publisher's PID so it can duplicate one of its +// own handles into that process via SYS_QUEUE_DUPLICATE. +// --------------------------------------------------------------------------- +static uint64_t SyscallNamedQueueOwnerPid(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a2; (void)a3; (void)a4; (void)a5; + const char* name = (const char*)(uintptr_t)a0; + uint32_t* pidOut = (uint32_t*)(uintptr_t)a1; + if (!name || !name[0] || !pidOut) return STATUS_INVALID_PARAMETER; + + uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock); + for (int i = 0; i < NAMED_QUEUE_MAX; i++) { + if (gNamedQueues[i].Queue && + strncmp(gNamedQueues[i].Name, name, NAMED_QUEUE_NAME_MAX) == 0) { + *pidOut = gNamedQueues[i].PublisherPid; + KeReleaseSpinlock(&gNamedQueueLock, flags); + return STATUS_SUCCESS; + } + } + KeReleaseSpinlock(&gNamedQueueLock, flags); + return STATUS_NOT_FOUND; +} + // =========================================================================== // Dispatch table - index must match SYS_* in syscall_nr.h exactly. // =========================================================================== @@ -938,61 +1148,69 @@ typedef uint64_t (*SYSCALL_HANDLER)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = { - /* 00 SYS_EXIT_PROCESS */ SyscallExitProcess, - /* 01 SYS_EXIT_THREAD */ SyscallExitThread, - /* 02 SYS_CREATE_THREAD */ SyscallCreateThread, - /* 03 SYS_GET_CURRENT_TID */ SyscallGetCurrentTid, - /* 04 SYS_GET_CURRENT_PID */ SyscallGetCurrentPid, - /* 05 SYS_YIELD */ SyscallYield, - /* 06 SYS_SLEEP */ SyscallSleep, - /* 07 SYS_SET_THREAD_PRIORITY */ SyscallSetThreadPriority, - /* 08 SYS_ALLOC */ SyscallAlloc, - /* 09 SYS_FREE */ SyscallFree, - /* 10 SYS_REALLOC */ SyscallRealloc, - /* 11 SYS_MUTEX_CREATE */ SyscallMutexCreate, - /* 12 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire, - /* 13 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire, - /* 14 SYS_MUTEX_RELEASE */ SyscallMutexRelease, - /* 15 SYS_SEM_CREATE */ SyscallSemCreate, - /* 16 SYS_SEM_WAIT */ SyscallSemWait, - /* 17 SYS_SEM_TRY_WAIT */ SyscallSemTryWait, - /* 18 SYS_SEM_SIGNAL */ SyscallSemSignal, - /* 19 SYS_EVENT_CREATE */ SyscallEventCreate, - /* 20 SYS_EVENT_SIGNAL */ SyscallEventSignal, - /* 21 SYS_EVENT_CLEAR */ SyscallEventClear, - /* 22 SYS_EVENT_WAIT */ SyscallEventWait, - /* 23 SYS_QUEUE_CREATE */ SyscallQueueCreate, - /* 24 SYS_QUEUE_SEND */ SyscallQueueSend, - /* 25 SYS_QUEUE_RECV */ SyscallQueueRecv, - /* 26 SYS_CLOSE_HANDLE */ SyscallCloseHandle, + /* 00 SYS_EXIT_PROCESS */ SyscallExitProcess, + /* 01 SYS_EXIT_THREAD */ SyscallExitThread, + /* 02 SYS_CREATE_THREAD */ SyscallCreateThread, + /* 03 SYS_GET_CURRENT_TID */ SyscallGetCurrentTid, + /* 04 SYS_GET_CURRENT_PID */ SyscallGetCurrentPid, + /* 05 SYS_YIELD */ SyscallYield, + /* 06 SYS_SLEEP */ SyscallSleep, + /* 07 SYS_SET_THREAD_PRIORITY */ SyscallSetThreadPriority, + /* 08 SYS_ALLOC */ SyscallAlloc, + /* 09 SYS_FREE */ SyscallFree, + /* 10 SYS_REALLOC */ SyscallRealloc, + /* 11 SYS_MUTEX_CREATE */ SyscallMutexCreate, + /* 12 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire, + /* 13 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire, + /* 14 SYS_MUTEX_RELEASE */ SyscallMutexRelease, + /* 15 SYS_SEM_CREATE */ SyscallSemCreate, + /* 16 SYS_SEM_WAIT */ SyscallSemWait, + /* 17 SYS_SEM_TRY_WAIT */ SyscallSemTryWait, + /* 18 SYS_SEM_SIGNAL */ SyscallSemSignal, + /* 19 SYS_EVENT_CREATE */ SyscallEventCreate, + /* 20 SYS_EVENT_SIGNAL */ SyscallEventSignal, + /* 21 SYS_EVENT_CLEAR */ SyscallEventClear, + /* 22 SYS_EVENT_WAIT */ SyscallEventWait, + /* 23 SYS_QUEUE_CREATE */ SyscallQueueCreate, + /* 24 SYS_QUEUE_SEND */ SyscallQueueSend, + /* 25 SYS_QUEUE_RECV */ SyscallQueueRecv, + /* 26 SYS_CLOSE_HANDLE */ SyscallCloseHandle, /* 27 SYS_OPEN_FILE */ SyscallOpenFile, /* 28 SYS_READ_FILE */ SyscallReadFile, /* 29 SYS_SEEK_FILE */ SyscallSeekFile, /* 30 SYS_GET_FILE_SIZE */ SyscallGetFileSize, - /* 31 SYS_SCREEN_BLIT */ SyscallScreenBlit, - /* 32 SYS_SCREEN_CLEAR */ SyscallScreenClear, - /* 33 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize, - /* 34 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar, - /* 35 SYS_KB_POLL */ SyscallKbPoll, - /* 36 SYS_KB_READ_CHAR */ SyscallKbReadChar, - /* 37 SYS_KB_READ_SCANCODE */ SyscallKbReadScancode, - /* 38 SYS_GET_TICK */ SyscallGetTick, - /* 39 SYS_DEBUG_PRINT */ SyscallDebugPrint, - /* 40 SYS_CREATE_PROCESS */ SyscallCreateProcess, - /* 41 SYS_WAIT_FOR_PROCESS */ SyscallWaitForProcess, - /* 42 SYS_GET_PROCESS_EXIT_CODE */ SyscallGetProcessExitCode, - /* 43 SYS_WRITE_FILE */ SyscallWriteFile, - /* 44 SYS_CREATE_FILE */ SyscallCreateFile, - /* 45 SYS_DELETE_FILE */ SyscallDeleteFile, - /* 46 SYS_TRUNCATE_FILE */ SyscallTruncateFile, - /* 47 SYS_GET_FILE_POS */ SyscallGetFilePos, - /* 48 SYS_WRITE_CONSOLE */ SyscallWriteConsole, - /* 49 SYS_OPEN_DIR */ SyscallOpenDir, - /* 50 SYS_READ_DIR */ SyscallReadDir, - /* 51 SYS_SET_CWD */ SyscallSetCwd, - /* 52 SYS_GET_CWD */ SyscallGetCwd, - /* 53 SYS_WAIT_THREAD */ SyscallWaitThread, - /* 54 SYS_GET_PROCESS_PID */ SyscallGetProcessPid, + /* 31 SYS_WRITE_FILE */ SyscallWriteFile, + /* 32 SYS_CREATE_FILE */ SyscallCreateFile, + /* 33 SYS_DELETE_FILE */ SyscallDeleteFile, + /* 34 SYS_TRUNCATE_FILE */ SyscallTruncateFile, + /* 35 SYS_GET_FILE_POS */ SyscallGetFilePos, + /* 36 SYS_SCREEN_BLIT */ SyscallScreenBlit, + /* 37 SYS_SCREEN_CLEAR */ SyscallScreenClear, + /* 38 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize, + /* 39 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar, + /* 40 SYS_KB_POLL */ SyscallKbPoll, + /* 41 SYS_KB_READ_CHAR */ SyscallKbReadChar, + /* 42 SYS_KB_READ_SCANCODE */ SyscallKbReadScancode, + /* 43 SYS_KB_GET_MODIFIERS */ SyscallKbGetModifiers, + /* 44 SYS_MOUSE_POLL */ SyscallMousePoll, + /* 45 SYS_MOUSE_READ */ SyscallMouseRead, + /* 46 SYS_MOUSE_GET_POS */ SyscallMouseGetPos, + /* 47 SYS_GET_TICK */ SyscallGetTick, + /* 48 SYS_DEBUG_PRINT */ SyscallDebugPrint, + /* 49 SYS_CREATE_PROCESS */ SyscallCreateProcess, + /* 50 SYS_WAIT_FOR_PROCESS */ SyscallWaitForProcess, + /* 51 SYS_GET_PROCESS_EXIT_CODE */ SyscallGetProcessExitCode, + /* 52 SYS_WRITE_CONSOLE */ SyscallWriteConsole, + /* 53 SYS_OPEN_DIR */ SyscallOpenDir, + /* 54 SYS_READ_DIR */ SyscallReadDir, + /* 55 SYS_SET_CWD */ SyscallSetCwd, + /* 56 SYS_GET_CWD */ SyscallGetCwd, + /* 57 SYS_WAIT_THREAD */ SyscallWaitThread, + /* 58 SYS_GET_PROCESS_PID */ SyscallGetProcessPid, + /* 59 SYS_PUBLISH_QUEUE */ SyscallPublishQueue, + /* 60 SYS_OPEN_NAMED_QUEUE */ SyscallOpenNamedQueue, + /* 61 SYS_QUEUE_DUPLICATE */ SyscallQueueDuplicate, + /* 62 SYS_NAMED_QUEUE_OWNER_PID */ SyscallNamedQueueOwnerPid, }; // --------------------------------------------------------------------------- diff --git a/code/kernel/syscall_nr.h b/code/kernel/syscall_nr.h index 0a7b78e..01da1f1 100644 --- a/code/kernel/syscall_nr.h +++ b/code/kernel/syscall_nr.h @@ -1,148 +1,171 @@ -#pragma once -// syscall_nr.h - system call numbers -// Shared between kernel (ke_syscall.c) and user mode (syscall.dll). -// Keep in sync with gSyscallTable in ke_syscall.c and SYS_MAX below. -// -// Calling convention (INT 0x40, MS x64): -// RAX = syscall number -// RCX, RDX, R8, R9 = args 0-3 -// R10, R11 = args 4-5 (loaded by SYSCALL_STUB6 in syscall_stubs.asm) -// Return value in RAX (KSTATUS or data). -// -// Handle semantics: -// Every kernel object (file, mutex, semaphore, event, queue) is reference- -// counted. SYS_CLOSE_HANDLE is the ONE way to close any handle regardless -// of the object type behind it. KeCloseHandle calls ObDereferenceObject, -// which fires the type-specific Destroy callback (e.g. FileDestroy) -// automatically when the refcount reaches zero. There is no separate -// SYS_CLOSE_FILE - that was redundant. - -// --------------------------------------------------------------------------- -// Process & Thread -// --------------------------------------------------------------------------- -#define SYS_EXIT_PROCESS 0 // (int exitCode) -> void -#define SYS_EXIT_THREAD 1 // (int exitCode) -> void -#define SYS_CREATE_THREAD 2 // (uint64_t entry, uint64_t arg, uint32_t priority, uint32_t* tidOut) -> KSTATUS -#define SYS_GET_CURRENT_TID 3 // () -> uint32_t -#define SYS_GET_CURRENT_PID 4 // () -> uint32_t -#define SYS_YIELD 5 // () -> void -#define SYS_SLEEP 6 // (uint32_t ms) -> void -#define SYS_SET_THREAD_PRIORITY 7 // (uint32_t priority) -> KSTATUS - -// --------------------------------------------------------------------------- -// Memory -// --------------------------------------------------------------------------- -#define SYS_ALLOC 8 // (size_t size) -> void* (NULL on failure) -#define SYS_FREE 9 // (void* ptr, size_t size) -> void -#define SYS_REALLOC 10 // (void* ptr, size_t newSize) -> void* - -// --------------------------------------------------------------------------- -// Synchronisation Objects -// --------------------------------------------------------------------------- -#define SYS_MUTEX_CREATE 11 // (uint32_t* handleOut) -> KSTATUS -#define SYS_MUTEX_ACQUIRE 12 // (uint32_t handle) -> KSTATUS -#define SYS_MUTEX_TRY_ACQUIRE 13 // (uint32_t handle) -> KSTATUS -#define SYS_MUTEX_RELEASE 14 // (uint32_t handle) -> KSTATUS - -#define SYS_SEM_CREATE 15 // (int32_t initial, int32_t max, uint32_t* handleOut) -> KSTATUS -#define SYS_SEM_WAIT 16 // (uint32_t handle) -> KSTATUS -#define SYS_SEM_TRY_WAIT 17 // (uint32_t handle) -> KSTATUS -#define SYS_SEM_SIGNAL 18 // (uint32_t handle) -> void - -#define SYS_EVENT_CREATE 19 // (uint32_t type, uint32_t initialState, uint32_t* handleOut) -> KSTATUS -#define SYS_EVENT_SIGNAL 20 // (uint32_t handle) -> void -#define SYS_EVENT_CLEAR 21 // (uint32_t handle) -> void -#define SYS_EVENT_WAIT 22 // (uint32_t handle) -> KSTATUS - -// --------------------------------------------------------------------------- -// Message Queues -// --------------------------------------------------------------------------- -#define SYS_QUEUE_CREATE 23 // (uint32_t* handleOut) -> KSTATUS -#define SYS_QUEUE_SEND 24 // (uint32_t handle, const QUEUE_MESSAGE* msg, uint32_t blocking) -> KSTATUS -#define SYS_QUEUE_RECV 25 // (uint32_t handle, QUEUE_MESSAGE* msg, uint32_t blocking) -> KSTATUS - -// --------------------------------------------------------------------------- -// Handle Management -// --------------------------------------------------------------------------- -#define SYS_CLOSE_HANDLE 26 // (uint32_t handle) -> void - -// --------------------------------------------------------------------------- -// File I/O -// (Close a file handle via SYS_CLOSE_HANDLE, same as any other object.) -// --------------------------------------------------------------------------- -#define SYS_OPEN_FILE 27 // (const char* path, uint32_t* handleOut) -> KSTATUS -#define SYS_READ_FILE 28 // (uint32_t handle, void* buf, size_t size, size_t* bytesReadOut) -> KSTATUS -#define SYS_SEEK_FILE 29 // (uint32_t handle, uint64_t offset) -> KSTATUS -#define SYS_GET_FILE_SIZE 30 // (uint32_t handle) -> uint64_t -#define SYS_WRITE_FILE 43 -#define SYS_CREATE_FILE 44 -#define SYS_DELETE_FILE 45 -#define SYS_TRUNCATE_FILE 46 -#define SYS_GET_FILE_POS 47 - -// --------------------------------------------------------------------------- -// Screen / Graphics -// --------------------------------------------------------------------------- -#define SYS_SCREEN_BLIT 31 // (int x, int y, int w, int h, const uint32_t* pixels) -> void -#define SYS_SCREEN_CLEAR 32 // (uint32_t color) -> void -#define SYS_SCREEN_GET_SIZE 33 // (int* widthOut, int* heightOut) -> void -#define SYS_SCREEN_PUT_CHAR 34 // (char c, int x, int y, uint32_t fg, uint32_t bg) -> void - -// --------------------------------------------------------------------------- -// Keyboard -// --------------------------------------------------------------------------- -#define SYS_KB_POLL 35 // () -> uint32_t (1 if key available, 0 otherwise) -#define SYS_KB_READ_CHAR 36 // () -> char (blocks, yields while waiting) -#define SYS_KB_READ_SCANCODE 37 // () -> uint8_t (blocks, yields while waiting) - -// --------------------------------------------------------------------------- -// Timer -// --------------------------------------------------------------------------- -#define SYS_GET_TICK 38 // () -> uint64_t (milliseconds since boot) - -// --------------------------------------------------------------------------- -// Debug -// --------------------------------------------------------------------------- -#define SYS_DEBUG_PRINT 39 // (const char* str) -> void - -// --------------------------------------------------------------------------- -// Process launch & lifecycle -// --------------------------------------------------------------------------- -#define SYS_CREATE_PROCESS 40 // (const char* path, uint32_t* handleOut) -> KSTATUS -#define SYS_WAIT_FOR_PROCESS 41 // (uint32_t handle) -> KSTATUS -#define SYS_GET_PROCESS_EXIT_CODE 42 // (uint32_t handle, int* exitCodeOut) -> KSTATUS - -// --------------------------------------------------------------------------- -// Console output (white text, distinct from green SYS_DEBUG_PRINT) -// --------------------------------------------------------------------------- -#define SYS_WRITE_CONSOLE 48 // (const char* buf, size_t len) -> void - -// --------------------------------------------------------------------------- -// Directory enumeration -// (Close the handle via SYS_CLOSE_HANDLE like any other object.) -// --------------------------------------------------------------------------- -#define SYS_OPEN_DIR 49 // (const char* dirPath, uint32_t* handleOut) -> KSTATUS -#define SYS_READ_DIR 50 // (uint32_t handle, KDIR_ENTRY* entryOut) -> KSTATUS - -// --------------------------------------------------------------------------- -// Current Working Directory -// --------------------------------------------------------------------------- -#define SYS_SET_CWD 51 // (const char* path) -> KSTATUS -#define SYS_GET_CWD 52 // (char* buf, size_t size) -> KSTATUS - -// --------------------------------------------------------------------------- -// Thread join -// --------------------------------------------------------------------------- -#define SYS_WAIT_THREAD 53 // (uint32_t tid) -> KSTATUS - // Blocks until the thread with that TID exits. - // Returns STATUS_NOT_FOUND if TID unknown. - -// --------------------------------------------------------------------------- -// Process PID query (needed by posix_spawn -> waitpid) -// --------------------------------------------------------------------------- -#define SYS_GET_PROCESS_PID 54 // (uint32_t procHandle, uint32_t* pidOut) -> KSTATUS - -// --------------------------------------------------------------------------- -// Sentinel -// --------------------------------------------------------------------------- -#define SYS_MAX 55 +#pragma once +// syscall_nr.h - system call numbers +// Shared between kernel (ke_syscall.c) and user mode (syscall.dll). +// Keep in sync with gSyscallTable in ke_syscall.c and SYS_MAX below. +// +// Calling convention (INT 0x40, MS x64): +// RAX = syscall number +// RCX, RDX, R8, R9 = args 0-3 +// R10, R11 = args 4-5 (loaded by SYSCALL_STUB6 in syscall_stubs.asm) +// Return value in RAX (KSTATUS or data). +// +// Handle semantics: +// Every kernel object (file, mutex, semaphore, event, queue) is reference- +// counted. SYS_CLOSE_HANDLE is the ONE way to close any handle regardless +// of the object type behind it. KeCloseHandle calls ObDereferenceObject, +// which fires the type-specific Destroy callback (e.g. FileDestroy) +// automatically when the refcount reaches zero. There is no separate +// SYS_CLOSE_FILE - that was redundant. + +// --------------------------------------------------------------------------- +// Process & Thread +// --------------------------------------------------------------------------- +#define SYS_EXIT_PROCESS 0 // (int exitCode) -> void +#define SYS_EXIT_THREAD 1 // (int exitCode) -> void +#define SYS_CREATE_THREAD 2 // (uint64_t entry, uint64_t arg, uint32_t priority, uint32_t* tidOut) -> KSTATUS +#define SYS_GET_CURRENT_TID 3 // () -> uint32_t +#define SYS_GET_CURRENT_PID 4 // () -> uint32_t +#define SYS_YIELD 5 // () -> void +#define SYS_SLEEP 6 // (uint32_t ms) -> void +#define SYS_SET_THREAD_PRIORITY 7 // (uint32_t priority) -> KSTATUS + +// --------------------------------------------------------------------------- +// Memory +// --------------------------------------------------------------------------- +#define SYS_ALLOC 8 // (size_t size) -> void* (NULL on failure) +#define SYS_FREE 9 // (void* ptr, size_t size) -> void +#define SYS_REALLOC 10 // (void* ptr, size_t newSize) -> void* + +// --------------------------------------------------------------------------- +// Synchronisation Objects +// --------------------------------------------------------------------------- +#define SYS_MUTEX_CREATE 11 // (uint32_t* handleOut) -> KSTATUS +#define SYS_MUTEX_ACQUIRE 12 // (uint32_t handle) -> KSTATUS +#define SYS_MUTEX_TRY_ACQUIRE 13 // (uint32_t handle) -> KSTATUS +#define SYS_MUTEX_RELEASE 14 // (uint32_t handle) -> KSTATUS + +#define SYS_SEM_CREATE 15 // (int32_t initial, int32_t max, uint32_t* handleOut) -> KSTATUS +#define SYS_SEM_WAIT 16 // (uint32_t handle) -> KSTATUS +#define SYS_SEM_TRY_WAIT 17 // (uint32_t handle) -> KSTATUS +#define SYS_SEM_SIGNAL 18 // (uint32_t handle) -> void + +#define SYS_EVENT_CREATE 19 // (uint32_t type, uint32_t initialState, uint32_t* handleOut) -> KSTATUS +#define SYS_EVENT_SIGNAL 20 // (uint32_t handle) -> void +#define SYS_EVENT_CLEAR 21 // (uint32_t handle) -> void +#define SYS_EVENT_WAIT 22 // (uint32_t handle) -> KSTATUS + +// --------------------------------------------------------------------------- +// Message Queues +// --------------------------------------------------------------------------- +#define SYS_QUEUE_CREATE 23 // (uint32_t* handleOut) -> KSTATUS +#define SYS_QUEUE_SEND 24 // (uint32_t handle, const QUEUE_MESSAGE* msg, uint32_t blocking) -> KSTATUS +#define SYS_QUEUE_RECV 25 // (uint32_t handle, QUEUE_MESSAGE* msg, uint32_t blocking) -> KSTATUS + +// --------------------------------------------------------------------------- +// Handle Management +// --------------------------------------------------------------------------- +#define SYS_CLOSE_HANDLE 26 // (uint32_t handle) -> void + +// --------------------------------------------------------------------------- +// File I/O +// (Close a file handle via SYS_CLOSE_HANDLE, same as any other object.) +// --------------------------------------------------------------------------- +#define SYS_OPEN_FILE 27 // (const char* path, uint32_t* handleOut) -> KSTATUS +#define SYS_READ_FILE 28 // (uint32_t handle, void* buf, size_t size, size_t* bytesReadOut) -> KSTATUS +#define SYS_SEEK_FILE 29 // (uint32_t handle, uint64_t offset) -> KSTATUS +#define SYS_GET_FILE_SIZE 30 // (uint32_t handle) -> uint64_t +#define SYS_WRITE_FILE 31 // (uint32_t handle, const void* buf, size_t size, size_t* bytesWrittenOut) -> KSTATUS +#define SYS_CREATE_FILE 32 // (const char* path, uint32_t* handleOut) -> KSTATUS +#define SYS_DELETE_FILE 33 // (const char* path) -> KSTATUS +#define SYS_TRUNCATE_FILE 34 // (uint32_t handle, uint64_t newSize) -> KSTATUS +#define SYS_GET_FILE_POS 35 // (uint32_t handle) -> uint64_t + +// --------------------------------------------------------------------------- +// Screen / Graphics +// --------------------------------------------------------------------------- +#define SYS_SCREEN_BLIT 36 // (int x, int y, int w, int h, const uint32_t* pixels) -> void +#define SYS_SCREEN_CLEAR 37 // (uint32_t color) -> void +#define SYS_SCREEN_GET_SIZE 38 // (int* widthOut, int* heightOut) -> void +#define SYS_SCREEN_PUT_CHAR 39 // (char c, int x, int y, uint32_t fg, uint32_t bg) -> void + +// --------------------------------------------------------------------------- +// Keyboard +// --------------------------------------------------------------------------- +#define SYS_KB_POLL 40 // () -> uint32_t (1 if key available, 0 otherwise) +#define SYS_KB_READ_CHAR 41 // () -> char (blocks, yields while waiting) +#define SYS_KB_READ_SCANCODE 42 // () -> uint8_t (blocks, yields while waiting) +#define SYS_KB_GET_MODIFIERS 43 // () -> uint32_t (current modifier bitmask) + +// --------------------------------------------------------------------------- +// Mouse +// --------------------------------------------------------------------------- +#define SYS_MOUSE_POLL 44 // () -> uint32_t (1 if packet waiting, 0 otherwise) +#define SYS_MOUSE_READ 45 // (int* dx, int* dy, uint8_t* buttons) -> uint32_t (1=ok, 0=empty) +#define SYS_MOUSE_GET_POS 46 // (int* x, int* y) -> void + +// --------------------------------------------------------------------------- +// Timer +// --------------------------------------------------------------------------- +#define SYS_GET_TICK 47 // () -> uint64_t (milliseconds since boot) + +// --------------------------------------------------------------------------- +// Debug +// --------------------------------------------------------------------------- +#define SYS_DEBUG_PRINT 48 // (const char* str) -> void + +// --------------------------------------------------------------------------- +// Process launch & lifecycle +// --------------------------------------------------------------------------- +#define SYS_CREATE_PROCESS 49 // (const char* path, uint32_t* handleOut, const char* cmdline) -> KSTATUS +#define SYS_WAIT_FOR_PROCESS 50 // (uint32_t handle) -> KSTATUS +#define SYS_GET_PROCESS_EXIT_CODE 51 // (uint32_t handle, int* exitCodeOut) -> KSTATUS + +// --------------------------------------------------------------------------- +// Console output (white text, distinct from green SYS_DEBUG_PRINT) +// --------------------------------------------------------------------------- +#define SYS_WRITE_CONSOLE 52 // (const char* buf, size_t len) -> void + +// --------------------------------------------------------------------------- +// Directory enumeration +// (Close the handle via SYS_CLOSE_HANDLE like any other object.) +// --------------------------------------------------------------------------- +#define SYS_OPEN_DIR 53 // (const char* dirPath, uint32_t* handleOut) -> KSTATUS +#define SYS_READ_DIR 54 // (uint32_t handle, KDIR_ENTRY* entryOut) -> KSTATUS + +// --------------------------------------------------------------------------- +// Current Working Directory +// --------------------------------------------------------------------------- +#define SYS_SET_CWD 55 // (const char* path) -> KSTATUS +#define SYS_GET_CWD 56 // (char* buf, size_t size) -> KSTATUS + +// --------------------------------------------------------------------------- +// Thread join +// --------------------------------------------------------------------------- +#define SYS_WAIT_THREAD 57 // (uint32_t tid) -> KSTATUS + // Blocks until the thread with that TID exits. + // Returns STATUS_NOT_FOUND if TID unknown. + +// --------------------------------------------------------------------------- +// Process PID query (needed by posix_spawn -> waitpid) +// --------------------------------------------------------------------------- +#define SYS_GET_PROCESS_PID 58 // (uint32_t procHandle, uint32_t* pidOut) -> KSTATUS + +// --------------------------------------------------------------------------- +// Named Queue Registry +// --------------------------------------------------------------------------- +#define SYS_PUBLISH_QUEUE 59 // (const char* name, uint32_t queueHandle) -> KSTATUS +#define SYS_OPEN_NAMED_QUEUE 60 // (const char* name, uint32_t* handleOut) -> KSTATUS + +// --------------------------------------------------------------------------- +// Handle Duplication +// --------------------------------------------------------------------------- +#define SYS_QUEUE_DUPLICATE 61 // (uint32_t handle, uint32_t targetPid, uint32_t* handleOut) -> KSTATUS + // Duplicates a queue handle into another process's handle table. + // Returns the new handle value (valid in targetPid's space) via *handleOut. +#define SYS_NAMED_QUEUE_OWNER_PID 62 // (const char* name, uint32_t* pidOut) -> KSTATUS + // Returns the ProcessId of whoever published the named queue. + +// --------------------------------------------------------------------------- +// Sentinel +// --------------------------------------------------------------------------- +#define SYS_MAX 63 diff --git a/code/syscall/syscall_nr.inc b/code/syscall/syscall_nr.inc index f163db5..a2df90e 100644 --- a/code/syscall/syscall_nr.inc +++ b/code/syscall/syscall_nr.inc @@ -1,96 +1,110 @@ -; syscall_nr.inc - assembled from syscall_nr.h for use in .asm files -; Keep in sync with syscall_nr.h and ke_syscall.c. - -; Process & Thread -SYS_EXIT_PROCESS EQU 0 -SYS_EXIT_THREAD EQU 1 -SYS_CREATE_THREAD EQU 2 -SYS_GET_CURRENT_TID EQU 3 -SYS_GET_CURRENT_PID EQU 4 -SYS_YIELD EQU 5 -SYS_SLEEP EQU 6 -SYS_SET_THREAD_PRIORITY EQU 7 - -; Memory -SYS_ALLOC EQU 8 -SYS_FREE EQU 9 -SYS_REALLOC EQU 10 - -; Mutex -SYS_MUTEX_CREATE EQU 11 -SYS_MUTEX_ACQUIRE EQU 12 -SYS_MUTEX_TRY_ACQUIRE EQU 13 -SYS_MUTEX_RELEASE EQU 14 - -; Semaphore -SYS_SEM_CREATE EQU 15 -SYS_SEM_WAIT EQU 16 -SYS_SEM_TRY_WAIT EQU 17 -SYS_SEM_SIGNAL EQU 18 - -; Event -SYS_EVENT_CREATE EQU 19 -SYS_EVENT_SIGNAL EQU 20 -SYS_EVENT_CLEAR EQU 21 -SYS_EVENT_WAIT EQU 22 - -; Queue -SYS_QUEUE_CREATE EQU 23 -SYS_QUEUE_SEND EQU 24 -SYS_QUEUE_RECV EQU 25 - -; Handle (unified - one close for every object type) -SYS_CLOSE_HANDLE EQU 26 - -; File I/O -SYS_OPEN_FILE EQU 27 -SYS_READ_FILE EQU 28 -SYS_SEEK_FILE EQU 29 -SYS_GET_FILE_SIZE EQU 30 -SYS_WRITE_FILE EQU 43 ; a0=handle a1=buf a2=size a3=*bytesWritten -SYS_CREATE_FILE EQU 44 ; a0=*path a1=*handleOut -SYS_DELETE_FILE EQU 45 ; a0=*path -SYS_TRUNCATE_FILE EQU 46 ; a0=handle a1=newSize -SYS_GET_FILE_POS EQU 47 ; a0=handle -> current offset - -; Screen -SYS_SCREEN_BLIT EQU 31 -SYS_SCREEN_CLEAR EQU 32 -SYS_SCREEN_GET_SIZE EQU 33 -SYS_SCREEN_PUT_CHAR EQU 34 - -; Keyboard -SYS_KB_POLL EQU 35 -SYS_KB_READ_CHAR EQU 36 -SYS_KB_READ_SCANCODE EQU 37 - -; Timer -SYS_GET_TICK EQU 38 - -; Debug -SYS_DEBUG_PRINT EQU 39 - -; Process launch & lifecycle -SYS_CREATE_PROCESS EQU 40 -SYS_WAIT_FOR_PROCESS EQU 41 -SYS_GET_PROCESS_EXIT_CODE EQU 42 - -; Console output -SYS_WRITE_CONSOLE EQU 48 - -; Directory enumeration -SYS_OPEN_DIR EQU 49 -SYS_READ_DIR EQU 50 - -; Current Working Directory -SYS_SET_CWD EQU 51 -SYS_GET_CWD EQU 52 - -; Thread join -SYS_WAIT_THREAD EQU 53 ; a0=tid -> KSTATUS - -; Process PID query -SYS_GET_PROCESS_PID EQU 54 ; a0=procHandle a1=*pidOut -> KSTATUS - -; Sentinel -SYS_MAX EQU 55 +; syscall_nr.inc - assembled from syscall_nr.h for use in .asm files +; Keep in sync with syscall_nr.h and ke_syscall.c. + +; Process & Thread +SYS_EXIT_PROCESS EQU 0 +SYS_EXIT_THREAD EQU 1 +SYS_CREATE_THREAD EQU 2 +SYS_GET_CURRENT_TID EQU 3 +SYS_GET_CURRENT_PID EQU 4 +SYS_YIELD EQU 5 +SYS_SLEEP EQU 6 +SYS_SET_THREAD_PRIORITY EQU 7 + +; Memory +SYS_ALLOC EQU 8 +SYS_FREE EQU 9 +SYS_REALLOC EQU 10 + +; Mutex +SYS_MUTEX_CREATE EQU 11 +SYS_MUTEX_ACQUIRE EQU 12 +SYS_MUTEX_TRY_ACQUIRE EQU 13 +SYS_MUTEX_RELEASE EQU 14 + +; Semaphore +SYS_SEM_CREATE EQU 15 +SYS_SEM_WAIT EQU 16 +SYS_SEM_TRY_WAIT EQU 17 +SYS_SEM_SIGNAL EQU 18 + +; Event +SYS_EVENT_CREATE EQU 19 +SYS_EVENT_SIGNAL EQU 20 +SYS_EVENT_CLEAR EQU 21 +SYS_EVENT_WAIT EQU 22 + +; Queue +SYS_QUEUE_CREATE EQU 23 +SYS_QUEUE_SEND EQU 24 +SYS_QUEUE_RECV EQU 25 + +; Handle (unified - one close for every object type) +SYS_CLOSE_HANDLE EQU 26 + +; File I/O +SYS_OPEN_FILE EQU 27 +SYS_READ_FILE EQU 28 +SYS_SEEK_FILE EQU 29 +SYS_GET_FILE_SIZE EQU 30 +SYS_WRITE_FILE EQU 31 ; handle, buf, size, *bytesWritten +SYS_CREATE_FILE EQU 32 ; *path, *handleOut +SYS_DELETE_FILE EQU 33 ; *path +SYS_TRUNCATE_FILE EQU 34 ; handle, newSize +SYS_GET_FILE_POS EQU 35 ; handle -> current offset + +; Screen +SYS_SCREEN_BLIT EQU 36 +SYS_SCREEN_CLEAR EQU 37 +SYS_SCREEN_GET_SIZE EQU 38 +SYS_SCREEN_PUT_CHAR EQU 39 + +; Keyboard +SYS_KB_POLL EQU 40 +SYS_KB_READ_CHAR EQU 41 +SYS_KB_READ_SCANCODE EQU 42 +SYS_KB_GET_MODIFIERS EQU 43 + +; Mouse +SYS_MOUSE_POLL EQU 44 +SYS_MOUSE_READ EQU 45 +SYS_MOUSE_GET_POS EQU 46 + +; Timer +SYS_GET_TICK EQU 47 + +; Debug +SYS_DEBUG_PRINT EQU 48 + +; Process launch & lifecycle +SYS_CREATE_PROCESS EQU 49 +SYS_WAIT_FOR_PROCESS EQU 50 +SYS_GET_PROCESS_EXIT_CODE EQU 51 + +; Console output +SYS_WRITE_CONSOLE EQU 52 + +; Directory enumeration +SYS_OPEN_DIR EQU 53 +SYS_READ_DIR EQU 54 + +; Current Working Directory +SYS_SET_CWD EQU 55 +SYS_GET_CWD EQU 56 + +; Thread join +SYS_WAIT_THREAD EQU 57 ; a0=tid -> KSTATUS + +; Process PID query +SYS_GET_PROCESS_PID EQU 58 ; a0=procHandle a1=*pidOut -> KSTATUS + +; Named Queue Registry +SYS_PUBLISH_QUEUE EQU 59 ; a0=*name a1=queueHandle -> KSTATUS +SYS_OPEN_NAMED_QUEUE EQU 60 ; a0=*name a1=*handleOut -> KSTATUS + +; Handle duplication +SYS_QUEUE_DUPLICATE EQU 61 ; a0=handle a1=targetPid a2=*handleOut -> KSTATUS +SYS_NAMED_QUEUE_OWNER_PID EQU 62 ; a0=*name a1=*pidOut -> KSTATUS + +; Sentinel +SYS_MAX EQU 63 diff --git a/code/syscall/syscall_stubs.asm b/code/syscall/syscall_stubs.asm index 0092531..5c508d0 100644 --- a/code/syscall/syscall_stubs.asm +++ b/code/syscall/syscall_stubs.asm @@ -1,179 +1,201 @@ -; syscall_stubs.asm - user-mode INT 0x40 stubs exported by syscall.dll (MASM64) -; -; Calling convention (kernel side): -; RAX = syscall number -; RCX = arg 0 -; RDX = arg 1 -; R8 = arg 2 -; R9 = arg 3 -; R10 = arg 4 (our extension - loaded from the stack by SYSCALL_STUB6) -; R11 = arg 5 (our extension - loaded from the stack by SYSCALL_STUB6) -; -; User-mode callers follow standard MS x64: args 1-4 in RCX/RDX/R8/R9, -; args 5+ on the stack above the home area ([rsp+28h], [rsp+30h], ...). -; -; SYSCALL_STUB2 - 4 or fewer args: pure register passing, no stack read. -; SYSCALL_STUB6 - 5 or 6 args: loads [rsp+28h] -> R10 and [rsp+30h] -> R11. -; -; Handle lifecycle: -; SysCloseHandle is the single close stub for every object type. -; There is no SysCloseFile - files are closed through the unified path, -; exactly like mutexes, semaphores, events, and queues. - -INCLUDE syscall_nr.inc - -.CODE - -; --------------------------------------------------------------------------- -SYSCALL_STUB2 MACRO name, nr -PUBLIC Sys&name -Sys&name PROC EXPORT - mov rax, nr - int 40h - ret -Sys&name ENDP -ENDM - -; --------------------------------------------------------------------------- -SYSCALL_STUB6 MACRO name, nr -PUBLIC Sys&name -Sys&name PROC EXPORT - mov r10, [rsp+28h] ; 5th argument - mov r11, [rsp+30h] ; 6th argument - mov rax, nr - int 40h - ret -Sys&name ENDP -ENDM - -; --------------------------------------------------------------------------- -; Process & Thread -; --------------------------------------------------------------------------- -SYSCALL_STUB2 ExitProcess, SYS_EXIT_PROCESS -SYSCALL_STUB2 ExitThread, SYS_EXIT_THREAD -SYSCALL_STUB2 CreateThread, SYS_CREATE_THREAD -SYSCALL_STUB2 GetCurrentTid, SYS_GET_CURRENT_TID -SYSCALL_STUB2 GetCurrentPid, SYS_GET_CURRENT_PID -SYSCALL_STUB2 Yield, SYS_YIELD -SYSCALL_STUB2 Sleep, SYS_SLEEP -SYSCALL_STUB2 SetThreadPriority, SYS_SET_THREAD_PRIORITY - -; --------------------------------------------------------------------------- -; Memory -; --------------------------------------------------------------------------- -SYSCALL_STUB2 Alloc, SYS_ALLOC -SYSCALL_STUB2 Free, SYS_FREE -SYSCALL_STUB2 Realloc, SYS_REALLOC - -; --------------------------------------------------------------------------- -; Mutex -; --------------------------------------------------------------------------- -SYSCALL_STUB2 MutexCreate, SYS_MUTEX_CREATE -SYSCALL_STUB2 MutexAcquire, SYS_MUTEX_ACQUIRE -SYSCALL_STUB2 MutexTryAcquire, SYS_MUTEX_TRY_ACQUIRE -SYSCALL_STUB2 MutexRelease, SYS_MUTEX_RELEASE - -; --------------------------------------------------------------------------- -; Semaphore -; --------------------------------------------------------------------------- -SYSCALL_STUB2 SemCreate, SYS_SEM_CREATE -SYSCALL_STUB2 SemWait, SYS_SEM_WAIT -SYSCALL_STUB2 SemTryWait, SYS_SEM_TRY_WAIT -SYSCALL_STUB2 SemSignal, SYS_SEM_SIGNAL - -; --------------------------------------------------------------------------- -; Event -; --------------------------------------------------------------------------- -SYSCALL_STUB2 EventCreate, SYS_EVENT_CREATE -SYSCALL_STUB2 EventSignal, SYS_EVENT_SIGNAL -SYSCALL_STUB2 EventClear, SYS_EVENT_CLEAR -SYSCALL_STUB2 EventWait, SYS_EVENT_WAIT - -; --------------------------------------------------------------------------- -; Queue -; --------------------------------------------------------------------------- -SYSCALL_STUB2 QueueCreate, SYS_QUEUE_CREATE -SYSCALL_STUB2 QueueSend, SYS_QUEUE_SEND -SYSCALL_STUB2 QueueRecv, SYS_QUEUE_RECV - -; --------------------------------------------------------------------------- -; Handle (unified - use for files, mutexes, semaphores, events, queues) -; --------------------------------------------------------------------------- -SYSCALL_STUB2 CloseHandle, SYS_CLOSE_HANDLE - -; --------------------------------------------------------------------------- -; File I/O -; (To close: SysCloseHandle(handle) - no dedicated SysCloseFile) -; --------------------------------------------------------------------------- -SYSCALL_STUB2 OpenFile, SYS_OPEN_FILE -SYSCALL_STUB2 ReadFile, SYS_READ_FILE -SYSCALL_STUB2 SeekFile, SYS_SEEK_FILE -SYSCALL_STUB2 GetFileSize, SYS_GET_FILE_SIZE -SYSCALL_STUB2 WriteFile, SYS_WRITE_FILE ; handle, buf, size, *bytesWritten -SYSCALL_STUB2 CreateFile, SYS_CREATE_FILE ; *path, *handleOut -SYSCALL_STUB2 DeleteFile, SYS_DELETE_FILE ; *path -SYSCALL_STUB2 TruncateFile, SYS_TRUNCATE_FILE ; handle, newSize -SYSCALL_STUB2 GetFilePos, SYS_GET_FILE_POS ; handle -> offset - -; --------------------------------------------------------------------------- -; Screen -; SysScreenBlit has 5 args (x, y, w, h, pixels) - needs SYSCALL_STUB6. -; SysScreenPutChar has 5 args (c, x, y, fg, bg) - needs SYSCALL_STUB6. -; --------------------------------------------------------------------------- -SYSCALL_STUB6 ScreenBlit, SYS_SCREEN_BLIT -SYSCALL_STUB2 ScreenClear, SYS_SCREEN_CLEAR -SYSCALL_STUB2 ScreenGetSize, SYS_SCREEN_GET_SIZE -SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR - -; --------------------------------------------------------------------------- -; Keyboard -; --------------------------------------------------------------------------- -SYSCALL_STUB2 KbPoll, SYS_KB_POLL -SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR -SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE - -; --------------------------------------------------------------------------- -; Timer -; --------------------------------------------------------------------------- -SYSCALL_STUB2 GetTick, SYS_GET_TICK - -; --------------------------------------------------------------------------- -; Debug -; --------------------------------------------------------------------------- -SYSCALL_STUB2 DebugPrint, SYS_DEBUG_PRINT - -; --------------------------------------------------------------------------- -; Process launch & lifecycle -; --------------------------------------------------------------------------- -SYSCALL_STUB2 CreateProcess, SYS_CREATE_PROCESS -SYSCALL_STUB2 WaitForProcess, SYS_WAIT_FOR_PROCESS -SYSCALL_STUB2 GetProcessExitCode, SYS_GET_PROCESS_EXIT_CODE - -; --------------------------------------------------------------------------- -; Console output (white text, for user programs) -; --------------------------------------------------------------------------- -SYSCALL_STUB2 WriteConsole, SYS_WRITE_CONSOLE - -; --------------------------------------------------------------------------- -; Directory enumeration -; --------------------------------------------------------------------------- -SYSCALL_STUB2 OpenDir, SYS_OPEN_DIR -SYSCALL_STUB2 ReadDir, SYS_READ_DIR - -; --------------------------------------------------------------------------- -; Current Working Directory -; --------------------------------------------------------------------------- -SYSCALL_STUB2 SetCwd, SYS_SET_CWD -SYSCALL_STUB2 GetCwd, SYS_GET_CWD - -; --------------------------------------------------------------------------- -; Thread join (used by pthread_join in posix.dll) -; --------------------------------------------------------------------------- -SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD ; a0=tid -> KSTATUS - -; --------------------------------------------------------------------------- -; Process PID query (used by posix_spawn -> waitpid in posix.dll) -; --------------------------------------------------------------------------- -SYSCALL_STUB2 GetProcessPid, SYS_GET_PROCESS_PID ; a0=procHandle a1=*pidOut -> KSTATUS - -END +; syscall_stubs.asm - user-mode INT 0x40 stubs exported by syscall.dll (MASM64) +; +; Calling convention (kernel side): +; RAX = syscall number +; RCX = arg 0 +; RDX = arg 1 +; R8 = arg 2 +; R9 = arg 3 +; R10 = arg 4 (our extension - loaded from the stack by SYSCALL_STUB6) +; R11 = arg 5 (our extension - loaded from the stack by SYSCALL_STUB6) +; +; User-mode callers follow standard MS x64: args 1-4 in RCX/RDX/R8/R9, +; args 5+ on the stack above the home area ([rsp+28h], [rsp+30h], ...). +; +; SYSCALL_STUB2 - 4 or fewer args: pure register passing, no stack read. +; SYSCALL_STUB6 - 5 or 6 args: loads [rsp+28h] -> R10 and [rsp+30h] -> R11. +; +; Handle lifecycle: +; SysCloseHandle is the single close stub for every object type. +; There is no SysCloseFile - files are closed through the unified path, +; exactly like mutexes, semaphores, events, and queues. + +INCLUDE syscall_nr.inc + +.CODE + +; --------------------------------------------------------------------------- +SYSCALL_STUB2 MACRO name, nr +PUBLIC Sys&name +Sys&name PROC EXPORT + mov rax, nr + int 40h + ret +Sys&name ENDP +ENDM + +; --------------------------------------------------------------------------- +SYSCALL_STUB6 MACRO name, nr +PUBLIC Sys&name +Sys&name PROC EXPORT + mov r10, [rsp+28h] ; 5th argument + mov r11, [rsp+30h] ; 6th argument + mov rax, nr + int 40h + ret +Sys&name ENDP +ENDM + +; --------------------------------------------------------------------------- +; Process & Thread +; --------------------------------------------------------------------------- +SYSCALL_STUB2 ExitProcess, SYS_EXIT_PROCESS +SYSCALL_STUB2 ExitThread, SYS_EXIT_THREAD +SYSCALL_STUB2 CreateThread, SYS_CREATE_THREAD +SYSCALL_STUB2 GetCurrentTid, SYS_GET_CURRENT_TID +SYSCALL_STUB2 GetCurrentPid, SYS_GET_CURRENT_PID +SYSCALL_STUB2 Yield, SYS_YIELD +SYSCALL_STUB2 Sleep, SYS_SLEEP +SYSCALL_STUB2 SetThreadPriority, SYS_SET_THREAD_PRIORITY + +; --------------------------------------------------------------------------- +; Memory +; --------------------------------------------------------------------------- +SYSCALL_STUB2 Alloc, SYS_ALLOC +SYSCALL_STUB2 Free, SYS_FREE +SYSCALL_STUB2 Realloc, SYS_REALLOC + +; --------------------------------------------------------------------------- +; Mutex +; --------------------------------------------------------------------------- +SYSCALL_STUB2 MutexCreate, SYS_MUTEX_CREATE +SYSCALL_STUB2 MutexAcquire, SYS_MUTEX_ACQUIRE +SYSCALL_STUB2 MutexTryAcquire, SYS_MUTEX_TRY_ACQUIRE +SYSCALL_STUB2 MutexRelease, SYS_MUTEX_RELEASE + +; --------------------------------------------------------------------------- +; Semaphore +; --------------------------------------------------------------------------- +SYSCALL_STUB2 SemCreate, SYS_SEM_CREATE +SYSCALL_STUB2 SemWait, SYS_SEM_WAIT +SYSCALL_STUB2 SemTryWait, SYS_SEM_TRY_WAIT +SYSCALL_STUB2 SemSignal, SYS_SEM_SIGNAL + +; --------------------------------------------------------------------------- +; Event +; --------------------------------------------------------------------------- +SYSCALL_STUB2 EventCreate, SYS_EVENT_CREATE +SYSCALL_STUB2 EventSignal, SYS_EVENT_SIGNAL +SYSCALL_STUB2 EventClear, SYS_EVENT_CLEAR +SYSCALL_STUB2 EventWait, SYS_EVENT_WAIT + +; --------------------------------------------------------------------------- +; Queue +; --------------------------------------------------------------------------- +SYSCALL_STUB2 QueueCreate, SYS_QUEUE_CREATE +SYSCALL_STUB2 QueueSend, SYS_QUEUE_SEND +SYSCALL_STUB2 QueueRecv, SYS_QUEUE_RECV + +; --------------------------------------------------------------------------- +; Handle (unified - use for files, mutexes, semaphores, events, queues) +; --------------------------------------------------------------------------- +SYSCALL_STUB2 CloseHandle, SYS_CLOSE_HANDLE + +; --------------------------------------------------------------------------- +; File I/O +; (To close: SysCloseHandle(handle) - no dedicated SysCloseFile) +; --------------------------------------------------------------------------- +SYSCALL_STUB2 OpenFile, SYS_OPEN_FILE +SYSCALL_STUB2 ReadFile, SYS_READ_FILE +SYSCALL_STUB2 SeekFile, SYS_SEEK_FILE +SYSCALL_STUB2 GetFileSize, SYS_GET_FILE_SIZE +SYSCALL_STUB2 WriteFile, SYS_WRITE_FILE +SYSCALL_STUB2 CreateFile, SYS_CREATE_FILE +SYSCALL_STUB2 DeleteFile, SYS_DELETE_FILE +SYSCALL_STUB2 TruncateFile, SYS_TRUNCATE_FILE +SYSCALL_STUB2 GetFilePos, SYS_GET_FILE_POS + +; --------------------------------------------------------------------------- +; Screen +; SysScreenBlit has 5 args (x, y, w, h, pixels) - needs SYSCALL_STUB6. +; SysScreenPutChar has 5 args (c, x, y, fg, bg) - needs SYSCALL_STUB6. +; --------------------------------------------------------------------------- +SYSCALL_STUB6 ScreenBlit, SYS_SCREEN_BLIT +SYSCALL_STUB2 ScreenClear, SYS_SCREEN_CLEAR +SYSCALL_STUB2 ScreenGetSize, SYS_SCREEN_GET_SIZE +SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR + +; --------------------------------------------------------------------------- +; Keyboard +; --------------------------------------------------------------------------- +SYSCALL_STUB2 KbPoll, SYS_KB_POLL +SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR +SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE +SYSCALL_STUB2 KbGetModifiers, SYS_KB_GET_MODIFIERS + +; --------------------------------------------------------------------------- +; Mouse +; --------------------------------------------------------------------------- +SYSCALL_STUB2 MousePoll, SYS_MOUSE_POLL +SYSCALL_STUB2 MouseRead, SYS_MOUSE_READ +SYSCALL_STUB2 MouseGetPos, SYS_MOUSE_GET_POS + +; --------------------------------------------------------------------------- +; Timer +; --------------------------------------------------------------------------- +SYSCALL_STUB2 GetTick, SYS_GET_TICK + +; --------------------------------------------------------------------------- +; Debug +; --------------------------------------------------------------------------- +SYSCALL_STUB2 DebugPrint, SYS_DEBUG_PRINT + +; --------------------------------------------------------------------------- +; Process launch & lifecycle +; --------------------------------------------------------------------------- +SYSCALL_STUB2 CreateProcess, SYS_CREATE_PROCESS +SYSCALL_STUB2 WaitForProcess, SYS_WAIT_FOR_PROCESS +SYSCALL_STUB2 GetProcessExitCode, SYS_GET_PROCESS_EXIT_CODE + +; --------------------------------------------------------------------------- +; Console output (white text, for user programs) +; --------------------------------------------------------------------------- +SYSCALL_STUB2 WriteConsole, SYS_WRITE_CONSOLE + +; --------------------------------------------------------------------------- +; Directory enumeration +; --------------------------------------------------------------------------- +SYSCALL_STUB2 OpenDir, SYS_OPEN_DIR +SYSCALL_STUB2 ReadDir, SYS_READ_DIR + +; --------------------------------------------------------------------------- +; Current Working Directory +; --------------------------------------------------------------------------- +SYSCALL_STUB2 SetCwd, SYS_SET_CWD +SYSCALL_STUB2 GetCwd, SYS_GET_CWD + +; --------------------------------------------------------------------------- +; Thread join (used by pthread_join in posix.dll) +; --------------------------------------------------------------------------- +SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD + +; --------------------------------------------------------------------------- +; Process PID query (used by posix_spawn -> waitpid in posix.dll) +; --------------------------------------------------------------------------- +SYSCALL_STUB2 GetProcessPid, SYS_GET_PROCESS_PID + +; --------------------------------------------------------------------------- +; Named Queue Registry +; SysPublishQueue - register a queue under a name (call once at startup) +; SysOpenNamedQueue - resolve a name to a handle (retry until SUCCESS) +; --------------------------------------------------------------------------- +SYSCALL_STUB2 PublishQueue, SYS_PUBLISH_QUEUE +SYSCALL_STUB2 OpenNamedQueue, SYS_OPEN_NAMED_QUEUE + +; --------------------------------------------------------------------------- +; Handle duplication +; --------------------------------------------------------------------------- +SYSCALL_STUB2 QueueDuplicate, SYS_QUEUE_DUPLICATE +SYSCALL_STUB2 NamedQueueOwnerPid, SYS_NAMED_QUEUE_OWNER_PID + +END diff --git a/readme.md b/readme.md index 1311892..e44a3c8 100644 --- a/readme.md +++ b/readme.md @@ -76,7 +76,7 @@ currently shipping: AHCI (interrupts), IDE (PIO/DMA) and FAT32. 6. loads runtime drivers from disk 7. launches `shell.exe` -## paths +## paths (because they're different) ``` "apps\shell.exe" -> current working directory @@ -84,7 +84,8 @@ currently shipping: AHCI (interrupts), IDE (PIO/DMA) and FAT32. "2:\data\config.ini" -> drive 2 ``` -Drives 0-7. A drive only works if a filesystem registered on it. +Drives 0-7. A drive only works if a filesystem registered on it. +The Win32 personality translates drive letters to drive numbers, the POSIX personality maps drives onto a tree. ## screenshots @@ -105,7 +106,7 @@ Q: Is the scheduler preemptive? A: As much as it will ever be. Q: Will it corrupt my data? -A: I hope not. +A: It shouldn't. Q: Is this finished? A: Not in the slightest. diff --git a/video.bk2 b/video.bk2 new file mode 100644 index 0000000..df733d2 Binary files /dev/null and b/video.bk2 differ