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:
Nexoniarz 2026-08-09 13:47:01 +02:00
commit d0f7acf9eb
275 changed files with 51417 additions and 0 deletions

79
kernel/core/uaccess.c Normal file
View file

@ -0,0 +1,79 @@
// User-memory access helpers — see include/uaccess.h for the rules.
//
// Everything here validates against the *current* process's page table
// (myproc()->pgdir), which is also the live CR3 while a syscall runs, so a
// range that passes access_ok() can be dereferenced directly by kernel
// code for the remainder of the syscall (single-threaded processes can't
// unmap it out from under us mid-call).
#include "types.h"
#include "defs.h"
#include "param.h"
#include "memlayout.h"
#include "mmu.h"
#include "proc.h"
#include "errno.h"
#include "uaccess.h"
int
access_ok(addr_t uaddr, uint64 size)
{
addr_t a, end;
if(size == 0)
return 1;
end = uaddr + size;
if(end < uaddr || end > KERNBASE)
return 0;
for(a = PGROUNDDOWN(uaddr); a < end; a += PGSIZE)
if(uva2ka(myproc()->pgdir, (char*)a) == 0)
return 0;
return 1;
}
void*
user_ptr(addr_t uaddr, uint64 size)
{
if(uaddr == 0 || !access_ok(uaddr, size))
return 0;
return (void*)uaddr;
}
int
copy_from_user(void *dst, addr_t uaddr, uint64 n)
{
if(uaddr + n < uaddr || uaddr + n > KERNBASE)
return -EFAULT;
if(copyin(myproc()->pgdir, uaddr, dst, n) < 0)
return -EFAULT;
return 0;
}
int
copy_to_user(addr_t uaddr, const void *src, uint64 n)
{
if(uaddr + n < uaddr || uaddr + n > KERNBASE)
return -EFAULT;
if(copyout(myproc()->pgdir, uaddr, (void*)src, n) < 0)
return -EFAULT;
return 0;
}
long
strlen_user(addr_t uaddr)
{
addr_t a = uaddr;
while(a - uaddr < USER_STR_MAX){
// Scan through the per-page kernel alias so an unmapped page is a
// clean failure instead of a fault.
char *ka = uva2ka(myproc()->pgdir, (char*)a);
if(ka == 0)
return -EFAULT;
addr_t pgend = PGROUNDDOWN(a) + PGSIZE;
for(; a < pgend; a++, ka++)
if(*ka == 0)
return a - uaddr;
}
return -EFAULT;
}