implement proper IRQL, DPCs, kernel and user APCs, alertable waits, async file I/O with cancellation, trap frames, selftests, a real driver/device model, native async FAT32, VFAT dotfile fixes, syscall ABI cleanup, async_apc and async_cancel tests, POSIX multi-volume paths, and pimp the readme.

This commit is contained in:
maksw committed 2026-05-19 20:56:15 +02:00
1 parent f5fd7bdd75
commit 529f816166
75 files changed
+9969 -5675

No files matched your search

+124 -139
View File
@@ -22,6 +22,16 @@
INCLUDE syscall_nr.inc
SYS_USER_APC_FRAME_Magic EQU 0
SYS_USER_APC_FRAME_OriginalRip EQU 8
SYS_USER_APC_FRAME_OriginalRsp EQU 16
SYS_USER_APC_FRAME_OriginalRflags EQU 24
SYS_USER_APC_FRAME_OriginalRax EQU 32
SYS_USER_APC_FRAME_Routine EQU 40
SYS_USER_APC_FRAME_NormalContext EQU 48
SYS_USER_APC_FRAME_SystemArgument1 EQU 56
SYS_USER_APC_FRAME_SystemArgument2 EQU 64
.CODE
; ---------------------------------------------------------------------------
@@ -47,169 +57,144 @@ Sys&name ENDP
ENDM
; ---------------------------------------------------------------------------
; Process & Thread
; Process & thread lifecycle
; ---------------------------------------------------------------------------
SYSCALL_STUB2 ExitProcess, SYS_EXIT_PROCESS ; (int exitCode) -> void
SYSCALL_STUB2 ExitThread, SYS_EXIT_THREAD ; (int exitCode) -> void
SYSCALL_STUB2 CreateThread, SYS_CREATE_THREAD ; (uint64_t entry, uint64_t arg, uint32_t priority, uint32_t* tidOut) -> KSTATUS
SYSCALL_STUB2 GetCurrentTid, SYS_GET_CURRENT_TID ; () -> uint32_t
SYSCALL_STUB2 GetCurrentPid, SYS_GET_CURRENT_PID ; () -> uint32_t
SYSCALL_STUB2 Yield, SYS_YIELD ; () -> void
SYSCALL_STUB2 Sleep, SYS_SLEEP ; (uint32_t ms) -> void
SYSCALL_STUB2 SetThreadPriority, SYS_SET_THREAD_PRIORITY ; (uint32_t priority) -> KSTATUS
SYSCALL_STUB2 ExitProcess, SYS_EXIT_PROCESS
SYSCALL_STUB2 ExitThread, SYS_EXIT_THREAD
SYSCALL_STUB2 CreateProcess, SYS_CREATE_PROCESS
SYSCALL_STUB2 WaitForProcess, SYS_WAIT_FOR_PROCESS
SYSCALL_STUB2 GetProcessExitCode, SYS_GET_PROCESS_EXIT_CODE
SYSCALL_STUB2 KillProcess, SYS_KILL_PROCESS
SYSCALL_STUB2 GetProcessList, SYS_GET_PROCESS_LIST
SYSCALL_STUB2 GetProcessPid, SYS_GET_PROCESS_PID
SYSCALL_STUB2 CreateThread, SYS_CREATE_THREAD
SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD
SYSCALL_STUB2 GetCurrentTid, SYS_GET_CURRENT_TID
SYSCALL_STUB2 GetCurrentPid, SYS_GET_CURRENT_PID
SYSCALL_STUB2 SetThreadPriority, SYS_SET_THREAD_PRIORITY
SYSCALL_STUB2 Yield, SYS_YIELD
SYSCALL_STUB2 Sleep, SYS_SLEEP
SYSCALL_STUB2 SetUserApcDispatcher, SYS_SET_USER_APC_DISPATCHER
SYSCALL_STUB2 ApcReturn, SYS_APC_RETURN
; ---------------------------------------------------------------------------
; Memory
; User APC dispatcher
; ---------------------------------------------------------------------------
SYSCALL_STUB2 Alloc, SYS_ALLOC ; (size_t size) -> void* (NULL on failure)
SYSCALL_STUB2 Free, SYS_FREE ; (void* ptr, size_t size) -> void
SYSCALL_STUB2 Realloc, SYS_REALLOC ; (void* ptr, size_t newSize) -> void*
PUBLIC SysUserApcDispatcher
SysUserApcDispatcher PROC EXPORT
; Kernel enters here with RSP pointing at SYS_USER_APC_FRAME. There is no
; return address because this is an IRET redirection. Preserve RBX because
; the original user context resumes after SysApcReturn.
push rbx
lea rbx, [rsp + 8] ; original injected RSP = frame pointer
sub rsp, 32 ; shadow space; RSP is already call-aligned
mov rcx, [rbx + SYS_USER_APC_FRAME_NormalContext]
mov rdx, [rbx + SYS_USER_APC_FRAME_SystemArgument1]
mov r8, [rbx + SYS_USER_APC_FRAME_SystemArgument2]
mov rax, [rbx + SYS_USER_APC_FRAME_Routine]
call rax
add rsp, 32
mov rcx, rbx ; SysApcReturn(frame)
mov rbx, [rsp] ; restore original user RBX
add rsp, 8
mov rax, SYS_APC_RETURN
int 40h
SysUserApcDispatcher_Failed:
jmp SysUserApcDispatcher_Failed
SysUserApcDispatcher ENDP
; ---------------------------------------------------------------------------
; Mutex
; Memory and handles
; ---------------------------------------------------------------------------
SYSCALL_STUB2 MutexCreate, SYS_MUTEX_CREATE ; (uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 MutexAcquire, SYS_MUTEX_ACQUIRE ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 MutexTryAcquire, SYS_MUTEX_TRY_ACQUIRE ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 MutexRelease, SYS_MUTEX_RELEASE ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 Alloc, SYS_ALLOC
SYSCALL_STUB2 Free, SYS_FREE
SYSCALL_STUB2 Realloc, SYS_REALLOC
SYSCALL_STUB2 CloseHandle, SYS_CLOSE_HANDLE
; ---------------------------------------------------------------------------
; Semaphore
; Synchronization objects
; ---------------------------------------------------------------------------
SYSCALL_STUB2 SemCreate, SYS_SEM_CREATE ; (int32_t initial, int32_t max, uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 SemWait, SYS_SEM_WAIT ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 SemTryWait, SYS_SEM_TRY_WAIT ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 SemSignal, SYS_SEM_SIGNAL ; (uint32_t handle) -> KSTATUS
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
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
SYSCALL_STUB2 EventCreate, SYS_EVENT_CREATE
SYSCALL_STUB2 EventSignal, SYS_EVENT_SIGNAL
SYSCALL_STUB2 EventClear, SYS_EVENT_CLEAR
SYSCALL_STUB2 EventWait, SYS_EVENT_WAIT
; ---------------------------------------------------------------------------
; Event
; Queues and named queues
; ---------------------------------------------------------------------------
SYSCALL_STUB2 EventCreate, SYS_EVENT_CREATE ; (uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 EventSignal, SYS_EVENT_SIGNAL ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 EventClear, SYS_EVENT_CLEAR ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 EventWait, SYS_EVENT_WAIT ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 QueueCreate, SYS_QUEUE_CREATE
SYSCALL_STUB2 QueueSend, SYS_QUEUE_SEND
SYSCALL_STUB2 QueueRecv, SYS_QUEUE_RECV
SYSCALL_STUB2 PublishQueue, SYS_PUBLISH_QUEUE
SYSCALL_STUB2 OpenNamedQueue, SYS_OPEN_NAMED_QUEUE
SYSCALL_STUB2 QueueDuplicate, SYS_QUEUE_DUPLICATE
SYSCALL_STUB2 NamedQueueOwnerPid, SYS_NAMED_QUEUE_OWNER_PID
; ---------------------------------------------------------------------------
; Queue
; Files, directories, and current directory
; ---------------------------------------------------------------------------
SYSCALL_STUB2 QueueCreate, SYS_QUEUE_CREATE ; (uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 QueueSend, SYS_QUEUE_SEND ; (uint32_t handle, void* msg, int blocking) -> KSTATUS
SYSCALL_STUB2 QueueRecv, SYS_QUEUE_RECV ; (uint32_t handle, void* msg, int blocking) -> KSTATUS
SYSCALL_STUB2 OpenFile, SYS_OPEN_FILE
SYSCALL_STUB2 CreateFile, SYS_CREATE_FILE
SYSCALL_STUB2 ReadFile, SYS_READ_FILE
SYSCALL_STUB2 WriteFile, SYS_WRITE_FILE
SYSCALL_STUB2 ReadFileAsync, SYS_READ_FILE_ASYNC
SYSCALL_STUB2 WriteFileAsync, SYS_WRITE_FILE_ASYNC
SYSCALL_STUB2 CancelIo, SYS_CANCEL_IO
SYSCALL_STUB2 SeekFile, SYS_SEEK_FILE
SYSCALL_STUB2 GetFilePos, SYS_GET_FILE_POS
SYSCALL_STUB2 GetFileSize, SYS_GET_FILE_SIZE
SYSCALL_STUB2 TruncateFile, SYS_TRUNCATE_FILE
SYSCALL_STUB2 DeleteFile, SYS_DELETE_FILE
SYSCALL_STUB2 RenameFile, SYS_RENAME_FILE
SYSCALL_STUB2 OpenDir, SYS_OPEN_DIR
SYSCALL_STUB2 ReadDir, SYS_READ_DIR
SYSCALL_STUB2 CreateDir, SYS_CREATE_DIR
SYSCALL_STUB2 RemoveDir, SYS_REMOVE_DIR
SYSCALL_STUB2 SetCwd, SYS_SET_CWD
SYSCALL_STUB2 GetCwd, SYS_GET_CWD
; ---------------------------------------------------------------------------
; Handle (unified - use for files, mutexes, semaphores, events, queues)
; Console and graphics
; ---------------------------------------------------------------------------
SYSCALL_STUB2 CloseHandle, SYS_CLOSE_HANDLE ; (uint32_t handle) -> KSTATUS
SYSCALL_STUB2 WriteConsole, SYS_WRITE_CONSOLE
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
; ---------------------------------------------------------------------------
; File I/O
; (To close: SysCloseHandle(handle) - no dedicated SysCloseFile)
; Input
; ---------------------------------------------------------------------------
SYSCALL_STUB2 OpenFile, SYS_OPEN_FILE ; (const char* path, uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 ReadFile, SYS_READ_FILE ; (uint32_t handle, void* buf, size_t size, size_t* bytesReadOut) -> KSTATUS
SYSCALL_STUB2 WriteFile, SYS_WRITE_FILE ; (uint32_t handle, const void* buf, size_t size, size_t* bytesWrittenOut) -> KSTATUS
SYSCALL_STUB2 CreateFile, SYS_CREATE_FILE ; (const char* path, uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 DeleteFile, SYS_DELETE_FILE ; (const char* path) -> KSTATUS
SYSCALL_STUB2 TruncateFile, SYS_TRUNCATE_FILE ; (uint32_t handle, uint64_t newSize) -> KSTATUS
SYSCALL_STUB2 GetFilePos, SYS_GET_FILE_POS ; (uint32_t handle) -> uint64_t
SYSCALL_STUB2 SeekFile, SYS_SEEK_FILE ; (uint32_t handle, uint64_t offset) -> KSTATUS
SYSCALL_STUB2 GetFileSize, SYS_GET_FILE_SIZE ; (uint32_t handle) -> uint64_t
SYSCALL_STUB2 KbPoll, SYS_KB_POLL
SYSCALL_STUB2 KbIsKeyDown, SYS_KB_IS_KEY_DOWN
SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR
SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE
SYSCALL_STUB2 KbGetModifiers, SYS_KB_GET_MODIFIERS
SYSCALL_STUB2 MousePoll, SYS_MOUSE_POLL
SYSCALL_STUB2 MouseRead, SYS_MOUSE_READ
SYSCALL_STUB2 MouseGetPos, SYS_MOUSE_GET_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.
; Time and debug
; ---------------------------------------------------------------------------
SYSCALL_STUB6 ScreenBlit, SYS_SCREEN_BLIT ; (int x, int y, int w, int h, const uint32_t* pixels) -> void
SYSCALL_STUB2 ScreenClear, SYS_SCREEN_CLEAR ; (uint32_t color) -> void
SYSCALL_STUB2 ScreenGetSize, SYS_SCREEN_GET_SIZE ; (int* widthOut, int* heightOut) -> void
SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR ; (char c, int x, int y, uint32_t fg, uint32_t bg) -> void
; ---------------------------------------------------------------------------
; Keyboard
; ---------------------------------------------------------------------------
SYSCALL_STUB2 KbPoll, SYS_KB_POLL ; () -> uint32_t (1 if key available, 0 otherwise)
SYSCALL_STUB2 KbIsKeyDown, SYS_KB_IS_KEY_DOWN ; (int scancode) -> uint32_t (1 if down, 0 otherwise)
SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR ; () -> char (blocks, yields while waiting)
SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE ; () -> uint8_t (blocks, yields while waiting)
SYSCALL_STUB2 KbGetModifiers, SYS_KB_GET_MODIFIERS ; () -> uint32_t (current modifier bitmask)
; ---------------------------------------------------------------------------
; Mouse
; ---------------------------------------------------------------------------
SYSCALL_STUB2 MousePoll, SYS_MOUSE_POLL ; () -> uint32_t (1 if packet waiting, 0 otherwise)
SYSCALL_STUB2 MouseRead, SYS_MOUSE_READ ; (int* dx, int* dy, uint8_t* buttons) -> uint32_t (1=ok, 0=empty)
SYSCALL_STUB2 MouseGetPos, SYS_MOUSE_GET_POS ; (int* x, int* y) -> void
; ---------------------------------------------------------------------------
; Timer
; ---------------------------------------------------------------------------
SYSCALL_STUB2 GetTick, SYS_GET_TICK ; () -> uint64_t (milliseconds since boot)
; ---------------------------------------------------------------------------
; Debug
; ---------------------------------------------------------------------------
SYSCALL_STUB2 DebugPrint, SYS_DEBUG_PRINT ; (const char* str) -> void
; ---------------------------------------------------------------------------
; Process launch & lifecycle
; ---------------------------------------------------------------------------
SYSCALL_STUB2 CreateProcess, SYS_CREATE_PROCESS ; (const char* path, const char* args, uint32_t* pidOut) -> KSTATUS
SYSCALL_STUB2 WaitForProcess, SYS_WAIT_FOR_PROCESS ; (uint32_t pid) -> KSTATUS
SYSCALL_STUB2 GetProcessExitCode, SYS_GET_PROCESS_EXIT_CODE ; (uint32_t pid, int* exitCodeOut) -> KSTATUS
; ---------------------------------------------------------------------------
; Console output (white text, for user programs)
; ---------------------------------------------------------------------------
SYSCALL_STUB2 WriteConsole, SYS_WRITE_CONSOLE ; (const char* str, size_t len) -> void
; ---------------------------------------------------------------------------
; Directory enumeration
; ---------------------------------------------------------------------------
SYSCALL_STUB2 OpenDir, SYS_OPEN_DIR ; (const char* path, uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 ReadDir, SYS_READ_DIR ; (uint32_t handle, DirEntry* entryOut) -> KSTATUS
; ---------------------------------------------------------------------------
; Current Working Directory
; ---------------------------------------------------------------------------
SYSCALL_STUB2 SetCwd, SYS_SET_CWD ; (const char* path) -> KSTATUS
SYSCALL_STUB2 GetCwd, SYS_GET_CWD ; (char* buf, size_t buflen) -> KSTATUS
; ---------------------------------------------------------------------------
; Thread join (used by pthread_join in posix.dll)
; ---------------------------------------------------------------------------
SYSCALL_STUB2 WaitThread, SYS_WAIT_THREAD ; (uint32_t tid) -> KSTATUS
; ---------------------------------------------------------------------------
; Process PID query (used by posix_spawn -> waitpid in posix.dll)
; ---------------------------------------------------------------------------
SYSCALL_STUB2 GetProcessPid, SYS_GET_PROCESS_PID ; (uint32_t pid) -> KSTATUS
; ---------------------------------------------------------------------------
; 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 ; (const char* name, uint32_t queueHandle) -> KSTATUS
SYSCALL_STUB2 OpenNamedQueue, SYS_OPEN_NAMED_QUEUE ; (const char* name, uint32_t* handleOut) -> KSTATUS
; ---------------------------------------------------------------------------
; Handle duplication
; ---------------------------------------------------------------------------
SYSCALL_STUB2 QueueDuplicate, SYS_QUEUE_DUPLICATE ; (uint32_t handle, uint32_t targetPid, uint32_t* handleOut) -> KSTATUS
SYSCALL_STUB2 NamedQueueOwnerPid, SYS_NAMED_QUEUE_OWNER_PID ; (const char* name, uint32_t* pidOut) -> KSTATUS
; ---------------------------------------------------------------------------
; Process utilities
; ---------------------------------------------------------------------------
SYSCALL_STUB2 KillProcess, SYS_KILL_PROCESS ; (uint32_t pid, int exitCode) -> KSTATUS
SYSCALL_STUB2 GetProcessList, SYS_GET_PROCESS_LIST ; (uint32_t* pidsOut, size_t maxCount, size_t* countOut) -> KSTATUS
; ---------------------------------------------------------------------------
; Filesystem mutations
; ---------------------------------------------------------------------------
SYSCALL_STUB2 RenameFile, SYS_RENAME_FILE ; (const char* oldPath, const char* newPath) -> KSTATUS
SYSCALL_STUB2 CreateDir, SYS_CREATE_DIR ; (const char* path) -> KSTATUS
SYSCALL_STUB2 RemoveDir, SYS_REMOVE_DIR ; (const char* path) -> KSTATUS
SYSCALL_STUB2 GetTick, SYS_GET_TICK
SYSCALL_STUB2 DebugPrint, SYS_DEBUG_PRINT
SYSCALL_STUB2 QueryTrapFrame, SYS_QUERY_TRAP_FRAME
END