file descriptors
pipes
This commit is contained in:
parent
b61c2547b8
commit
c41f1de5d4
16 changed files with 424 additions and 39 deletions
18
Makefile
18
Makefile
|
@ -1,5 +1,5 @@
|
||||||
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
|
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
|
||||||
syscall.o ide.o picirq.o mp.o spinlock.o
|
syscall.o ide.o picirq.o mp.o spinlock.o fd.o pipe.o
|
||||||
|
|
||||||
CC = i386-jos-elf-gcc
|
CC = i386-jos-elf-gcc
|
||||||
LD = i386-jos-elf-ld
|
LD = i386-jos-elf-ld
|
||||||
|
@ -20,22 +20,30 @@ bootblock : bootasm.S bootmain.c
|
||||||
$(OBJCOPY) -S -O binary bootblock.o bootblock
|
$(OBJCOPY) -S -O binary bootblock.o bootblock
|
||||||
./sign.pl bootblock
|
./sign.pl bootblock
|
||||||
|
|
||||||
kernel : $(OBJS) bootother.S user1
|
kernel : $(OBJS) bootother.S user1 usertests
|
||||||
$(CC) -nostdinc -I. -c bootother.S
|
$(CC) -nostdinc -I. -c bootother.S
|
||||||
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
|
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
|
||||||
$(OBJCOPY) -S -O binary bootother.out bootother
|
$(OBJCOPY) -S -O binary bootother.out bootother
|
||||||
$(OBJDUMP) -S bootother.o > bootother.asm
|
$(OBJDUMP) -S bootother.o > bootother.asm
|
||||||
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1
|
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1 usertests
|
||||||
$(OBJDUMP) -S kernel > kernel.asm
|
$(OBJDUMP) -S kernel > kernel.asm
|
||||||
|
|
||||||
vectors.S : vectors.pl
|
vectors.S : vectors.pl
|
||||||
perl vectors.pl > vectors.S
|
perl vectors.pl > vectors.S
|
||||||
|
|
||||||
user1 : user1.c
|
user1 : user1.c ulib.o
|
||||||
$(CC) -nostdinc -I. -c user1.c
|
$(CC) -nostdinc -I. -c user1.c
|
||||||
$(LD) -N -e main -Ttext 0 -o user1 user1.o
|
$(LD) -N -e main -Ttext 0 -o user1 user1.o ulib.o
|
||||||
$(OBJDUMP) -S user1 > user1.asm
|
$(OBJDUMP) -S user1 > user1.asm
|
||||||
|
|
||||||
|
usertests : usertests.c ulib.o
|
||||||
|
$(CC) -nostdinc -I. -c usertests.c
|
||||||
|
$(LD) -N -e main -Ttext 0 -o usertests usertests.o ulib.o
|
||||||
|
$(OBJDUMP) -S usertests > usertests.asm
|
||||||
|
|
||||||
|
ulib.o : ulib.c
|
||||||
|
$(CC) -nostdinc -I. -c ulib.c
|
||||||
|
|
||||||
-include *.d
|
-include *.d
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
|
|
8
Notes
8
Notes
|
@ -83,3 +83,11 @@ it's IRQ 0, but it comes at a weird and changing vector (e.g. 119) if
|
||||||
you don't initialize the PIC. why doesn't jos see this? if i
|
you don't initialize the PIC. why doesn't jos see this? if i
|
||||||
initialize the PIC with IRQ_OFFSET 32, the interrupt arrives at vector
|
initialize the PIC with IRQ_OFFSET 32, the interrupt arrives at vector
|
||||||
32.
|
32.
|
||||||
|
|
||||||
|
test out-of-fd cases for creating pipe.
|
||||||
|
test pipe circular buffer
|
||||||
|
test pipe writer or reader closes while other active or waiting
|
||||||
|
test exit vs fd reference counts
|
||||||
|
test write of more than PIPESIZE
|
||||||
|
test reader goes first vs writer goes first
|
||||||
|
test streaming of a lot of data
|
||||||
|
|
16
defs.h
16
defs.h
|
@ -37,6 +37,7 @@ void pic_init(void);
|
||||||
void mp_init(void);
|
void mp_init(void);
|
||||||
int cpu(void);
|
int cpu(void);
|
||||||
int mp_isbcpu(void);
|
int mp_isbcpu(void);
|
||||||
|
void lapic_init(int c);
|
||||||
|
|
||||||
// spinlock.c
|
// spinlock.c
|
||||||
extern uint32_t kernel_lock;
|
extern uint32_t kernel_lock;
|
||||||
|
@ -46,3 +47,18 @@ void release_grant_spinlock(uint32_t* lock, int cpu);
|
||||||
|
|
||||||
// main.c
|
// main.c
|
||||||
void load_icode(struct proc *p, uint8_t *binary, unsigned size);
|
void load_icode(struct proc *p, uint8_t *binary, unsigned size);
|
||||||
|
|
||||||
|
// pipe.c
|
||||||
|
struct pipe;
|
||||||
|
struct fd;
|
||||||
|
int pipe_alloc(struct fd **fd1, struct fd **fd2);
|
||||||
|
void pipe_close(struct pipe *p, int writeable);
|
||||||
|
int pipe_write(struct pipe *p, char *addr, int n);
|
||||||
|
int pipe_read(struct pipe *p, char *addr, int n);
|
||||||
|
|
||||||
|
// fd.c
|
||||||
|
int fd_ualloc();
|
||||||
|
struct fd * fd_alloc();
|
||||||
|
void fd_close(struct fd *);
|
||||||
|
int fd_read(struct fd *fd, char *addr, int n);
|
||||||
|
int fd_write(struct fd *fd, char *addr, int n);
|
||||||
|
|
80
fd.c
Normal file
80
fd.c
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "param.h"
|
||||||
|
#include "x86.h"
|
||||||
|
#include "mmu.h"
|
||||||
|
#include "proc.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "fd.h"
|
||||||
|
|
||||||
|
struct fd fds[NFD];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* allocate a file descriptor number for curproc.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fd_ualloc()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct proc *p = curproc[cpu()];
|
||||||
|
for(fd = 0; fd < NOFILE; fd++)
|
||||||
|
if(p->fds[fd] == 0)
|
||||||
|
return fd;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fd *
|
||||||
|
fd_alloc()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < NFD; i++){
|
||||||
|
if(fds[i].type == FD_CLOSED){
|
||||||
|
fds[i].type = FD_NONE;
|
||||||
|
fds[i].count = 1;
|
||||||
|
return fds + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fd_close(struct fd *fd)
|
||||||
|
{
|
||||||
|
if(fd->type == FD_CLOSED || fd->count <= 0)
|
||||||
|
panic("fd_close");
|
||||||
|
fd->count -= 1;
|
||||||
|
if(fd->count == 0){
|
||||||
|
if(fd->type == FD_PIPE)
|
||||||
|
pipe_close(fd->pipe, fd->writeable);
|
||||||
|
fd->type = FD_CLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addr is a kernel address, pointing into some process's p->mem.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fd_write(struct fd *fd, char *addr, int n)
|
||||||
|
{
|
||||||
|
if(fd->writeable == 0)
|
||||||
|
return -1;
|
||||||
|
if(fd->type == FD_PIPE){
|
||||||
|
return pipe_write(fd->pipe, addr, n);
|
||||||
|
} else {
|
||||||
|
panic("fd_write");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fd_read(struct fd *fd, char *addr, int n)
|
||||||
|
{
|
||||||
|
if(fd->readable == 0)
|
||||||
|
return -1;
|
||||||
|
if(fd->type == FD_PIPE){
|
||||||
|
return pipe_read(fd->pipe, addr, n);
|
||||||
|
} else {
|
||||||
|
panic("fd_read");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
9
fd.h
Normal file
9
fd.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
struct fd {
|
||||||
|
enum { FD_CLOSED, FD_NONE, FD_PIPE } type;
|
||||||
|
int count; // reference count
|
||||||
|
char readable;
|
||||||
|
char writeable;
|
||||||
|
struct pipe *pipe;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct fd fds[NFD];
|
8
main.c
8
main.c
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
extern char edata[], end[];
|
extern char edata[], end[];
|
||||||
extern int acpu;
|
extern int acpu;
|
||||||
extern char _binary_user1_start[];
|
extern char _binary_user1_start[], _binary_user1_size[];
|
||||||
extern char _binary_user1_size[];
|
extern char _binary_usertests_start[], _binary_usertests_size[];
|
||||||
|
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ main()
|
||||||
cprintf("an application processor\n");
|
cprintf("an application processor\n");
|
||||||
release_spinlock(&kernel_lock);
|
release_spinlock(&kernel_lock);
|
||||||
acquire_spinlock(&kernel_lock);
|
acquire_spinlock(&kernel_lock);
|
||||||
idtinit();
|
idtinit(); // CPU's idt
|
||||||
lapic_init(cpu());
|
lapic_init(cpu());
|
||||||
curproc[cpu()] = &proc[0]; // XXX
|
curproc[cpu()] = &proc[0]; // XXX
|
||||||
swtch();
|
swtch();
|
||||||
|
@ -70,7 +70,7 @@ main()
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
p = newproc();
|
p = newproc();
|
||||||
load_icode(p, _binary_user1_start, (unsigned) _binary_user1_size);
|
load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
2
param.h
2
param.h
|
@ -2,3 +2,5 @@
|
||||||
#define PAGE 4096
|
#define PAGE 4096
|
||||||
#define KSTACKSIZE PAGE
|
#define KSTACKSIZE PAGE
|
||||||
#define NCPU 8
|
#define NCPU 8
|
||||||
|
#define NOFILE 16 // file descriptors per process
|
||||||
|
#define NFD 100 // file descriptors per system
|
||||||
|
|
100
pipe.c
Normal file
100
pipe.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "param.h"
|
||||||
|
#include "x86.h"
|
||||||
|
#include "mmu.h"
|
||||||
|
#include "proc.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "fd.h"
|
||||||
|
|
||||||
|
#define PIPESIZE 512
|
||||||
|
|
||||||
|
struct pipe {
|
||||||
|
int readopen; // read fd is still open
|
||||||
|
int writeopen; // write fd is still open
|
||||||
|
int writep; // next index to write
|
||||||
|
int readp; // next index to read
|
||||||
|
char data[PIPESIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
pipe_alloc(struct fd **fd1, struct fd **fd2)
|
||||||
|
{
|
||||||
|
*fd1 = *fd2 = 0;
|
||||||
|
struct pipe *p = 0;
|
||||||
|
|
||||||
|
if((*fd1 = fd_alloc()) == 0)
|
||||||
|
goto oops;
|
||||||
|
if((*fd2 = fd_alloc()) == 0)
|
||||||
|
goto oops;
|
||||||
|
if((p = (struct pipe *) kalloc(PAGE)) == 0)
|
||||||
|
goto oops;
|
||||||
|
(*fd1)->type = FD_PIPE;
|
||||||
|
(*fd1)->readable = 1;
|
||||||
|
(*fd1)->writeable = 0;
|
||||||
|
(*fd1)->pipe = p;
|
||||||
|
(*fd2)->type = FD_PIPE;
|
||||||
|
(*fd2)->readable = 0;
|
||||||
|
(*fd2)->writeable = 1;
|
||||||
|
(*fd2)->pipe = p;
|
||||||
|
return 0;
|
||||||
|
oops:
|
||||||
|
if(p)
|
||||||
|
kfree((char *) p, PAGE);
|
||||||
|
if(*fd1){
|
||||||
|
(*fd1)->type = FD_NONE;
|
||||||
|
fd_close(*fd1);
|
||||||
|
}
|
||||||
|
if(*fd2){
|
||||||
|
(*fd2)->type = FD_NONE;
|
||||||
|
fd_close(*fd2);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pipe_close(struct pipe *p, int writeable)
|
||||||
|
{
|
||||||
|
if(writeable)
|
||||||
|
p->writeopen = 0;
|
||||||
|
else
|
||||||
|
p->readopen = 0;
|
||||||
|
if(p->readopen == 0 && p->writeopen == 0)
|
||||||
|
kfree((char *) p, PAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pipe_write(struct pipe *p, char *addr, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n; i++){
|
||||||
|
while(((p->writep + 1) % PIPESIZE) == p->readp){
|
||||||
|
if(p->readopen == 0)
|
||||||
|
return -1;
|
||||||
|
sleep(&p->writep);
|
||||||
|
}
|
||||||
|
p->data[p->writep] = addr[i];
|
||||||
|
p->writep = (p->writep + 1) % PIPESIZE;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pipe_read(struct pipe *p, char *addr, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while(p->readp == p->writep){
|
||||||
|
if(p->writeopen == 0)
|
||||||
|
return 0;
|
||||||
|
sleep(&p->readp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < n; i++){
|
||||||
|
if(p->readp == p->writep)
|
||||||
|
break;
|
||||||
|
addr[i] = p->data[p->readp];
|
||||||
|
p->readp = (p->readp + 1) % PIPESIZE;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
9
proc.c
9
proc.c
|
@ -2,6 +2,7 @@
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
|
#include "fd.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ newproc()
|
||||||
struct proc *np;
|
struct proc *np;
|
||||||
struct proc *op = curproc[cpu()];
|
struct proc *op = curproc[cpu()];
|
||||||
unsigned *sp;
|
unsigned *sp;
|
||||||
|
int fd;
|
||||||
|
|
||||||
for(np = &proc[1]; np < &proc[NPROC]; np++)
|
for(np = &proc[1]; np < &proc[NPROC]; np++)
|
||||||
if(np->state == UNUSED)
|
if(np->state == UNUSED)
|
||||||
|
@ -80,6 +82,13 @@ newproc()
|
||||||
np->esp = (unsigned) sp;
|
np->esp = (unsigned) sp;
|
||||||
np->ebp = (unsigned) sp;
|
np->ebp = (unsigned) sp;
|
||||||
|
|
||||||
|
// copy file descriptors
|
||||||
|
for(fd = 0; fd < NOFILE; fd++){
|
||||||
|
np->fds[fd] = op->fds[fd];
|
||||||
|
if(np->fds[fd])
|
||||||
|
np->fds[fd]->count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
np->state = RUNNABLE;
|
np->state = RUNNABLE;
|
||||||
|
|
||||||
cprintf("newproc %x\n", np);
|
cprintf("newproc %x\n", np);
|
||||||
|
|
1
proc.h
1
proc.h
|
@ -24,6 +24,7 @@ struct proc{
|
||||||
int pid;
|
int pid;
|
||||||
int ppid;
|
int ppid;
|
||||||
void *chan; // sleep
|
void *chan; // sleep
|
||||||
|
struct fd *fds[NOFILE];
|
||||||
|
|
||||||
struct Taskstate ts; // only to give cpu address of kernel stack
|
struct Taskstate ts; // only to give cpu address of kernel stack
|
||||||
struct Segdesc gdt[NSEGS];
|
struct Segdesc gdt[NSEGS];
|
||||||
|
|
93
syscall.c
93
syscall.c
|
@ -42,6 +42,88 @@ fetcharg(int argno, int *ip)
|
||||||
return fetchint(curproc[cpu()], esp + 8 + 4*argno, ip);
|
return fetchint(curproc[cpu()], esp + 8 + 4*argno, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
putint(struct proc *p, unsigned addr, int ip)
|
||||||
|
{
|
||||||
|
if(addr > p->sz - 4)
|
||||||
|
return 0;
|
||||||
|
memcpy(p->mem + addr, &ip, 4);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sys_pipe()
|
||||||
|
{
|
||||||
|
struct fd *rfd = 0, *wfd = 0;
|
||||||
|
int f1 = -1, f2 = -1;
|
||||||
|
struct proc *p = curproc[cpu()];
|
||||||
|
unsigned fdp;
|
||||||
|
|
||||||
|
if(pipe_alloc(&rfd, &wfd) < 0)
|
||||||
|
goto oops;
|
||||||
|
if((f1 = fd_ualloc()) < 0)
|
||||||
|
goto oops;
|
||||||
|
p->fds[f1] = rfd;
|
||||||
|
if((f2 = fd_ualloc()) < 0)
|
||||||
|
goto oops;
|
||||||
|
p->fds[f2] = wfd;
|
||||||
|
if(fetcharg(0, &fdp) < 0)
|
||||||
|
goto oops;
|
||||||
|
if(putint(p, fdp, f1) < 0)
|
||||||
|
goto oops;
|
||||||
|
if(putint(p, fdp+4, f2) < 0)
|
||||||
|
goto oops;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
cprintf("sys_pipe failed\n");
|
||||||
|
if(rfd)
|
||||||
|
fd_close(rfd);
|
||||||
|
if(wfd)
|
||||||
|
fd_close(wfd);
|
||||||
|
if(f1 >= 0)
|
||||||
|
p->fds[f1] = 0;
|
||||||
|
if(f2 >= 0)
|
||||||
|
p->fds[f2] = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sys_write()
|
||||||
|
{
|
||||||
|
int fd, n;
|
||||||
|
unsigned addr;
|
||||||
|
struct proc *p = curproc[cpu()];
|
||||||
|
|
||||||
|
if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0)
|
||||||
|
return -1;
|
||||||
|
if(fd < 0 || fd >= NOFILE)
|
||||||
|
return -1;
|
||||||
|
if(p->fds[fd] == 0)
|
||||||
|
return -1;
|
||||||
|
if(addr + n > p->sz)
|
||||||
|
return -1;
|
||||||
|
return fd_write(p->fds[fd], p->mem + addr, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sys_read()
|
||||||
|
{
|
||||||
|
int fd, n;
|
||||||
|
unsigned addr;
|
||||||
|
struct proc *p = curproc[cpu()];
|
||||||
|
|
||||||
|
if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0)
|
||||||
|
return -1;
|
||||||
|
if(fd < 0 || fd >= NOFILE)
|
||||||
|
return -1;
|
||||||
|
if(p->fds[fd] == 0)
|
||||||
|
return -1;
|
||||||
|
if(addr + n > p->sz)
|
||||||
|
return -1;
|
||||||
|
return fd_read(p->fds[fd], p->mem + addr, n);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_fork()
|
sys_fork()
|
||||||
{
|
{
|
||||||
|
@ -122,7 +204,7 @@ syscall()
|
||||||
int num = cp->tf->tf_regs.reg_eax;
|
int num = cp->tf->tf_regs.reg_eax;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
cprintf("%x sys %d\n", cp, num);
|
//cprintf("%x sys %d\n", cp, num);
|
||||||
switch(num){
|
switch(num){
|
||||||
case SYS_fork:
|
case SYS_fork:
|
||||||
ret = sys_fork();
|
ret = sys_fork();
|
||||||
|
@ -136,6 +218,15 @@ syscall()
|
||||||
case SYS_cons_putc:
|
case SYS_cons_putc:
|
||||||
ret = sys_cons_putc();
|
ret = sys_cons_putc();
|
||||||
break;
|
break;
|
||||||
|
case SYS_pipe:
|
||||||
|
ret = sys_pipe();
|
||||||
|
break;
|
||||||
|
case SYS_write:
|
||||||
|
ret = sys_write();
|
||||||
|
break;
|
||||||
|
case SYS_read:
|
||||||
|
ret = sys_read();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cprintf("unknown sys call %d\n", num);
|
cprintf("unknown sys call %d\n", num);
|
||||||
// XXX fault
|
// XXX fault
|
||||||
|
|
|
@ -2,3 +2,6 @@
|
||||||
#define SYS_exit 2
|
#define SYS_exit 2
|
||||||
#define SYS_wait 3
|
#define SYS_wait 3
|
||||||
#define SYS_cons_putc 4
|
#define SYS_cons_putc 4
|
||||||
|
#define SYS_pipe 5
|
||||||
|
#define SYS_write 6
|
||||||
|
#define SYS_read 7
|
||||||
|
|
4
trap.c
4
trap.c
|
@ -37,14 +37,14 @@ trap(struct Trapframe *tf)
|
||||||
|
|
||||||
acquire_spinlock(&kernel_lock); // released in trapret in trapasm.S
|
acquire_spinlock(&kernel_lock); // released in trapret in trapasm.S
|
||||||
|
|
||||||
cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
|
|
||||||
|
|
||||||
if(v == T_SYSCALL){
|
if(v == T_SYSCALL){
|
||||||
curproc[cpu()]->tf = tf;
|
curproc[cpu()]->tf = tf;
|
||||||
syscall();
|
syscall();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
|
||||||
|
|
||||||
if(v == 32){
|
if(v == 32){
|
||||||
// probably clock
|
// probably clock
|
||||||
return;
|
return;
|
||||||
|
|
44
ulib.c
Normal file
44
ulib.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
int
|
||||||
|
fork()
|
||||||
|
{
|
||||||
|
asm("mov $1, %eax");
|
||||||
|
asm("int $48");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cons_putc(int c)
|
||||||
|
{
|
||||||
|
asm("mov $4, %eax");
|
||||||
|
asm("int $48");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
puts(char *s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; s[i]; i++)
|
||||||
|
cons_putc(s[i]);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pipe(int fds[])
|
||||||
|
{
|
||||||
|
asm("mov $5, %eax");
|
||||||
|
asm("int $48");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
read(int fd, char *buf, int n)
|
||||||
|
{
|
||||||
|
asm("mov $7, %eax");
|
||||||
|
asm("int $48");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write(int fd, char *buf, int n)
|
||||||
|
{
|
||||||
|
asm("mov $6, %eax");
|
||||||
|
asm("int $48");
|
||||||
|
}
|
38
user1.c
38
user1.c
|
@ -1,35 +1,19 @@
|
||||||
int
|
char buf[32];
|
||||||
fork()
|
|
||||||
{
|
|
||||||
asm("mov $1, %eax");
|
|
||||||
asm("int $48");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cons_putc(int c)
|
|
||||||
{
|
|
||||||
asm("mov $4, %eax");
|
|
||||||
asm("int $48");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
puts(char *s)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; s[i]; i++)
|
|
||||||
cons_putc(s[i]);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
int pid;
|
int pid, fds[2], n;
|
||||||
|
|
||||||
|
pipe(fds);
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0){
|
if(pid > 0){
|
||||||
cons_putc('C');
|
write(fds[1], "xyz", 4);
|
||||||
|
puts("w");
|
||||||
} else {
|
} else {
|
||||||
cons_putc('P');
|
n = read(fds[0], buf, sizeof(buf));
|
||||||
|
puts("r: ");
|
||||||
|
puts(buf);
|
||||||
|
puts("\n");
|
||||||
}
|
}
|
||||||
while(1)
|
while(1)
|
||||||
;
|
;
|
||||||
|
|
30
usertests.c
Normal file
30
usertests.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// simple fork and pipe read/write
|
||||||
|
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
void
|
||||||
|
pipe1()
|
||||||
|
{
|
||||||
|
int fds[2], pid;
|
||||||
|
|
||||||
|
pipe(fds);
|
||||||
|
pid = pipe();
|
||||||
|
if(pid == 0){
|
||||||
|
write(fds[1], "xyz", 4);
|
||||||
|
} else {
|
||||||
|
read(fds[0], buf, sizeof(buf));
|
||||||
|
if(buf[0] != 'x' || buf[1] != 'y'){
|
||||||
|
puts("pipe1 oops\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts("pipe1 ok\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
pipe1();
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
;
|
||||||
|
}
|
Loading…
Reference in a new issue