diff options
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | Notes | 2 | ||||
| -rw-r--r-- | echo.c | 14 | ||||
| -rw-r--r-- | mkfs.c | 5 | ||||
| -rw-r--r-- | syscall.c | 70 | ||||
| -rw-r--r-- | userfs.c | 3 | ||||
| -rw-r--r-- | usertests.c | 2 | 
7 files changed, 89 insertions, 17 deletions
| @@ -66,6 +66,10 @@ usertests : usertests.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB)  	$(OBJDUMP) -S usertests > usertests.asm +echo : echo.o $(ULIB) +	$(LD) -N -e main -Ttext 0 -o echo echo.o $(ULIB) +	$(OBJDUMP) -S echo > echo.asm +  userfs : userfs.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)  	$(OBJDUMP) -S userfs > userfs.asm @@ -73,12 +77,12 @@ userfs : userfs.o $(ULIB)  mkfs : mkfs.c fs.h  	cc -o mkfs mkfs.c -fs.img : mkfs usertests -	./mkfs fs.img usertests +fs.img : mkfs usertests echo +	./mkfs fs.img usertests echo  -include *.d  clean :   	rm -f *.o *.d *.asm vectors.S parport.out \  		bootblock kernel xv6.img user1 userfs usertests \ -		fs.img mkfs +		fs.img mkfs echo @@ -161,3 +161,5 @@ need to lock bufs in bio between bread and brelse  test 14-character file names  and file arguments longer than 14  and directories longer than one sector + +kalloc() can return 0; do callers handle this right? @@ -0,0 +1,14 @@ +#include "user.h" + +int +main(int argc, char *argv[]) +{ +  int i; + +  for(i = 0; i < argc; i++){ +    puts(argv[i]); +    puts(" "); +  } +  puts("\n"); +  exit(); +} @@ -144,11 +144,6 @@ winode(uint inum, struct dinode *ip)    dip = ((struct dinode *) buf) + (inum % IPB);    *dip = *ip;    wsect(bn, buf); -  printf("wi %d size %d addrs %d %d...\n", -         inum, -         xint(dip->size), -         xint(dip->addrs[0]), -         xint(dip->addrs[1]));  }  void @@ -58,17 +58,20 @@ fetcharg(int argno, void *ip)    return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);  } -// check that an entire string is valid in user space +// check that an entire string is valid in user space. +// returns the length, not including null, or -1.  int  checkstring(uint s)  {    char c; +  int len = 0;    while(1){      if(fetchbyte(curproc[cpu()], s, &c) < 0)        return -1;      if(c == '\0') -      return 0; +      return len; +    len++;      s++;    }  } @@ -244,14 +247,17 @@ int  sys_exec(void)  {    struct proc *cp = curproc[cpu()]; -  uint arg0, sz; -  int i; +  uint arg0, arg1, sz=0, ap, sp, p1, p2; +  int i, nargs, argbytes, len;    struct inode *ip;    struct elfhdr elf;    struct proghdr ph; +  char *mem = 0;    if(fetcharg(0, &arg0) < 0)      return -1; +  if(fetcharg(1, &arg1) < 0) +    return -1;    if(checkstring(arg0) < 0)      return -1;    ip = namei(cp->mem + arg0); @@ -278,14 +284,62 @@ sys_exec(void)    sz += 4096 - (sz % 4096);    sz += 4096; +  mem = kalloc(sz); +  if(mem == 0) +    goto bad; +  memset(mem, 0, sz); + +  // arg1 is a pointer to an array of pointers to string. +  nargs = 0; +  argbytes = 0; +  for(i = 0; ; i++){ +    if(fetchint(cp, arg1 + 4*i, &ap) < 0) +      goto bad; +    if(ap == 0) +      break; +    len = checkstring(ap); +    if(len < 0) +      goto bad; +    nargs++; +    argbytes += len + 1; +  } + +  // argn\0 +  // ... +  // arg0\0 +  // 0 +  // ptr to argn +  // ... +  // 12: ptr to arg0 +  //  8: argv (points to ptr to arg0) +  //  4: argc +  //  0: fake return pc +  sp = sz - argbytes - (nargs+1)*4 - 4 - 4 - 4; +  *(uint*)(mem + sp) = 0xffffffff; +  *(uint*)(mem + sp + 4) = nargs; +  *(uint*)(mem + sp + 8) = (uint)(sp + 12); + +  p1 = sp + 12; +  p2 = sp + 12 + (nargs + 1) * 4; +  for(i = 0; i < nargs; i++){ +    fetchint(cp, arg1 + 4*i, &ap); +    len = checkstring(ap); +    memmove(mem + p2, cp->mem + ap, len + 1); +    *(uint*)(mem + p1) = p2; +    p1 += 4; +    p2 += len + 1; +  } +  *(uint*)(mem + p1) = 0; +    // commit to the new image.    kfree(cp->mem, cp->sz);    cp->sz = sz; -  cp->mem = kalloc(cp->sz); +  cp->mem = mem; +  mem = 0;    for(i = 0; i < elf.phnum; i++){      if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph)) -      goto bad; +      goto bad2;      if(ph.type != ELF_PROG_LOAD)        continue;      if(ph.va + ph.memsz > sz) @@ -298,13 +352,15 @@ sys_exec(void)    iput(ip);    cp->tf->eip = elf.entry; -  cp->tf->esp = cp->sz; +  cp->tf->esp = sp;    setupsegs(cp);    return 0;   bad:    cprintf("exec failed early\n"); +  if(mem) +    kfree(mem, sz);    iput(ip);    return -1; @@ -3,12 +3,13 @@  // file system tests  char buf[1024]; +char *args[] = { "echo", "hello", "goodbye", 0 };  int  main(void)  {    puts("userfs running\n");    block(); -  exec("usertests"); +  exec("echo", args);    return 0;  } diff --git a/usertests.c b/usertests.c index 370054b..cba362f 100644 --- a/usertests.c +++ b/usertests.c @@ -115,7 +115,7 @@ exitwait(void)  }  int -main(void) +main(int argc, char *argv[])  {    puts("usertests starting\n"); | 
