build.bat can create the image if missing, split the shell into native, posix and win32, clean up the build by moving executables into directories, the bootloader is no longer responsible to resolve drivers, fix ResolvePath, every process gets a copy of a module (dll), the child always inherits the cwd, fix function exports in posix, add unlink and exit to posix, add path translator to win32, first bugcheck.

This commit is contained in:
maksw committed 2026-05-13 09:24:16 +02:00
1 parent 0c7f461c6d
commit f80e66ecde
38 files changed
+1620 -462

No files matched your search

+1
View File
@@ -32,6 +32,7 @@ extern int errno; // defined in posix_fd.c; single global in v1
#define ENODEV 19
#define ENOTDIR 20
#define EINVAL 22
#define ESPIPE 29
#define EMFILE 24
#define ENOSPC 28
#define ERANGE 34
+6 -14
View File
@@ -1,17 +1,9 @@
// posix_dir.c - chdir, getcwd, opendir, readdir, closedir
#include <string.h>
#include <syscall.h>
#include "posix.h"
#include "posix_path.h"
extern uint32_t SysGetCurrentPid(void);
extern uint32_t SysSetCwd(const char* path);
extern uint32_t SysGetCwd(char* buf, size_t size);
extern uint32_t SysOpenDir(const char* path, uint32_t* handleOut);
extern uint32_t SysReadDir(uint32_t handle, void* entryOut);
extern void SysCloseHandle(uint32_t handle);
extern void* SysAlloc(size_t);
extern void SysFree(void*, size_t);
// KDIR_ENTRY layout mirrors io_file.h - duplicated here to avoid
// pulling kernel headers into posix.dll
#define KDIR_NAME_MAX 260
@@ -23,7 +15,7 @@ typedef struct {
#define KATTR_DIR 0x10
int chdir(const char* path) {
__declspec(dllexport) int chdir(const char* path) {
char native[512];
PosixTranslatePath(path, native, sizeof(native));
uint32_t s = SysSetCwd(native);
@@ -31,7 +23,7 @@ int chdir(const char* path) {
return 0;
}
char* getcwd(char* buf, size_t size) {
__declspec(dllexport) char* getcwd(char* buf, size_t size) {
if (!buf || size == 0) { errno = EINVAL; return (char*)0; }
char native[512];
uint32_t s = SysGetCwd(native, sizeof(native));
@@ -40,7 +32,7 @@ char* getcwd(char* buf, size_t size) {
return buf;
}
DIR* opendir(const char* path) {
__declspec(dllexport) DIR* opendir(const char* path) {
char native[512];
PosixTranslatePath(path, native, sizeof(native));
uint32_t kh;
@@ -55,7 +47,7 @@ DIR* opendir(const char* path) {
return d;
}
struct dirent* readdir(DIR* d) {
__declspec(dllexport) struct dirent* readdir(DIR* d) {
if (!d) { errno = EBADF; return (struct dirent*)0; }
KDIR_ENTRY ke;
uint32_t s = SysReadDir(d->KHandle, &ke);
@@ -70,7 +62,7 @@ struct dirent* readdir(DIR* d) {
return &d->Current;
}
int closedir(DIR* d) {
__declspec(dllexport) int closedir(DIR* d) {
if (!d) { errno = EBADF; return -1; }
SysCloseHandle(d->KHandle);
SysFree(d, sizeof(DIR));
+5 -12
View File
@@ -1,20 +1,13 @@
// posix_fd.c - file descriptor table
#include "posix.h"
#include "posix_fd.h"
// yeah
#ifdef errno
#undef errno
#endif
#include <syscall.h>
int errno = 0;
static FD_ENTRY gFdTable[FD_TABLE_PIDS][FD_MAX];
// Syscall stub declarations (from syscall.dll)
extern uint32_t SysGetCurrentPid(void);
void PosixFdInit(void) {
__declspec(dllexport) void PosixFdInit(void) {
uint32_t pid = SysGetCurrentPid();
uint32_t slot = pid % FD_TABLE_PIDS;
@@ -28,7 +21,7 @@ void PosixFdInit(void) {
gFdTable[slot][2] = (FD_ENTRY){ FD_CONSOLE_W, 0, true };
}
int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle) {
__declspec(dllexport) int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle) {
uint32_t slot = pid % FD_TABLE_PIDS;
for (int fd = 3; fd < FD_MAX; fd++) {
if (!gFdTable[slot][fd].Used) {
@@ -40,7 +33,7 @@ int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle) {
return -1;
}
FD_ENTRY* FdGet(uint32_t pid, int fd) {
__declspec(dllexport) FD_ENTRY* FdGet(uint32_t pid, int fd) {
if (fd < 0 || fd >= FD_MAX) { errno = EBADF; return (FD_ENTRY*)0; }
uint32_t slot = pid % FD_TABLE_PIDS;
FD_ENTRY* e = &gFdTable[slot][fd];
@@ -48,7 +41,7 @@ FD_ENTRY* FdGet(uint32_t pid, int fd) {
return e;
}
void FdFree(uint32_t pid, int fd) {
__declspec(dllexport) void FdFree(uint32_t pid, int fd) {
if (fd < 0 || fd >= FD_MAX) return;
uint32_t slot = pid % FD_TABLE_PIDS;
gFdTable[slot][fd] = (FD_ENTRY){ FD_FREE, 0, false };
+4 -4
View File
@@ -22,13 +22,13 @@ typedef struct {
#define FD_TABLE_PIDS 32 // circular, indexed by pid % FD_TABLE_PIDS
// Called from _start before main(); sets up fds 0/1/2 for this process.
void PosixFdInit(void);
__declspec(dllexport) void PosixFdInit(void);
// Allocate the lowest free fd >= 3. Returns -1 and sets errno=EMFILE on failure.
int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle);
__declspec(dllexport) int FdAlloc(uint32_t pid, FD_TYPE type, uint32_t khandle);
// Look up an fd. Returns NULL and sets errno=EBADF if invalid.
FD_ENTRY* FdGet(uint32_t pid, int fd);
__declspec(dllexport) FD_ENTRY* FdGet(uint32_t pid, int fd);
// Release an fd slot (does NOT close the kernel handle).
void FdFree(uint32_t pid, int fd);
__declspec(dllexport) void FdFree(uint32_t pid, int fd);
+27 -18
View File
@@ -1,23 +1,11 @@
// posix_io.c - open, read, write, close, lseek
#include <stddef.h>
#include <string.h>
#include <syscall.h>
#include "posix.h"
#include "posix_fd.h"
#include "posix_path.h"
extern uint32_t SysGetCurrentPid(void);
extern uint32_t SysOpenFile (const char* path, uint32_t* handleOut);
extern uint32_t SysCreateFile (const char* path, uint32_t* handleOut);
extern uint32_t SysTruncateFile(uint32_t handle, uint64_t newSize);
extern uint32_t SysReadFile (uint32_t handle, void* buf, size_t size, size_t* bytesRead);
extern uint32_t SysWriteFile (uint32_t handle, const void* buf, size_t size, size_t* written);
extern uint32_t SysSeekFile (uint32_t handle, uint64_t offset);
extern uint64_t SysGetFilePos (uint32_t handle);
extern uint64_t SysGetFileSize(uint32_t handle);
extern void SysCloseHandle(uint32_t handle);
extern void SysWriteConsole(const char* buf, size_t len);
extern char SysKbReadChar(void);
// KSTATUS -> errno
static int KsToErrno(uint32_t s) {
switch (s) {
@@ -34,7 +22,12 @@ static int KsToErrno(uint32_t s) {
}
}
int open(const char* path, int flags, ...) {
__declspec(dllexport) int ClearConsoleScreenBuffer(void* hConsole) {
SysScreenClear(0x00000000);
return 1;
}
__declspec(dllexport) int open(const char* path, int flags, ...) {
char native[512];
const char* p = PosixTranslatePath(path, native, sizeof(native));
@@ -72,7 +65,7 @@ int open(const char* path, int flags, ...) {
return fd;
}
ssize_t read(int fd, void* buf, size_t count) {
__declspec(dllexport) ssize_t read(int fd, void* buf, size_t count) {
if (count == 0) return 0;
uint32_t pid = SysGetCurrentPid();
FD_ENTRY* e = FdGet(pid, fd);
@@ -105,7 +98,7 @@ ssize_t read(int fd, void* buf, size_t count) {
}
}
ssize_t write(int fd, const void* buf, size_t count) {
__declspec(dllexport) ssize_t write(int fd, const void* buf, size_t count) {
if (count == 0) return 0;
uint32_t pid = SysGetCurrentPid();
FD_ENTRY* e = FdGet(pid, fd);
@@ -130,7 +123,7 @@ ssize_t write(int fd, const void* buf, size_t count) {
}
}
int close(int fd) {
__declspec(dllexport) int close(int fd) {
uint32_t pid = SysGetCurrentPid();
FD_ENTRY* e = FdGet(pid, fd);
if (!e) return -1;
@@ -140,7 +133,23 @@ int close(int fd) {
return 0;
}
off_t lseek(int fd, off_t offset, int whence) {
__declspec(dllexport) int unlink(const char* path) {
if (!path) { errno = EINVAL; return -1; }
char native[512];
const char* p = PosixTranslatePath(path, native, sizeof(native));
if (strcmp(p, SYNTH_DEVNULL) == 0 || strcmp(p, SYNTH_DEVZERO) == 0) {
errno = EINVAL;
return -1;
}
uint32_t s = SysDeleteFile(p);
if (s != 0) { errno = KsToErrno(s); return -1; }
return 0;
}
__declspec(dllexport) off_t lseek(int fd, off_t offset, int whence) {
uint32_t pid = SysGetCurrentPid();
FD_ENTRY* e = FdGet(pid, fd);
if (!e || e->Type != FD_FILE) { errno = (e ? ESPIPE : EBADF); return -1; }
+2 -2
View File
@@ -5,7 +5,7 @@
// The drive letter used as the POSIX filesystem root.
// A future SYS_GET_BOOT_DRIVE could populate this; hardcoded for v1.
static const char gRootDrive = 'C';
static const char gRootDrive = '0';
static void FlipSlashes(char* s) {
for (; *s; s++) if (*s == '/') *s = '\\';
@@ -27,7 +27,7 @@ const char* PosixTranslatePath(const char* in, char* out, size_t outSize) {
// outSize must fit "C:\" + rest
out[0] = gRootDrive;
out[1] = ':';
out[2] = '\\';
out[2] = '/';
size_t rest = strlen(in + 1);
if (rest + 4 > outSize) rest = outSize - 4;
memcpy(out + 3, in + 1, rest);
+8 -11
View File
@@ -1,17 +1,10 @@
// posix_proc.c - posix_spawn, waitpid, getpid
#include <stddef.h>
#include <string.h>
#include <syscall.h>
#include "posix.h"
#include "posix_path.h"
extern uint32_t SysGetCurrentPid(void);
extern uint32_t SysCreateProcess(const char* path, uint32_t* handleOut,
const char* cmdline);
extern uint32_t SysWaitForProcess(uint32_t handle);
extern uint32_t SysGetProcessExitCode(uint32_t handle, int* exitCodeOut);
extern uint32_t SysGetProcessPid(uint32_t handle, uint32_t* pidOut);
extern void SysCloseHandle(uint32_t handle);
// pid -> proc handle table (user-mode side, for waitpid)
#define PROC_TABLE_SIZE 32
typedef struct {
@@ -69,11 +62,11 @@ static void BuildCmdline(char* const argv[], char* out, size_t outSize) {
// POSIX API
// ---------------------------------------------------------------------------
pid_t getpid(void) {
__declspec(dllexport) pid_t getpid(void) {
return (pid_t)SysGetCurrentPid();
}
int posix_spawn(pid_t* pidOut,
__declspec(dllexport) int posix_spawn(pid_t* pidOut,
const char* path,
const posix_spawn_file_actions_t* file_actions, // ignored v1
const posix_spawnattr_t* attrp, // ignored v1
@@ -108,7 +101,7 @@ int posix_spawn(pid_t* pidOut,
}
// options: WNOHANG not supported in v1 (always blocks).
pid_t waitpid(pid_t pid, int* status, int options) {
__declspec(dllexport) pid_t waitpid(pid_t pid, int* status, int options) {
(void)options;
uint32_t handle = ProcTableFind(pid);
@@ -124,3 +117,7 @@ pid_t waitpid(pid_t pid, int* status, int options) {
ProcTableRemove(pid);
return pid;
}
__declspec(dllexport) void exit(int status) {
SysExitProcess(status);
}
+9 -22
View File
@@ -1,21 +1,8 @@
// posix_thread.c - pthread_create, pthread_join, pthread_exit, pthread_mutex_*
#include <stddef.h>
#include <syscall.h>
#include "posix.h"
extern uint32_t SysGetCurrentPid(void);
extern uint32_t SysGetCurrentTid(void);
extern uint32_t SysCreateThread(uint64_t entry, uint64_t arg,
uint32_t priority, uint32_t* tidOut);
extern uint32_t SysWaitThread(uint32_t tid);
extern void SysExitThread(int code);
extern void* SysAlloc(size_t size);
extern void SysFree(void* ptr, size_t size);
extern uint32_t SysMutexCreate(uint32_t* handleOut);
extern uint32_t SysMutexAcquire(uint32_t handle);
extern uint32_t SysMutexTryAcquire(uint32_t handle);
extern uint32_t SysMutexRelease(uint32_t handle);
extern void SysCloseHandle(uint32_t handle);
// Thread return-value table (PID-keyed like the fd table)
#define PTHREAD_TABLE_PIDS 32
#define PTHREAD_TABLE_SIZE 32
@@ -79,7 +66,7 @@ static void PthreadTrampoline(uintptr_t raw) {
// pthread API
// ---------------------------------------------------------------------------
int pthread_create(pthread_t* t, const pthread_attr_t* attr,
__declspec(dllexport) int pthread_create(pthread_t* t, const pthread_attr_t* attr,
void* (*fn)(void*), void* arg) {
(void)attr;
@@ -108,7 +95,7 @@ int pthread_create(pthread_t* t, const pthread_attr_t* attr,
return 0;
}
int pthread_join(pthread_t t, void** retval) {
__declspec(dllexport) int pthread_join(pthread_t t, void** retval) {
uint32_t pid = SysGetCurrentPid();
uint32_t s = SysWaitThread(t.Tid);
// STATUS_NOT_FOUND (0x22) means already dead - treat as success
@@ -120,7 +107,7 @@ int pthread_join(pthread_t t, void** retval) {
return 0;
}
void pthread_exit(void* retval) {
__declspec(dllexport) void pthread_exit(void* retval) {
uint32_t pid = SysGetCurrentPid();
uint32_t tid = SysGetCurrentTid();
PTHREAD_SLOT* slot = PthreadSlotFind(pid, tid);
@@ -129,7 +116,7 @@ void pthread_exit(void* retval) {
while (1); // unreachable
}
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr) {
__declspec(dllexport) int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr) {
(void)attr;
uint32_t h;
uint32_t s = SysMutexCreate(&h);
@@ -138,23 +125,23 @@ int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr) {
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t* m) {
__declspec(dllexport) int pthread_mutex_destroy(pthread_mutex_t* m) {
SysCloseHandle(m->Handle);
m->Handle = 0;
return 0;
}
int pthread_mutex_lock(pthread_mutex_t* m) {
__declspec(dllexport) int pthread_mutex_lock(pthread_mutex_t* m) {
uint32_t s = SysMutexAcquire(m->Handle);
return s == 0 ? 0 : EINVAL;
}
int pthread_mutex_trylock(pthread_mutex_t* m) {
__declspec(dllexport) int pthread_mutex_trylock(pthread_mutex_t* m) {
uint32_t s = SysMutexTryAcquire(m->Handle);
return s == 0 ? 0 : EAGAIN;
}
int pthread_mutex_unlock(pthread_mutex_t* m) {
__declspec(dllexport) int pthread_mutex_unlock(pthread_mutex_t* m) {
uint32_t s = SysMutexRelease(m->Handle);
return s == 0 ? 0 : EINVAL;
}