提交 16f95ce9 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge branch 'scale-amd64' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

...@@ -28,7 +28,7 @@ NM = $(TOOLPREFIX)nm ...@@ -28,7 +28,7 @@ NM = $(TOOLPREFIX)nm
OBJCOPY = $(TOOLPREFIX)objcopy OBJCOPY = $(TOOLPREFIX)objcopy
STRIP = $(TOOLPREFIX)strip STRIP = $(TOOLPREFIX)strip
INCLUDES = -iquote include -Istdinc -I$(QEMUSRC) -include param.h -include include/compiler.h INCLUDES = -iquote include -iquote$(O)/include -Istdinc -I$(QEMUSRC) -include param.h -include include/compiler.h
COMFLAGS = -static -g -MD -m64 -O3 -Wall -Werror -DHW_$(HW) -DXV6 \ COMFLAGS = -static -g -MD -m64 -O3 -Wall -Werror -DHW_$(HW) -DXV6 \
-fno-builtin -fno-strict-aliasing -fno-omit-frame-pointer -fms-extensions \ -fno-builtin -fno-strict-aliasing -fno-omit-frame-pointer -fms-extensions \
-mno-sse -mcx16 -mno-red-zone $(INCLUDES) -mno-sse -mcx16 -mno-red-zone $(INCLUDES)
...@@ -58,11 +58,21 @@ $(O)/%.o: %.cc ...@@ -58,11 +58,21 @@ $(O)/%.o: %.cc
$(Q)mkdir -p $(@D) $(Q)mkdir -p $(@D)
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $< $(Q)$(CXX) $(CXXFLAGS) -c -o $@ $<
$(O)/%.o: $(O)/%.cc
@echo " CXX $@"
$(Q)mkdir -p $(@D)
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $<
$(O)/%.o: %.S $(O)/%.o: %.S
@echo " CC $@" @echo " CC $@"
$(Q)mkdir -p $(@D) $(Q)mkdir -p $(@D)
$(Q)$(CC) $(ASFLAGS) -c -o $@ $< $(Q)$(CC) $(ASFLAGS) -c -o $@ $<
$(O)/%.o: $(O)/%.S
@echo " CC $@"
$(Q)mkdir -p $(@D)
$(Q)$(CC) $(ASFLAGS) -c -o $@ $<
xv6memfs.img: bootblock kernelmemfs xv6memfs.img: bootblock kernelmemfs
dd if=/dev/zero of=xv6memfs.img count=10000 dd if=/dev/zero of=xv6memfs.img count=10000
dd if=bootblock of=xv6memfs.img conv=notrunc dd if=bootblock of=xv6memfs.img conv=notrunc
......
...@@ -57,5 +57,7 @@ $(O)/bin/%: $(O)/bin/%.unstripped ...@@ -57,5 +57,7 @@ $(O)/bin/%: $(O)/bin/%.unstripped
$(Q)mkdir -p $(@D) $(Q)mkdir -p $(@D)
$(Q)$(STRIP) -o $@ $< $(Q)$(STRIP) -o $@ $<
$(addsuffix .o,$(UPROGS)): $(O)/include/sysstubs.h
.PRECIOUS: $(O)/bin/%.o $(O)/bin/%.unstripped .PRECIOUS: $(O)/bin/%.o $(O)/bin/%.unstripped
-include $(O)/bin/*.d -include $(O)/bin/*.d
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#include "user.h" #include "user.h"
#include "fs.h" #include "fs.h"
#include "fcntl.h" #include "fcntl.h"
#include "syscall.h"
#include "traps.h" #include "traps.h"
#include "pthread.h" #include "pthread.h"
......
...@@ -16,46 +16,6 @@ void swtch(struct context**, struct context*); ...@@ -16,46 +16,6 @@ void swtch(struct context**, struct context*);
// trap.c // trap.c
extern struct segdesc bootgdt[NSEGS]; extern struct segdesc bootgdt[NSEGS];
// syscalls
struct stat;
long sys_chdir(const char*);
long sys_close(int);
long sys_dup(int);
long sys_exec(const char*, u64);
long sys_exit(void);
long sys_fork(int);
long sys_fstat(int, struct stat*);
long sys_getpid(void);
long sys_kill(int);
long sys_link(const char*, const char*);
long sys_mkdirat(int, const char*);
long sys_mknod(const char*, int, int);
long sys_openat(int, const char*, int);
long sys_pipe(int*);
long sys_read(int, char*, int);
long sys_sbrk(int);
long sys_nsleep(u64);
long sys_unlink(const char*);
long sys_wait(void);
long sys_write(int, const void*, int);
long sys_uptime(void);
long sys_map(uptr, u64);
long sys_unmap(uptr, u64);
long sys_halt(void);
long sys_socket(int, int, int);
long sys_bind(int, void*, int);
long sys_listen(int, int);
long sys_accept(int, void*, void*);
long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
long sys_async(int, size_t, off_t, u32, u32);
long sys_script(void *addr, u64 len, u64 chunk);
long sys_setfs(u64 base);
long sys_wqwait(void);
long sys_setaffinity(int cpu);
long sys_futex(const u64* addr, int op, u64 val, u64 timer);
extern long (*syscalls[])(u64, u64, u64, u64, u64);
// other exported/imported functions // other exported/imported functions
void cmain(u64 mbmagic, u64 mbaddr); void cmain(u64 mbmagic, u64 mbaddr);
void mpboot(void); void mpboot(void);
......
...@@ -6,6 +6,7 @@ extern "C" { ...@@ -6,6 +6,7 @@ extern "C" {
#include "atomic.hh" #include "atomic.hh"
#include "memlayout.h" #include "memlayout.h"
#include "userptr.hh"
#include <stdarg.h> #include <stdarg.h>
#define KCSEG (2<<3) /* kernel code segment */ #define KCSEG (2<<3) /* kernel code segment */
...@@ -147,6 +148,9 @@ void lapic_tlbflush(hwid_t); ...@@ -147,6 +148,9 @@ void lapic_tlbflush(hwid_t);
void lapic_sampconf(hwid_t); void lapic_sampconf(hwid_t);
void lapicpc(char mask); void lapicpc(char mask);
// main.c
void halt(void) __attribute__((noreturn));
// mp.c // mp.c
extern int ncpu; extern int ncpu;
int mpbcpu(void); int mpbcpu(void);
......
// System call numbers
#define SYS_fork 1
#define SYS_exit 2
#define SYS_wait 3
#define SYS_pipe 4
#define SYS_write 5
#define SYS_read 6
#define SYS_close 7
#define SYS_kill 8
#define SYS_exec 9
#define SYS_openat 10
#define SYS_mknod 11
#define SYS_unlink 12
#define SYS_fstat 13
#define SYS_link 14
#define SYS_mkdirat 15
#define SYS_chdir 16
#define SYS_dup 17
#define SYS_getpid 18
#define SYS_sbrk 19
#define SYS_nsleep 20
#define SYS_uptime 21
#define SYS_map 22
#define SYS_unmap 23
#define SYS_halt 24
#define SYS_socket 25
#define SYS_bind 26
#define SYS_listen 27
#define SYS_accept 28
#define SYS_pread 29
#define SYS_async 30
#define SYS_script 31
#define SYS_setfs 32
#define SYS_wqwait 33
#define SYS_setaffinity 34
#define SYS_futex 35
#define SYS_ncount 36 /* total number of system calls */
...@@ -5,9 +5,9 @@ extern "C" { ...@@ -5,9 +5,9 @@ extern "C" {
// system calls // system calls
extern int socket(int domain, int type, int protocol); extern int socket(int domain, int type, int protocol);
extern int bind(int sockfd, const struct sockaddr *addr, extern int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen); int addrlen);
extern int listen(int sockfd, int backlog); extern int listen(int sockfd, int backlog);
extern int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); extern int accept(int sockfd, struct sockaddr *addr, int *addrlen);
} }
static inline const char * static inline const char *
......
...@@ -2,40 +2,9 @@ ...@@ -2,40 +2,9 @@
BEGIN_DECLS BEGIN_DECLS
struct stat; struct stat;
struct ipcmsg; struct sockaddr;
// system calls #include "sysstubs.h"
int fork(int);
int exit(void) __attribute__((noreturn));
int wait(void);
int pipe(int*);
int write(int, const void*, int);
int read(int, void*, int);
int close(int);
int kill(int);
int exec(const char*, const char**);
int openat(int dirfd, const char *pathname, int omode);
int mknod(const char*, short, short);
int unlink(const char*);
int fstat(int fd, struct stat*);
int link(const char*, const char*);
int mkdir(const char*);
int mkdirat(int dirfd, const char *pathname);
int chdir(const char*);
int dup(int);
int getpid(void);
char* sbrk(int);
int nsleep(u64);
u64 uptime(void);
int map(void *addr, int len);
int unmap(void *addr, int len);
void halt(void);
ssize_t pread(int, void*, size_t, off_t);
int async(int, size_t, off_t, u32, u32);
int script(void *addr, u64 len, u64 chunk);
int setfs(u64 base);
int setaffinity(int cpu);
long futex(const u64* addr, int op, u64 val, u64 timer);
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);
...@@ -48,6 +17,7 @@ char* strchr(const char*, char c); ...@@ -48,6 +17,7 @@ char* strchr(const char*, char c);
int strcmp(const char*, const char*); int strcmp(const char*, const char*);
int strncmp(const char *p, const char *q, size_t n); int strncmp(const char *p, const char *q, size_t n);
int open(const char*, int); int open(const char*, int);
int mkdir(const char*);
char* gets(char*, int max); char* gets(char*, int max);
unsigned int strlen(const char*); unsigned int strlen(const char*);
......
#pragma once
// A protected pointer to user data. These act like pointers (and
// their in-memory representation is identical), but userptr's cannot
// be dereferenced without explicit checks.
template<typename T>
class userptr
{
T* ptr;
public:
explicit userptr(T* p) : ptr(p) { }
explicit userptr(uptr p) : ptr((T*)p) { }
userptr() = default;
userptr(const userptr<T> &o) = default;
userptr(userptr<T> &&o) = default;
T* unsafe_get() const
{
return ptr;
}
// Allow implicit conversion to userptr<void> (mirroring C++'s
// implicit casts to void*)
operator userptr<void> () const
{
return userptr<void>{ptr};
}
// Allow implicit casts to uptr. Often it makes sense to treat a
// user pointer as an opaque number and a lot of existing code uses
// this convention. (XXX(austin) this means we can't have things
// like operator+, which would probably subsume our current uses of
// uptr anyway.)
operator uptr () const
{
return (uptr)ptr;
}
};
// For userptr to be passed like a regular pointer, its representation
// must be the same as a pointer (obviously) and, furthermore, the
// AMD64 ABI requires that it have a trivial copy construct and
// trivial destructor.
static_assert(sizeof(userptr<void>) == sizeof(void*), "userptr is wrong size");
static_assert(__is_pod(userptr<void>), "userptr is not a POD");
...@@ -52,7 +52,8 @@ OBJS = \ ...@@ -52,7 +52,8 @@ OBJS = \
wqlib.o \ wqlib.o \
script.o \ script.o \
zalloc.o \ zalloc.o \
incbin.o incbin.o \
sysvectors.o \
ifeq ($(EXCEPTIONS),y) ifeq ($(EXCEPTIONS),y)
OBJS += \ OBJS += \
...@@ -114,13 +115,18 @@ $(O)/kernel/%.o: lib/%.cc ...@@ -114,13 +115,18 @@ $(O)/kernel/%.o: lib/%.cc
$(O)/kernel/incbin.o: ASFLAGS+=-DMAKE_OUT=$(O) $(O)/kernel/incbin.o: ASFLAGS+=-DMAKE_OUT=$(O)
$(O)/kernel/incbin.o: $(O)/kernel/initcode $(O)/kernel/bootother $(O)/fs.img $(O)/kernel/incbin.o: $(O)/kernel/initcode $(O)/kernel/bootother $(O)/fs.img
# link initcode against sysstubs to get syscall numbers
$(O)/kernel/initcode: TTEXT = 0x1000 $(O)/kernel/initcode: TTEXT = 0x1000
$(O)/kernel/initcode: LDEXTRA = $(O)/lib/sysstubs.o
$(O)/kernel/initcode: $(O)/lib/sysstubs.o
$(O)/kernel/bootother: TTEXT = 0x7000 $(O)/kernel/bootother: TTEXT = 0x7000
$(O)/kernel/%: kernel/%.S $(O)/kernel/%: kernel/%.S
@echo " CC $@" @echo " CC $@"
$(Q)mkdir -p $(@D) $(Q)mkdir -p $(@D)
$(Q)$(CC) $(CFLAGS) -nostdinc -I. -c $< -o $@.o $(Q)$(CC) $(CFLAGS) -nostdinc -I. -c $< -o $@.o
$(Q)$(LD) $(LDFLAGS) -N -e start -Ttext $(TTEXT) -o $@.out $@.o $(Q)$(LD) $(LDFLAGS) -N -e start -Ttext $(TTEXT) -o $@.out $@.o $(LDEXTRA)
$(Q)$(OBJCOPY) -S -O binary $@.out $@ $(Q)$(OBJCOPY) -S -O binary $@.out $@
$(O)/kernel/asmdefines.S: kernel/asmdefines.c $(O)/kernel/asmdefines.S: kernel/asmdefines.c
...@@ -135,6 +141,11 @@ $(O)/include/asmdefines.h: $(O)/kernel/asmdefines.S ...@@ -135,6 +141,11 @@ $(O)/include/asmdefines.h: $(O)/kernel/asmdefines.S
$(O)/kernel/trapasm.o: $(O)/include/asmdefines.h $(O)/kernel/trapasm.o: $(O)/include/asmdefines.h
$(O)/kernel/uaccess.o: $(O)/include/asmdefines.h $(O)/kernel/uaccess.o: $(O)/include/asmdefines.h
$(O)/kernel/sysvectors.cc: tools/syscalls.py kernel/*.cc
@echo " GEN $@"
$(Q)mkdir -p $(@D)
$(Q)python $^ --kvectors > $@
.PRECIOUS: $(O)/kernel/%.o .PRECIOUS: $(O)/kernel/%.o
-include $(O)/kernel/*.d -include $(O)/kernel/*.d
......
...@@ -52,9 +52,10 @@ pread_allocwork(struct inode *ip, size_t count, off_t off, ...@@ -52,9 +52,10 @@ pread_allocwork(struct inode *ip, size_t count, off_t off,
return w; return w;
} }
long //SYSCALL
int
sys_async(int fd, size_t count, off_t off, sys_async(int fd, size_t count, off_t off,
msgid_t msgid, pageid_t pageid) int msgid, int pageid)
{ {
sref<file> f;; sref<file> f;;
cwork *w; cwork *w;
......
#include "types.h" #include "types.h"
#include "mmu.h" #include "mmu.h"
#include "spinlock.h"
#include "syscall.h"
#include "kern_c.h"
/* /*
* Data structures that use C99 designated initializers, * Data structures that use C99 designated initializers,
...@@ -25,43 +22,3 @@ struct segdesc __attribute__((aligned(16))) bootgdt[NSEGS] = { ...@@ -25,43 +22,3 @@ struct segdesc __attribute__((aligned(16))) bootgdt[NSEGS] = {
// 64-bit user code // 64-bit user code
[7]=SEGDESC(0, 0, SEG_R|SEG_CODE|SEG_S|SEG_DPL(3)|SEG_P|SEG_L|SEG_G), [7]=SEGDESC(0, 0, SEG_R|SEG_CODE|SEG_S|SEG_DPL(3)|SEG_P|SEG_L|SEG_G),
}; };
#define SYSCALL(name) [SYS_##name] = (void*)sys_##name
long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL(chdir),
SYSCALL(close),
SYSCALL(dup),
SYSCALL(exec),
SYSCALL(exit),
SYSCALL(fork),
SYSCALL(fstat),
SYSCALL(getpid),
SYSCALL(kill),
SYSCALL(link),
SYSCALL(mkdirat),
SYSCALL(mknod),
SYSCALL(openat),
SYSCALL(pipe),
SYSCALL(read),
SYSCALL(sbrk),
SYSCALL(nsleep),
SYSCALL(unlink),
SYSCALL(wait),
SYSCALL(write),
SYSCALL(uptime),
SYSCALL(map),
SYSCALL(unmap),
SYSCALL(halt),
SYSCALL(socket),
SYSCALL(bind),
SYSCALL(listen),
SYSCALL(accept),
SYSCALL(pread),
SYSCALL(async),
SYSCALL(script),
SYSCALL(setfs),
SYSCALL(wqwait),
SYSCALL(setaffinity),
SYSCALL(futex),
};
...@@ -183,7 +183,7 @@ kerneltrap(struct trapframe *tf) ...@@ -183,7 +183,7 @@ kerneltrap(struct trapframe *tf)
printtrace(tf->rbp); printtrace(tf->rbp);
panicked = 1; panicked = 1;
sys_halt(); halt();
for(;;) for(;;)
; ;
} }
...@@ -204,7 +204,7 @@ panic(const char *fmt, ...) ...@@ -204,7 +204,7 @@ panic(const char *fmt, ...)
printtrace(rrbp()); printtrace(rrbp());
panicked = 1; panicked = 1;
sys_halt(); halt();
for(;;) for(;;)
; ;
} }
......
# Initial process execs /init. # Initial process execs /init.
#include "syscall.h"
#include "traps.h" #include "traps.h"
# exec(init, argv) # exec(init, argv)
......
...@@ -140,3 +140,14 @@ cmain(u64 mbmagic, u64 mbaddr) ...@@ -140,3 +140,14 @@ cmain(u64 mbmagic, u64 mbaddr)
panic("Unreachable"); panic("Unreachable");
} }
void
halt(void)
{
int i;
const char s[] = "Shutdown";
for(i = 0; i < 8; i++)
outb(0x8900, s[i]);
for (;;);
}
...@@ -273,9 +273,9 @@ netsocket(int domain, int type, int protocol) ...@@ -273,9 +273,9 @@ netsocket(int domain, int type, int protocol)
} }
long long
netbind(int sock, void *xaddr, int xaddrlen) netbind(int sock, const sockaddr *xaddr, int xaddrlen)
{ {
void *addr; const sockaddr *addr;
long r; long r;
addr = kmalloc(xaddrlen, "sockaddr"); addr = kmalloc(xaddrlen, "sockaddr");
...@@ -286,7 +286,7 @@ netbind(int sock, void *xaddr, int xaddrlen) ...@@ -286,7 +286,7 @@ netbind(int sock, void *xaddr, int xaddrlen)
return -1; return -1;
lwip_core_lock(); lwip_core_lock();
r = lwip_bind(sock, (const sockaddr*) addr, xaddrlen); r = lwip_bind(sock, addr, xaddrlen);
lwip_core_unlock(); lwip_core_unlock();
kmfree(addr, xaddrlen); kmfree(addr, xaddrlen);
return r; return r;
...@@ -304,14 +304,13 @@ netlisten(int sock, int backlog) ...@@ -304,14 +304,13 @@ netlisten(int sock, int backlog)
} }
long long
netaccept(int sock, void *xaddr, void *xaddrlen) netaccept(int sock, struct sockaddr *xaddr, int *xaddrlen)
{ {
socklen_t *lenptr = (socklen_t*) xaddrlen;
socklen_t len; socklen_t len;
void *addr; void *addr;
int ss; int ss;
if (fetchmem(&len, lenptr, sizeof(*lenptr))) if (fetchmem(&len, xaddrlen, sizeof(*xaddrlen)))
return -1; return -1;
addr = kmalloc(len, "sockaddr"); addr = kmalloc(len, "sockaddr");
...@@ -413,7 +412,7 @@ netsocket(int domain, int type, int protocol) ...@@ -413,7 +412,7 @@ netsocket(int domain, int type, int protocol)
} }
long long
netbind(int sock, void *xaddr, int xaddrlen) netbind(int sock, const struct sockaddr *xaddr, int xaddrlen)
{ {
return -1; return -1;
} }
...@@ -425,7 +424,7 @@ netlisten(int sock, int backlog) ...@@ -425,7 +424,7 @@ netlisten(int sock, int backlog)
} }
long long
netaccept(int sock, void *xaddr, void *xaddrlen) netaccept(int sock, struct sockaddr *xaddr, int *xaddrlen)
{ {
return -1; return -1;
} }
......
...@@ -28,7 +28,8 @@ script_mmap_work(void *a0, void *a1, void *a2, void *a3) ...@@ -28,7 +28,8 @@ script_mmap_work(void *a0, void *a1, void *a2, void *a3)
*donep += 1; *donep += 1;
} }
long //SYSCALL
int
sys_script(void *addr, u64 len, u64 chunk) sys_script(void *addr, u64 len, u64 chunk)
{ {
atomic<int> done; atomic<int> done;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "queue.h" #include "queue.h"
#include "proc.hh" #include "proc.hh"
#include "amd64.h" #include "amd64.h"
#include "syscall.h"
#include "cpu.hh" #include "cpu.hh"
#include "kmtrace.hh" #include "kmtrace.hh"
...@@ -14,6 +13,9 @@ extern "C" int __uaccess_mem(void* dst, const void* src, u64 size); ...@@ -14,6 +13,9 @@ extern "C" int __uaccess_mem(void* dst, const void* src, u64 size);
extern "C" int __uaccess_str(char* dst, const char* src, u64 size); extern "C" int __uaccess_str(char* dst, const char* src, u64 size);
extern "C" int __uaccess_int64(uptr addr, u64* ip); extern "C" int __uaccess_int64(uptr addr, u64* ip);
// XXX(austin) Many of these functions should take userptr<void>
// instead of regular pointers
int int
fetchmem(void* dst, const void* usrc, u64 size) fetchmem(void* dst, const void* usrc, u64 size)
{ {
...@@ -77,6 +79,9 @@ argcheckptr(const void *p, int size) ...@@ -77,6 +79,9 @@ argcheckptr(const void *p, int size)
return 0; return 0;
} }
extern u64 (*syscalls[])(u64, u64, u64, u64, u64);
extern const int nsyscalls;
u64 u64
syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num) syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
{ {
...@@ -86,7 +91,7 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num) ...@@ -86,7 +91,7 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
#if EXCEPTIONS #if EXCEPTIONS
try { try {
#endif #endif
if(num < SYS_ncount && syscalls[num]) { if(num < nsyscalls && syscalls[num]) {
mtstart(syscalls[num], myproc()); mtstart(syscalls[num], myproc());
mtrec(); mtrec();
u64 r = syscalls[num](a0, a1, a2, a3, a4); u64 r = syscalls[num](a0, a1, a2, a3, a4);
......
...@@ -28,7 +28,8 @@ fdalloc(file *f) ...@@ -28,7 +28,8 @@ fdalloc(file *f)
return myproc()->ftable->allocfd(f); return myproc()->ftable->allocfd(f);
} }
long //SYSCALL
int
sys_dup(int ofd) sys_dup(int ofd)
{ {
sref<file> f; sref<file> f;
...@@ -44,16 +45,18 @@ sys_dup(int ofd) ...@@ -44,16 +45,18 @@ sys_dup(int ofd)
return fd; return fd;
} }
s64 //SYSCALL
sys_read(int fd, char *p, int n) ssize_t
sys_read(int fd, void *p, size_t n)
{ {
sref<file> f; sref<file> f;
if(!getfile(fd, &f) || argcheckptr(p, n) < 0) if(!getfile(fd, &f) || argcheckptr(p, n) < 0)
return -1; return -1;
return f->read(p, n); return f->read(static_cast<char*>(p), n);
} }
//SYSCALL
ssize_t ssize_t
sys_pread(int fd, void *ubuf, size_t count, off_t offset) sys_pread(int fd, void *ubuf, size_t count, off_t offset)
{ {
...@@ -70,8 +73,9 @@ sys_pread(int fd, void *ubuf, size_t count, off_t offset) ...@@ -70,8 +73,9 @@ sys_pread(int fd, void *ubuf, size_t count, off_t offset)
return f->pread((char*)ubuf, count, offset); return f->pread((char*)ubuf, count, offset);
} }
long //SYSCALL
sys_write(int fd, const void *p, int n) ssize_t
sys_write(int fd, const void *p, size_t n)
{ {
sref<file> f; sref<file> f;
...@@ -80,7 +84,8 @@ sys_write(int fd, const void *p, int n) ...@@ -80,7 +84,8 @@ sys_write(int fd, const void *p, int n)
return f->write(static_cast<const char*>(p), n); return f->write(static_cast<const char*>(p), n);
} }
long //SYSCALL
int
sys_close(int fd) sys_close(int fd)
{ {
sref<file> f; sref<file> f;
...@@ -91,7 +96,8 @@ sys_close(int fd) ...@@ -91,7 +96,8 @@ sys_close(int fd)
return 0; return 0;
} }
long //SYSCALL
int
sys_fstat(int fd, struct stat *st) sys_fstat(int fd, struct stat *st)
{ {
sref<file> f; sref<file> f;
...@@ -102,7 +108,8 @@ sys_fstat(int fd, struct stat *st) ...@@ -102,7 +108,8 @@ sys_fstat(int fd, struct stat *st)
} }
// Create the path new as a link to the same inode as old. // Create the path new as a link to the same inode as old.
long //SYSCALL
int
sys_link(const char *old, const char *newn) sys_link(const char *old, const char *newn)
{ {
char name[DIRSIZ]; char name[DIRSIZ];
...@@ -155,7 +162,8 @@ isdirempty(struct inode *dp) ...@@ -155,7 +162,8 @@ isdirempty(struct inode *dp)
return empty; return empty;
} }
long //SYSCALL
int
sys_unlink(const char *path) sys_unlink(const char *path)
{ {
struct inode *ip, *dp; struct inode *ip, *dp;
...@@ -266,7 +274,8 @@ create(inode *cwd, const char *path, short type, short major, short minor) ...@@ -266,7 +274,8 @@ create(inode *cwd, const char *path, short type, short major, short minor)
return ip; return ip;
} }
long //SYSCALL
int
sys_openat(int dirfd, const char *path, int omode) sys_openat(int dirfd, const char *path, int omode)
{ {
int fd; int fd;
...@@ -363,7 +372,8 @@ sys_openat(int dirfd, const char *path, int omode) ...@@ -363,7 +372,8 @@ sys_openat(int dirfd, const char *path, int omode)
return fd; return fd;
} }
long //SYSCALL
int
sys_mkdirat(int dirfd, const char *path) sys_mkdirat(int dirfd, const char *path)
{ {
struct inode *cwd; struct inode *cwd;
...@@ -388,7 +398,8 @@ sys_mkdirat(int dirfd, const char *path) ...@@ -388,7 +398,8 @@ sys_mkdirat(int dirfd, const char *path)
return 0; return 0;
} }
long //SYSCALL
int
sys_mknod(const char *path, int major, int minor) sys_mknod(const char *path, int major, int minor)
{ {
struct inode *ip; struct inode *ip;
...@@ -401,7 +412,8 @@ sys_mknod(const char *path, int major, int minor) ...@@ -401,7 +412,8 @@ sys_mknod(const char *path, int major, int minor)
return 0; return 0;
} }
long //SYSCALL
int
sys_chdir(const char *path) sys_chdir(const char *path)
{ {
struct inode *ip; struct inode *ip;
...@@ -419,8 +431,9 @@ sys_chdir(const char *path) ...@@ -419,8 +431,9 @@ sys_chdir(const char *path)
return 0; return 0;
} }
long //SYSCALL INT
sys_exec(const char *upath, u64 uargv) int
sys_exec(const char *upath, userptr<userptr<const char> > uargv)
{ {
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
static const int len = 32; static const int len = 32;
...@@ -456,7 +469,8 @@ clean: ...@@ -456,7 +469,8 @@ clean:
return r; return r;
} }
long //SYSCALL
int
sys_pipe(int *fd) sys_pipe(int *fd)
{ {
struct file *rf, *wf; struct file *rf, *wf;
...@@ -522,7 +536,8 @@ allocsocket(struct file **rf, int *rfd) ...@@ -522,7 +536,8 @@ allocsocket(struct file **rf, int *rfd)
return 0; return 0;
} }
long //SYSCALL
int
sys_socket(int domain, int type, int protocol) sys_socket(int domain, int type, int protocol)
{ {
extern long netsocket(int domain, int type, int protocol); extern long netsocket(int domain, int type, int protocol);
...@@ -543,10 +558,11 @@ sys_socket(int domain, int type, int protocol) ...@@ -543,10 +558,11 @@ sys_socket(int domain, int type, int protocol)
return fd; return fd;
} }
long //SYSCALL
sys_bind(int xsock, void *xaddr, int xaddrlen) int
sys_bind(int xsock, const struct sockaddr *xaddr, int xaddrlen)
{ {
extern long netbind(int, void*, int); extern long netbind(int, const struct sockaddr*, int);
sref<file> f; sref<file> f;
if (!getsocket(xsock, &f)) if (!getsocket(xsock, &f))
...@@ -555,7 +571,8 @@ sys_bind(int xsock, void *xaddr, int xaddrlen) ...@@ -555,7 +571,8 @@ sys_bind(int xsock, void *xaddr, int xaddrlen)
return netbind(f->socket, xaddr, xaddrlen); return netbind(f->socket, xaddr, xaddrlen);
} }
long //SYSCALL
int
sys_listen(int xsock, int backlog) sys_listen(int xsock, int backlog)
{ {
extern long netlisten(int, int); extern long netlisten(int, int);
...@@ -567,10 +584,11 @@ sys_listen(int xsock, int backlog) ...@@ -567,10 +584,11 @@ sys_listen(int xsock, int backlog)
return netlisten(f->socket, backlog); return netlisten(f->socket, backlog);
} }
long //SYSCALL
sys_accept(int xsock, void *xaddr, void *xaddrlen) int
sys_accept(int xsock, struct sockaddr *xaddr, int *xaddrlen)
{ {
extern long netaccept(int, void*, void*); extern long netaccept(int, struct sockaddr*, int*);
file *cf; file *cf;
sref<file> f; sref<file> f;
int cfd; int cfd;
......
...@@ -12,50 +12,57 @@ ...@@ -12,50 +12,57 @@
#include "kmtrace.hh" #include "kmtrace.hh"
#include "futex.h" #include "futex.h"
long //SYSCALL
int
sys_fork(int flags) sys_fork(int flags)
{ {
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
return fork(flags); return fork(flags);
} }
long //SYSCALL NORET
int
sys_exit(void) sys_exit(void)
{ {
exit(); exit();
return 0; // not reached panic("exit() returned");
} }
long //SYSCALL
int
sys_wait(void) sys_wait(void)
{ {
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
return wait(); return wait();
} }
long //SYSCALL
int
sys_kill(int pid) sys_kill(int pid)
{ {
return proc::kill(pid); return proc::kill(pid);
} }
long //SYSCALL
int
sys_getpid(void) sys_getpid(void)
{ {
return myproc()->pid; return myproc()->pid;
} }
long //SYSCALL
char*
sys_sbrk(int n) sys_sbrk(int n)
{ {
uptr addr; uptr addr;
if(myproc()->vmap->sbrk(n, &addr) < 0) if(myproc()->vmap->sbrk(n, &addr) < 0)
return -1; return (char*)-1;
return addr; return (char*)addr;
} }
long //SYSCALL
int
sys_nsleep(u64 nsec) sys_nsleep(u64 nsec)
{ {
struct spinlock lock; struct spinlock lock;
...@@ -83,14 +90,16 @@ sys_nsleep(u64 nsec) ...@@ -83,14 +90,16 @@ sys_nsleep(u64 nsec)
// return how many clock tick interrupts have occurred // return how many clock tick interrupts have occurred
// since boot. // since boot.
long //SYSCALL
u64
sys_uptime(void) sys_uptime(void)
{ {
return nsectime(); return nsectime();
} }
long //SYSCALL
sys_map(uptr addr, u64 len) int
sys_map(userptr<void> addr, size_t len)
{ {
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
...@@ -114,8 +123,9 @@ sys_map(uptr addr, u64 len) ...@@ -114,8 +123,9 @@ sys_map(uptr addr, u64 len)
return r; return r;
} }
long //SYSCALL
sys_unmap(uptr addr, u64 len) int
sys_unmap(userptr<void> addr, size_t len)
{ {
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
...@@ -134,18 +144,16 @@ sys_unmap(uptr addr, u64 len) ...@@ -134,18 +144,16 @@ sys_unmap(uptr addr, u64 len)
return 0; return 0;
} }
long //SYSCALL
int
sys_halt(void) sys_halt(void)
{ {
int i; halt();
const char s[] = "Shutdown"; panic("halt returned");
for(i = 0; i < 8; i++)
outb(0x8900, s[i]);
return 0;
} }
long //SYSCALL
int
sys_setfs(u64 base) sys_setfs(u64 base)
{ {
proc *p = myproc(); proc *p = myproc();
...@@ -154,12 +162,14 @@ sys_setfs(u64 base) ...@@ -154,12 +162,14 @@ sys_setfs(u64 base)
return 0; return 0;
} }
long //SYSCALL
int
sys_setaffinity(int cpu) sys_setaffinity(int cpu)
{ {
return myproc()->set_cpu_pin(cpu); return myproc()->set_cpu_pin(cpu);
} }
//SYSCALL
long long
sys_futex(const u64* addr, int op, u64 val, u64 timer) sys_futex(const u64* addr, int op, u64 val, u64 timer)
{ {
......
...@@ -52,7 +52,8 @@ uwq_trywork(void) ...@@ -52,7 +52,8 @@ uwq_trywork(void)
return false; return false;
} }
long //SYSCALL
int
sys_wqwait(void) sys_wqwait(void)
{ {
uwq_worker* w = myproc()->worker; uwq_worker* w = myproc()->worker;
......
$(O)/lib/%.o: CFLAGS:=$(CFLAGS) -DXV6_USER $(O)/lib/%.o: CFLAGS:=$(CFLAGS) -DXV6_USER
$(O)/lib/%.o: CXXFLAGS:=$(CXXFLAGS) -DXV6_USER -fno-exceptions -fno-rtti $(O)/lib/%.o: CXXFLAGS:=$(CXXFLAGS) -DXV6_USER -fno-exceptions -fno-rtti
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \ ULIB = ulib.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \
threads.o crt.o wqlib.o wquser.o perf.o wqalloc.o threads.o crt.o wqlib.o wquser.o perf.o wqalloc.o sysstubs.o
ULIB := $(addprefix $(O)/lib/, $(ULIB)) ULIB := $(addprefix $(O)/lib/, $(ULIB))
$(O)/lib/sysstubs.S: tools/syscalls.py kernel/*.cc
@echo " GEN $@"
$(Q)mkdir -p $(@D)
$(Q)python $^ --ustubs > $@
$(O)/include/sysstubs.h: tools/syscalls.py kernel/*.cc
@echo " GEN $@"
$(Q)mkdir -p $(@D)
$(Q)python $^ --udecls > $@
.PRECIOUS: $(O)/lib/%.o .PRECIOUS: $(O)/lib/%.o
-include $(O)/lib/*.d -include $(O)/lib/*.d
#include "syscall.h"
#include "traps.h"
#define SYSCALL_INT(name) \
.globl name; \
name: \
movq $SYS_ ## name, %rax; \
int $T_SYSCALL; \
ret
#define SYSCALL(name) \
.globl name; \
name: \
movq $SYS_ ## name, %rax; \
movq %rcx, %r10; \
syscall; \
ret
SYSCALL(fork)
SYSCALL(exit)
SYSCALL(wait)
SYSCALL(pipe)
SYSCALL(read)
SYSCALL(write)
SYSCALL(close)
SYSCALL(kill)
SYSCALL_INT(exec)
SYSCALL(openat)
SYSCALL(mknod)
SYSCALL(unlink)
SYSCALL(fstat)
SYSCALL(link)
SYSCALL(mkdirat)
SYSCALL(chdir)
SYSCALL(dup)
SYSCALL(getpid)
SYSCALL(sbrk)
SYSCALL(nsleep)
SYSCALL(uptime)
SYSCALL(map)
SYSCALL(unmap)
SYSCALL(halt)
SYSCALL(socket)
SYSCALL(bind)
SYSCALL(listen)
SYSCALL(accept)
SYSCALL(pread)
SYSCALL(async)
SYSCALL(script)
SYSCALL(setfs)
SYSCALL(wqwait)
SYSCALL(setaffinity)
SYSCALL(futex)
#include "syscall.h"
#include "traps.h"
# We assume that the kernel follows the amd64 ABI, but not # We assume that the kernel follows the amd64 ABI, but not
# that it saves caller-saved registers. # that it saves caller-saved registers.
.globl forkt .globl forkt
......
...@@ -14,8 +14,6 @@ static std::atomic<int> nextid; ...@@ -14,8 +14,6 @@ static std::atomic<int> nextid;
static wq *wq_; static wq *wq_;
extern "C" long wqwait(void);
static void __attribute__((used)) static void __attribute__((used))
initworker(void) initworker(void)
{ {
......
from optparse import OptionParser
import sys, re
def main():
parser = OptionParser(usage="usage: %prog [options] source...")
parser.add_option("--kvectors", action="store_true",
help="output kernel syscall vectors")
parser.add_option("--ustubs", action="store_true",
help="output user syscall stubs")
parser.add_option("--udecls", action="store_true",
help="output user syscall declarations")
(options, args) = parser.parse_args()
if len(args) < 1:
parser.print_help()
parser.exit()
# Parse source files
syscalls = []
for fname in args:
syscalls.extend(parse(file(fname, "r")))
# Generate syscall numbers
for n, syscall in enumerate(syscalls):
syscall.num = n + 1
# Output
if options.kvectors:
print "#include \"types.h\""
print "#include \"userptr.hh\""
print
for syscall in syscalls:
print "extern %s %s(%s);" % (syscall.rettype, syscall.kname,
", ".join(syscall.kargs))
print
print "u64 (*syscalls[])(u64, u64, u64, u64, u64) = {"
bynum = dict((s.num, s) for s in syscalls)
for num in range(max(bynum.keys()) + 1):
if num not in bynum:
print " nullptr,"
else:
print " (u64(*)(u64,u64,u64,u64,u64))%s," % bynum[num].kname
print "};"
print
print "extern const int nsyscalls = %d;" % (max(bynum.keys()) + 1)
if options.ustubs:
print "#include \"traps.h\""
print
for syscall in syscalls:
print """\
.globl SYS_%(uname)s
SYS_%(uname)s = %(num)d
.globl %(uname)s
%(uname)s:
movq $%(num)d, %%rax""" % syscall.__dict__
if "INT" in syscall.flags:
print " int $T_SYSCALL"
else:
print " movq %rcx, %r10\n syscall"
print " ret"
print
if options.udecls:
for syscall in syscalls:
extra = ""
if "NORET" in syscall.flags:
extra = " __attribute__((noreturn))"
print "%s %s(%s)%s;" % (syscall.rettype, syscall.uname,
", ".join(syscall.uargs), extra)
class Syscall(object):
def __init__(self, kname, rettype, kargs, flags, num=None):
self.kname, self.rettype, self.kargs, self.flags, self.num = \
kname, rettype, kargs, flags, num
self.basename = kname[4:]
# Construct user space prototype
self.uname = self.basename
uargs = []
for karg in kargs:
m = re.match("(.*?) *[a-z_]+$", karg)
atype = m.group(1)
while True:
atype2 = re.sub("userptr<(.*)>", r"\1*", atype)
if atype2 == atype:
break
atype = atype2
uargs.append(atype)
self.uargs = uargs
def __repr__(self):
return "Syscall(%r,%r,%r,%r,%r)" % (
self.kname, self.rettype, self.kargs, self.flags, self.num)
class ParseError(RuntimeError):
def __init__(self, fname, msg):
RuntimeError.__init__(self, "%s: %s" % (fname, msg))
def parse(fp):
res = []
for flags, proto in re.findall(r"//SYSCALL(.*)([^{]*)", fp.read()):
# Parse the prototype
proto = " ".join(proto.split())
m = re.match(r"(.+) ([a-z_]+) *\(([^)]+)\)", proto)
if not m:
raise ParseError(fp.name, "could not parse prototype %r" % proto)
rettype, name, kargs = m.groups()
kargs = re.split(" *, *", kargs)
res.append(Syscall(name, rettype, kargs, flags.split()))
return res
if __name__ == "__main__":
main()
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论