a few new syscalls, init process
This commit is contained in:
1 parent
320a24e1a5
commit
cdf7ed4cea
12 files changed
+436
-86
No files matched your search
@@ -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...
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
[kernel]
|
||||
debug = 1
|
||||
[init]
|
||||
commandline = shell.exe
|
||||
commandline = init.exe
|
||||
@@ -0,0 +1,40 @@
|
||||
// init.c - first user-mode process
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
+243
-25
@@ -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.
|
||||
// ===========================================================================
|
||||
@@ -969,30 +1179,38 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
|
||||
/* 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,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
+48
-25
@@ -74,75 +74,98 @@
|
||||
#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
|
||||
#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 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
|
||||
#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 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)
|
||||
#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 38 // () -> uint64_t (milliseconds since boot)
|
||||
#define SYS_GET_TICK 47 // () -> uint64_t (milliseconds since boot)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Debug
|
||||
// ---------------------------------------------------------------------------
|
||||
#define SYS_DEBUG_PRINT 39 // (const char* str) -> void
|
||||
#define SYS_DEBUG_PRINT 48 // (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
|
||||
#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 48 // (const char* buf, size_t len) -> void
|
||||
#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 49 // (const char* dirPath, uint32_t* handleOut) -> KSTATUS
|
||||
#define SYS_READ_DIR 50 // (uint32_t handle, KDIR_ENTRY* entryOut) -> KSTATUS
|
||||
#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 51 // (const char* path) -> KSTATUS
|
||||
#define SYS_GET_CWD 52 // (char* buf, size_t size) -> KSTATUS
|
||||
#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 53 // (uint32_t tid) -> KSTATUS
|
||||
#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 54 // (uint32_t procHandle, uint32_t* pidOut) -> KSTATUS
|
||||
#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 55
|
||||
#define SYS_MAX 63
|
||||
+39
-25
@@ -47,50 +47,64 @@ 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
|
||||
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 31
|
||||
SYS_SCREEN_CLEAR EQU 32
|
||||
SYS_SCREEN_GET_SIZE EQU 33
|
||||
SYS_SCREEN_PUT_CHAR EQU 34
|
||||
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 35
|
||||
SYS_KB_READ_CHAR EQU 36
|
||||
SYS_KB_READ_SCANCODE EQU 37
|
||||
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 38
|
||||
SYS_GET_TICK EQU 47
|
||||
|
||||
; Debug
|
||||
SYS_DEBUG_PRINT EQU 39
|
||||
SYS_DEBUG_PRINT EQU 48
|
||||
|
||||
; Process launch & lifecycle
|
||||
SYS_CREATE_PROCESS EQU 40
|
||||
SYS_WAIT_FOR_PROCESS EQU 41
|
||||
SYS_GET_PROCESS_EXIT_CODE EQU 42
|
||||
SYS_CREATE_PROCESS EQU 49
|
||||
SYS_WAIT_FOR_PROCESS EQU 50
|
||||
SYS_GET_PROCESS_EXIT_CODE EQU 51
|
||||
|
||||
; Console output
|
||||
SYS_WRITE_CONSOLE EQU 48
|
||||
SYS_WRITE_CONSOLE EQU 52
|
||||
|
||||
; Directory enumeration
|
||||
SYS_OPEN_DIR EQU 49
|
||||
SYS_READ_DIR EQU 50
|
||||
SYS_OPEN_DIR EQU 53
|
||||
SYS_READ_DIR EQU 54
|
||||
|
||||
; Current Working Directory
|
||||
SYS_SET_CWD EQU 51
|
||||
SYS_GET_CWD EQU 52
|
||||
SYS_SET_CWD EQU 55
|
||||
SYS_GET_CWD EQU 56
|
||||
|
||||
; Thread join
|
||||
SYS_WAIT_THREAD EQU 53 ; a0=tid -> KSTATUS
|
||||
SYS_WAIT_THREAD EQU 57 ; a0=tid -> KSTATUS
|
||||
|
||||
; Process PID query
|
||||
SYS_GET_PROCESS_PID EQU 54 ; a0=procHandle a1=*pidOut -> KSTATUS
|
||||
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 55
|
||||
SYS_MAX EQU 63
|
||||
@@ -109,11 +109,11 @@ 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
|
||||
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
|
||||
@@ -131,6 +131,14 @@ SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR
|
||||
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
|
||||
@@ -169,11 +177,25 @@ SYSCALL_STUB2 GetCwd, SYS_GET_CWD
|
||||
; ---------------------------------------------------------------------------
|
||||
; Thread join (used by pthread_join in posix.dll)
|
||||
; ---------------------------------------------------------------------------
|
||||
SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD ; a0=tid -> KSTATUS
|
||||
SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Process PID query (used by posix_spawn -> waitpid in posix.dll)
|
||||
; ---------------------------------------------------------------------------
|
||||
SYSCALL_STUB2 GetProcessPid, SYS_GET_PROCESS_PID ; a0=procHandle a1=*pidOut -> KSTATUS
|
||||
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
|
||||
@@ -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
|
||||
@@ -85,6 +85,7 @@ currently shipping: AHCI (interrupts), IDE (PIO/DMA) and FAT32.
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Reference in new issue
Block a user