Initial commit: Schunix as it stands before the SchOS rename
An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
This commit is contained in:
commit
d0f7acf9eb
275 changed files with 51417 additions and 0 deletions
162
kernel/sys/sys_compat.c
Normal file
162
kernel/sys/sys_compat.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// POSIX / Linux-ABI compatibility syscalls.
|
||||
// These are stubs or thin wrappers that make musl and ksh happy
|
||||
// without implementing full semantics.
|
||||
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "memlayout.h"
|
||||
#include "mmu.h"
|
||||
#include "traps.h"
|
||||
#include "proc.h"
|
||||
#include "x86.h"
|
||||
#include "syscall.h"
|
||||
#include "posix.h"
|
||||
#include "uaccess.h"
|
||||
#include "errno.h"
|
||||
|
||||
extern int linux_syscall_map[];
|
||||
extern int linux_syscall_map_size;
|
||||
|
||||
// enable_linux_abi: switch this process to Linux syscall numbering.
|
||||
addr_t
|
||||
sys_enable_linux_abi(void)
|
||||
{
|
||||
myproc()->syscall_map = linux_syscall_map;
|
||||
myproc()->map_size = linux_syscall_map_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set_tid_address: musl calls this at startup to register its TID location.
|
||||
addr_t
|
||||
sys_set_tid_address(void)
|
||||
{
|
||||
addr_t tidp;
|
||||
argaddr(0, &tidp);
|
||||
if (tidp)
|
||||
put_user(myproc()->pid, tidp);
|
||||
return myproc()->pid;
|
||||
}
|
||||
|
||||
// set_robust_list: robust mutex cleanup on exit — stub.
|
||||
addr_t sys_set_robust_list(void) { return 0; }
|
||||
|
||||
// futex: used by musl for single-threaded lock primitives.
|
||||
addr_t
|
||||
sys_futex(void)
|
||||
{
|
||||
int op;
|
||||
argint(1, &op);
|
||||
op &= ~(FUTEX_WAIT_PRIVATE - FUTEX_WAIT);
|
||||
if (op == FUTEX_WAKE || op == FUTEX_WAKE_PRIVATE)
|
||||
return 0;
|
||||
return -EAGAIN; // no blocking, musl retries
|
||||
}
|
||||
|
||||
// arch_prctl: save FS_BASE for TLS.
|
||||
addr_t
|
||||
sys_arch_prctl(void)
|
||||
{
|
||||
int code;
|
||||
addr_t addr;
|
||||
argint(0, &code);
|
||||
argaddr(1, &addr);
|
||||
if (code == ARCH_SET_FS) {
|
||||
myproc()->fs_base = addr;
|
||||
return 0;
|
||||
}
|
||||
if (code == ARCH_GET_FS) {
|
||||
if (put_user(myproc()->fs_base, addr) < 0)
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_getrlimit(void)
|
||||
{
|
||||
int resource;
|
||||
struct rlimit *rlp;
|
||||
argint(0, &resource);
|
||||
if (argptr(1, (char**)&rlp, sizeof(*rlp)) < 0)
|
||||
return -1;
|
||||
rlp->rlim_cur = (uint64)-1;
|
||||
rlp->rlim_max = (uint64)-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_prlimit(void)
|
||||
{
|
||||
struct rlimit *oldrlp;
|
||||
if (argptr(3, (char**)&oldrlp, sizeof(*oldrlp)) == 0 && oldrlp) {
|
||||
oldrlp->rlim_cur = (uint64)-1;
|
||||
oldrlp->rlim_max = (uint64)-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// uname: return fake but plausible kernel/host info
|
||||
addr_t
|
||||
sys_uname(void)
|
||||
{
|
||||
struct utsname {
|
||||
char sysname[65];
|
||||
char nodename[65];
|
||||
char release[65];
|
||||
char version[65];
|
||||
char machine[65];
|
||||
char domainname[65];
|
||||
};
|
||||
addr_t ubuf;
|
||||
argaddr(0, &ubuf);
|
||||
struct utsname *u = (struct utsname*)user_ptr(ubuf, sizeof(*u));
|
||||
if (!u) return -EFAULT;
|
||||
memset(u, 0, sizeof(*u));
|
||||
memmove(u->sysname, "Schunix", 8);
|
||||
memmove(u->nodename, "schunix", 8);
|
||||
memmove(u->release, "0.1.0", 6);
|
||||
memmove(u->version, "#1", 3);
|
||||
memmove(u->machine, "x86_64", 7);
|
||||
memmove(u->domainname, "(none)", 7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// socket/bind/listen/accept/connect live in sys_net.c now that they do
|
||||
// something.
|
||||
|
||||
// syslog: kernel logging facility — no-op for user processes.
|
||||
addr_t sys_syslog(void) { return 0; }
|
||||
|
||||
// getrandom: fill buffer with pseudo-random bytes.
|
||||
addr_t sys_getrandom(void)
|
||||
{
|
||||
addr_t bufaddr;
|
||||
int len, flags;
|
||||
argaddr(0, &bufaddr); argint(1, &len); argint(2, &flags);
|
||||
if (len <= 0) return 0;
|
||||
uint8 *buf = (uint8*)user_ptr(bufaddr, (uint64)len);
|
||||
if (!buf) return -EFAULT;
|
||||
// LCG seeded from proc pointer + pid; no lock needed (read-only fields).
|
||||
uint rseed = (uint)(uintptr_t)myproc() ^ (uint)myproc()->pid;
|
||||
for (int i = 0; i < len; i++) {
|
||||
rseed = rseed * 1664525u + 1013904223u;
|
||||
buf[i] = (uint8)(rseed >> 16);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
// pselect6 / ppoll live in sys_poll.c alongside select/poll.
|
||||
|
||||
// epoll: not implemented.
|
||||
addr_t sys_epoll_create1(void) { return -ENOSYS; }
|
||||
addr_t sys_epoll_ctl(void) { return -ENOSYS; }
|
||||
addr_t sys_epoll_wait(void) { return -ENOSYS; }
|
||||
|
||||
// signalfd / eventfd / timerfd: not implemented.
|
||||
addr_t sys_signalfd4(void) { return -ENOSYS; }
|
||||
addr_t sys_eventfd2(void) { return -ENOSYS; }
|
||||
addr_t sys_timerfd_create(void) { return -ENOSYS; }
|
||||
addr_t sys_timerfd_settime(void){ return -ENOSYS; }
|
||||
addr_t sys_timerfd_gettime(void){ return -ENOSYS; }
|
||||
Loading…
Reference in a new issue