提交 7bbae2fb 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

The start of syscalls.

上级 bcd91944
...@@ -4,6 +4,7 @@ OBJS = \ ...@@ -4,6 +4,7 @@ OBJS = \
cga.o \ cga.o \
condvar.o \ condvar.o \
console.o \ console.o \
exec.o \
file.o \ file.o \
fs.o \ fs.o \
lapic.o \ lapic.o \
...@@ -18,6 +19,8 @@ OBJS = \ ...@@ -18,6 +19,8 @@ OBJS = \
spinlock.o \ spinlock.o \
swtch.o \ swtch.o \
string.o \ string.o \
syscall.o \
sysfile.o \
uart.o \ uart.o \
vm.o \ vm.o \
trap.o \ trap.o \
......
...@@ -6,16 +6,22 @@ ...@@ -6,16 +6,22 @@
#include "condvar.h" #include "condvar.h"
#include "queue.h" #include "queue.h"
#include "proc.h" #include "proc.h"
#include "defs.h" #include "kernel.h"
#include "x86.h" #include "x86.h"
#include "elf.h"
#include "stat.h" #include "stat.h"
#include "fs.h" #include "fs.h"
#include "file.h" #include "file.h"
#if 0
#include "elf.h"
#endif
int int
exec(char *path, char **argv) exec(char *path, char **argv)
{ {
panic("exec");
return 0;
#if 0
char *s, *last; char *s, *last;
int i, off, brk = 0; int i, off, brk = 0;
uint argc, sp, ustack[3+MAXARG+1]; uint argc, sp, ustack[3+MAXARG+1];
...@@ -149,4 +155,5 @@ exec(char *path, char **argv) ...@@ -149,4 +155,5 @@ exec(char *path, char **argv)
vmn_free(vmn); vmn_free(vmn);
rcu_end_read(); rcu_end_read();
return -1; return -1;
#endif
} }
...@@ -46,6 +46,9 @@ void cprintf(const char*, ...); ...@@ -46,6 +46,9 @@ void cprintf(const char*, ...);
void panic(const char*) __attribute__((noreturn)); void panic(const char*) __attribute__((noreturn));
void snprintf(char *buf, u32 n, char *fmt, ...); void snprintf(char *buf, u32 n, char *fmt, ...);
// exec.c
int exec(char*, char**);
// file.c // file.c
struct file* filealloc(void); struct file* filealloc(void);
void fileclose(struct file*); void fileclose(struct file*);
...@@ -57,6 +60,8 @@ int filewrite(struct file*, char*, int n); ...@@ -57,6 +60,8 @@ int filewrite(struct file*, char*, int n);
// fs.c // fs.c
int namecmp(const char*, const char*); int namecmp(const char*, const char*);
struct inode* dirlookup(struct inode*, char*);
struct inode* ialloc(u32, short);
struct inode* namei(char*); struct inode* namei(char*);
void iput(struct inode*); void iput(struct inode*);
struct inode* iget(u32 dev, u32 inum); struct inode* iget(u32 dev, u32 inum);
...@@ -68,6 +73,10 @@ int readi(struct inode*, char*, u32, u32); ...@@ -68,6 +73,10 @@ int readi(struct inode*, char*, u32, u32);
void stati(struct inode*, struct stat*); void stati(struct inode*, struct stat*);
int writei(struct inode*, char*, u32, u32); int writei(struct inode*, char*, u32, u32);
struct inode* idup(struct inode*); struct inode* idup(struct inode*);
struct inode* nameiparent(char*, char*);
int dirlink(struct inode*, char*, u32);
void dir_init(struct inode *dp);
void dir_flush(struct inode *dp);
// ide.c // ide.c
void ideinit(void); void ideinit(void);
...@@ -176,6 +185,15 @@ void release(struct spinlock*); ...@@ -176,6 +185,15 @@ void release(struct spinlock*);
void pushcli(void); void pushcli(void);
void popcli(void); void popcli(void);
// syscall.c
int argint64(int, u64*);
int argint32(int n, int *ip);
int argptr(int, char**, int);
int argstr(int, char**);
int fetchint64(uptr, u64*);
int fetchstr(uptr, char**);
void syscall(void);
// string.c // string.c
int memcmp(const void*, const void*, u32); int memcmp(const void*, const void*, u32);
void* memmove(void*, const void*, u32); void* memmove(void*, const void*, u32);
......
#include "types.h" #include "types.h"
#include "defs.h"
#include "param.h" #include "param.h"
#include "memlayout.h" #include "memlayout.h"
#include "mmu.h" #include "mmu.h"
#include "kernel.h"
#include "spinlock.h" #include "spinlock.h"
#include "condvar.h" #include "condvar.h"
#include "queue.h" #include "queue.h"
#include "proc.h" #include "proc.h"
#include "x86.h" #include "x86.h"
#include "syscall.h" #include "syscall.h"
#include "xv6-kmtrace.h" #include "xv6-mtrace.h"
#include "cpu.h"
// User code makes a system call with INT T_SYSCALL. // User code makes a system call with INT T_SYSCALL.
// System call number in %eax. // System call number in %eax.
...@@ -19,13 +20,13 @@ ...@@ -19,13 +20,13 @@
// Fetch the int at addr from process p. // Fetch the int at addr from process p.
int int
fetchint(uint addr, int *ip) fetchint64(uptr addr, u64 *ip)
{ {
if(pagefault(proc->vmap, addr, 0) < 0) if(pagefault(myproc()->vmap, addr, 0) < 0)
return -1; return -1;
if(pagefault(proc->vmap, addr+3, 0) < 0) if(pagefault(myproc()->vmap, addr+sizeof(*ip)-1, 0) < 0)
return -1; return -1;
*ip = *(int*)(addr); *ip = *(u64*)(addr);
return 0; return 0;
} }
...@@ -33,12 +34,12 @@ fetchint(uint addr, int *ip) ...@@ -33,12 +34,12 @@ fetchint(uint addr, int *ip)
// Doesn't actually copy the string - just sets *pp to point at it. // Doesn't actually copy the string - just sets *pp to point at it.
// Returns length of string, not including nul. // Returns length of string, not including nul.
int int
fetchstr(uint addr, char **pp) fetchstr(uptr addr, char **pp)
{ {
char *s = (char *) addr; char *s = (char *) addr;
while(1){ while(1){
if(pagefault(proc->vmap, (uint) s, 0) < 0) if(pagefault(myproc()->vmap, (uptr) s, 0) < 0)
return -1; return -1;
if(*s == 0){ if(*s == 0){
*pp = (char*)addr; *pp = (char*)addr;
...@@ -49,11 +50,23 @@ fetchstr(uint addr, char **pp) ...@@ -49,11 +50,23 @@ fetchstr(uint addr, char **pp)
return -1; return -1;
} }
// Fetch the nth 32-bit system call argument. // Fetch the nth 64-bit system call argument.
int int
argint(int n, int *ip) argint64(int n, u64 *ip)
{ {
return fetchint(proc->tf->esp + 4 + 4*n, ip); return fetchint64(myproc()->tf->rsp + 8 + 8*n, ip);
}
int
argint32(int n, int *ip)
{
int r;
u64 i;
r = fetchint64(myproc()->tf->rsp + 8 + 8*n, &i);
if (r > 0)
*ip = i;
return r;
} }
// Fetch the nth word-sized system call argument as a pointer // Fetch the nth word-sized system call argument as a pointer
...@@ -62,12 +75,12 @@ argint(int n, int *ip) ...@@ -62,12 +75,12 @@ argint(int n, int *ip)
int int
argptr(int n, char **pp, int size) argptr(int n, char **pp, int size)
{ {
int i; u64 i;
if(argint(n, &i) < 0) if(argint64(n, &i) < 0)
return -1; return -1;
for(uint va = PGROUNDDOWN(i); va < i+size; va = va + PGSIZE) for(uptr va = PGROUNDDOWN(i); va < i+size; va = va + PGSIZE)
if(pagefault(proc->vmap, va, 0) < 0) if(pagefault(myproc()->vmap, va, 0) < 0)
return -1; return -1;
*pp = (char*)i; *pp = (char*)i;
return 0; return 0;
...@@ -80,8 +93,8 @@ argptr(int n, char **pp, int size) ...@@ -80,8 +93,8 @@ argptr(int n, char **pp, int size)
int int
argstr(int n, char **pp) argstr(int n, char **pp)
{ {
int addr; uptr addr;
if(argint(n, &addr) < 0) if(argint64(n, &addr) < 0)
return -1; return -1;
return fetchstr(addr, pp); return fetchstr(addr, pp);
} }
...@@ -112,10 +125,13 @@ extern int sys_unmap(void); ...@@ -112,10 +125,13 @@ extern int sys_unmap(void);
extern int sys_halt(void); extern int sys_halt(void);
static int (*syscalls[])(void) = { static int (*syscalls[])(void) = {
[SYS_chdir] sys_chdir, #if 0
[SYS_close] sys_close, [SYS_chdir] = sys_chdir,
[SYS_dup] sys_dup, [SYS_close] = sys_close,
[SYS_exec] sys_exec, [SYS_dup] = sys_dup,
#endif
[SYS_exec] = sys_exec,
#if 0
[SYS_exit] sys_exit, [SYS_exit] sys_exit,
[SYS_fork] sys_fork, [SYS_fork] sys_fork,
[SYS_fstat] sys_fstat, [SYS_fstat] sys_fstat,
...@@ -136,6 +152,7 @@ static int (*syscalls[])(void) = { ...@@ -136,6 +152,7 @@ static int (*syscalls[])(void) = {
[SYS_map] sys_map, [SYS_map] sys_map,
[SYS_unmap] sys_unmap, [SYS_unmap] sys_unmap,
[SYS_halt] sys_halt, [SYS_halt] sys_halt,
#endif
}; };
void void
...@@ -143,16 +160,16 @@ syscall(void) ...@@ -143,16 +160,16 @@ syscall(void)
{ {
int num; int num;
num = proc->tf->eax; num = myproc()->tf->rax;
if(num >= 0 && num < NELEM(syscalls) && syscalls[num]) { if(num >= 0 && num < NELEM(syscalls) && syscalls[num]) {
mtrace_kstack_start(syscalls[num], proc); mtrace_kstack_start(syscalls[num], proc);
mtrace_call_set(1, cpunum()); mtrace_call_set(1, cpunum());
proc->tf->eax = syscalls[num](); myproc()->tf->rax = syscalls[num]();
mtrace_kstack_stop(proc); mtrace_kstack_stop(myproc());
mtrace_call_set(0, cpunum()); mtrace_call_set(0, cpunum());
} else { } else {
cprintf("%d %s: unknown sys call %d\n", cprintf("%d %s: unknown sys call %d\n",
proc->pid, proc->name, num); myproc()->pid, myproc()->name, num);
proc->tf->eax = -1; myproc()->tf->rax = -1;
} }
} }
#include "types.h" #include "types.h"
#include "defs.h"
#include "param.h" #include "param.h"
#include "stat.h" #include "stat.h"
#include "mmu.h" #include "mmu.h"
#include "kernel.h"
#include "spinlock.h" #include "spinlock.h"
#include "condvar.h" #include "condvar.h"
#include "queue.h" #include "queue.h"
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "fs.h" #include "fs.h"
#include "file.h" #include "file.h"
#include "fcntl.h" #include "fcntl.h"
#include "cpu.h"
// Fetch the nth word-sized system call argument as a file descriptor // Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file. // and return both the descriptor and the corresponding struct file.
...@@ -19,9 +20,9 @@ argfd(int n, int *pfd, struct file **pf) ...@@ -19,9 +20,9 @@ argfd(int n, int *pfd, struct file **pf)
int fd; int fd;
struct file *f; struct file *f;
if(argint(n, &fd) < 0) if(argint32(n, &fd) < 0)
return -1; return -1;
if(fd < 0 || fd >= NOFILE || (f=proc->ofile[fd]) == 0) if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1; return -1;
if(pfd) if(pfd)
*pfd = fd; *pfd = fd;
...@@ -38,8 +39,8 @@ fdalloc(struct file *f) ...@@ -38,8 +39,8 @@ fdalloc(struct file *f)
int fd; int fd;
for(fd = 0; fd < NOFILE; fd++){ for(fd = 0; fd < NOFILE; fd++){
if(proc->ofile[fd] == 0){ if(myproc()->ofile[fd] == 0){
proc->ofile[fd] = f; myproc()->ofile[fd] = f;
return fd; return fd;
} }
} }
...@@ -67,7 +68,7 @@ sys_read(void) ...@@ -67,7 +68,7 @@ sys_read(void)
int n; int n;
char *p; char *p;
if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) if(argfd(0, 0, &f) < 0 || argint32(2, &n) < 0 || argptr(1, &p, n) < 0)
return -1; return -1;
return fileread(f, p, n); return fileread(f, p, n);
} }
...@@ -79,7 +80,7 @@ sys_write(void) ...@@ -79,7 +80,7 @@ sys_write(void)
int n; int n;
char *p; char *p;
if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) if(argfd(0, 0, &f) < 0 || argint32(2, &n) < 0 || argptr(1, &p, n) < 0)
return -1; return -1;
return filewrite(f, p, n); return filewrite(f, p, n);
} }
...@@ -92,7 +93,7 @@ sys_close(void) ...@@ -92,7 +93,7 @@ sys_close(void)
if(argfd(0, &fd, &f) < 0) if(argfd(0, &fd, &f) < 0)
return -1; return -1;
proc->ofile[fd] = 0; myproc()->ofile[fd] = 0;
fileclose(f); fileclose(f);
return 0; return 0;
} }
...@@ -200,7 +201,7 @@ sys_unlink(void) ...@@ -200,7 +201,7 @@ sys_unlink(void)
} }
dir_init(dp); dir_init(dp);
if (ns_remove(dp->dir, KD(name), (void*)ip->inum) == 0) { if (ns_remove(dp->dir, KD(name), (void*)(u64)ip->inum) == 0) {
iunlockput(ip); iunlockput(ip);
goto retry; goto retry;
} }
...@@ -279,7 +280,7 @@ sys_open(void) ...@@ -279,7 +280,7 @@ sys_open(void)
struct file *f; struct file *f;
struct inode *ip; struct inode *ip;
if(argstr(0, &path) < 0 || argint(1, &omode) < 0) if(argstr(0, &path) < 0 || argint32(1, &omode) < 0)
return -1; return -1;
if(omode & O_CREATE){ if(omode & O_CREATE){
if((ip = create(path, T_FILE, 0, 0)) == 0) if((ip = create(path, T_FILE, 0, 0)) == 0)
...@@ -340,8 +341,8 @@ sys_mknod(void) ...@@ -340,8 +341,8 @@ sys_mknod(void)
int major, minor; int major, minor;
if((len=argstr(0, &path)) < 0 || if((len=argstr(0, &path)) < 0 ||
argint(1, &major) < 0 || argint32(1, &major) < 0 ||
argint(2, &minor) < 0 || argint32(2, &minor) < 0 ||
(ip = create(path, T_DEV, major, minor)) == 0) (ip = create(path, T_DEV, major, minor)) == 0)
return -1; return -1;
iunlockput(ip); iunlockput(ip);
...@@ -362,8 +363,8 @@ sys_chdir(void) ...@@ -362,8 +363,8 @@ sys_chdir(void)
return -1; return -1;
} }
iunlock(ip); iunlock(ip);
iput(proc->cwd); iput(myproc()->cwd);
proc->cwd = ip; myproc()->cwd = ip;
return 0; return 0;
} }
...@@ -372,16 +373,17 @@ sys_exec(void) ...@@ -372,16 +373,17 @@ sys_exec(void)
{ {
char *path, *argv[MAXARG]; char *path, *argv[MAXARG];
int i; int i;
uint uargv, uarg; uptr uargv;
u64 uarg;
if(argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0){ if(argstr(0, &path) < 0 || argint64(1, &uargv) < 0){
return -1; return -1;
} }
memset(argv, 0, sizeof(argv)); memset(argv, 0, sizeof(argv));
for(i=0;; i++){ for(i=0;; i++){
if(i >= NELEM(argv)) if(i >= NELEM(argv))
return -1; return -1;
if(fetchint(uargv+4*i, (int*)&uarg) < 0) if(fetchint64(uargv+8*i, &uarg) < 0)
return -1; return -1;
if(uarg == 0){ if(uarg == 0){
argv[i] = 0; argv[i] = 0;
...@@ -407,7 +409,7 @@ sys_pipe(void) ...@@ -407,7 +409,7 @@ sys_pipe(void)
fd0 = -1; fd0 = -1;
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){ if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){
if(fd0 >= 0) if(fd0 >= 0)
proc->ofile[fd0] = 0; myproc()->ofile[fd0] = 0;
fileclose(rf); fileclose(rf);
fileclose(wf); fileclose(wf);
return -1; return -1;
......
...@@ -50,19 +50,16 @@ trap(struct trapframe *tf) ...@@ -50,19 +50,16 @@ trap(struct trapframe *tf)
// XXX(sbw) sysenter/sysexit // XXX(sbw) sysenter/sysexit
if(tf->trapno == T_SYSCALL){ if(tf->trapno == T_SYSCALL){
panic("syscall.."); if(myproc()->killed) {
#if 0
if(proc->killed) {
mtrace_kstack_start(trap, proc); mtrace_kstack_start(trap, proc);
exit(); exit();
} }
proc->tf = tf; myproc()->tf = tf;
syscall(); syscall();
if(proc->killed) { if(myproc()->killed) {
mtrace_kstack_start(trap, proc); mtrace_kstack_start(trap, myproc());
exit(); exit();
} }
#endif
return; return;
} }
......
...@@ -470,7 +470,7 @@ pagefault_wcow(struct vmap *vmap, uptr va, pme_t *pte, struct vma *m, u64 npg) ...@@ -470,7 +470,7 @@ pagefault_wcow(struct vmap *vmap, uptr va, pme_t *pte, struct vma *m, u64 npg)
} }
int int
pagefault(struct vmap *vmap, u64 va, u32 err) pagefault(struct vmap *vmap, uptr va, u32 err)
{ {
pme_t *pte = walkpgdir(vmap->pml4, (const void *)va, 1); pme_t *pte = walkpgdir(vmap->pml4, (const void *)va, 1);
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论