diff --git a/Notes b/Notes index 0399f5c..4e1703b 100644 --- a/Notes +++ b/Notes @@ -120,3 +120,4 @@ echo foo > bar should truncate bar make it work on one cpu make it work on a real machine release before acquire at end of sleep? +check 2nd disk (i.e. if not in .bochsrc) diff --git a/bio.c b/bio.c index 251f2f9..49b52c9 100644 --- a/bio.c +++ b/bio.c @@ -75,9 +75,8 @@ bread(uint dev, uint sector) extern struct spinlock ide_lock; b = getblk(dev, sector); - if(b->flags & B_VALID){ + if(b->flags & B_VALID) return b; - } acquire(&ide_lock); c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1); diff --git a/defs.h b/defs.h index 1dd415c..752a7b7 100644 --- a/defs.h +++ b/defs.h @@ -116,6 +116,7 @@ void iinit(void); struct inode * iget(uint dev, uint inum); void ilock(struct inode *ip); void iunlock(struct inode *ip); +void itrunc(struct inode *ip); void idecref(struct inode *ip); void iincref(struct inode *ip); void iput(struct inode *ip); diff --git a/fs.c b/fs.c index 80f522b..576bcb7 100644 --- a/fs.c +++ b/fs.c @@ -24,6 +24,9 @@ iinit(void) initlock(&inode_table_lock, "inode_table"); } +/* + * allocate a disk block + */ static uint balloc(uint dev) { @@ -52,7 +55,7 @@ balloc(uint dev) } } if (b >= size) - panic("balloc: out of blocks\n"); + panic("balloc: out of blocks"); bp->data[bi/8] |= 0x1 << (bi % 8); bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk @@ -87,7 +90,11 @@ bfree(int dev, uint b) brelse(bp); } -// returns an inode with busy set and incremented reference count. +/* + * fetch an inode, from the in-core table if it's already + * in use, otherwise read from the disk. + * returns an inode with busy set and incremented reference count. + */ struct inode * iget(uint dev, uint inum) { @@ -180,8 +187,9 @@ ialloc(uint dev, short type) } if (inum >= ninodes) - panic ("ialloc: no inodes left\n"); + panic ("ialloc: no inodes left"); + memset(dip, 0, sizeof(*dip)); dip->type = type; bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk brelse(bp); @@ -254,12 +262,11 @@ bmap(struct inode *ip, uint bn) } void -iunlink(struct inode *ip) +itrunc(struct inode *ip) { int i, j; struct buf *inbp; - // free inode, its blocks, and remove dir entry for (i = 0; i < NADDRS; i++) { if (ip->addrs[i] != 0) { if (i == INDIRECT) { @@ -278,10 +285,7 @@ iunlink(struct inode *ip) } } ip->size = 0; - ip->major = 0; - ip->minor = 0; iupdate(ip); - ifree(ip); // is this the right order? } // caller is releasing a reference to this inode. @@ -292,8 +296,10 @@ iput(struct inode *ip) if(ip->count < 1 || ip->busy != 1) panic("iput"); - if ((ip->count == 1) && (ip->nlink == 0)) - iunlink(ip); + if ((ip->count == 1) && (ip->nlink == 0)) { + itrunc(ip); + ifree(ip); + } acquire(&inode_table_lock); @@ -425,7 +431,7 @@ writei(struct inode *ip, char *addr, uint off, uint n) } return r; } else { - panic ("writei: unknown type\n"); + panic ("writei: unknown type"); return 0; } } @@ -451,10 +457,6 @@ namei(char *path, int mode, uint *ret_off, char **ret_last, struct inode **ret_i int i, atend; unsigned ninum; - if(mode == NAMEI_DELETE && ret_off == 0) - panic("namei no ret_off"); - if(mode == NAMEI_CREATE && ret_last == 0) - panic("namei no ret_last"); if(ret_off) *ret_off = 0xffffffff; if(ret_last) @@ -550,9 +552,6 @@ wdir(struct inode *dp, char *name, uint ino) struct dirent de; int i; - if(name[0] == '\0') - panic("wdir no name"); - for(off = 0; off < dp->size; off += sizeof(de)){ if(readi(dp, (char *) &de, off, sizeof(de)) != sizeof(de)) panic("wdir read"); @@ -561,11 +560,8 @@ wdir(struct inode *dp, char *name, uint ino) } de.inum = ino; - for(i = 0; i < DIRSIZ && name[i]; i++){ - if(name[i] == '/') - panic("wdir /"); + for(i = 0; i < DIRSIZ && name[i]; i++) de.name[i] = name[i]; - } for( ; i < DIRSIZ; i++) de.name[i] = '\0'; @@ -595,10 +591,8 @@ mknod1(struct inode *dp, char *name, short type, short major, short minor) struct inode *ip; ip = ialloc(dp->dev, type); - if (ip == 0) { - iput(dp); + if (ip == 0) return 0; - } ip->major = major; ip->minor = minor; ip->size = 0; diff --git a/ide.c b/ide.c index 331553f..b999786 100644 --- a/ide.c +++ b/ide.c @@ -1,7 +1,5 @@ /* - * Minimal PIO-based (non-interrupt-driven) IDE driver code. - * For information about what all this IDE/ATA magic means, - * see the materials available on the class references page. + * Simple PIO-based (non-DMA) IDE driver code. */ #include "types.h" @@ -27,9 +25,11 @@ struct ide_request { struct ide_request request[NREQUEST]; int head, tail; struct spinlock ide_lock; - +int disk_1_present; int disk_channel; +int ide_probe_disk1(void); + static int ide_wait_ready(int check_error) { @@ -47,11 +47,9 @@ void ide_init(void) { initlock(&ide_lock, "ide"); - if (ncpu < 2) { - panic ("ide_init: disk interrupt is going to the second cpu\n"); - } - ioapic_enable (IRQ_IDE, 1); + ioapic_enable (IRQ_IDE, ncpu - 1); ide_wait_ready(0); + disk_1_present = ide_probe_disk1(); } void @@ -80,7 +78,6 @@ ide_probe_disk1(void) // switch back to Device 0 outb(0x1F6, 0xE0 | (0<<4)); - cprintf("Device 1 presence: %d\n", (x < 1000)); return (x < 1000); } @@ -111,11 +108,8 @@ ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read) { struct ide_request *r; - if(!holding(&ide_lock)) - panic("ide_start_read: not holding ide_lock"); - - if(nsecs > 1) - panic("ide_start_read: nsecs too large"); + if(diskno && !disk_1_present) + panic("ide disk 1 not present"); while ((head + 1) % NREQUEST == tail) sleep (&disk_channel, &ide_lock); @@ -140,12 +134,6 @@ ide_finish(void *c) int r; struct ide_request *req = (struct ide_request *) c; - if(c != &request[tail]) - panic("ide_finish_read"); - - if(!holding(&ide_lock)) - panic("ide_start_read: not holding ide_lock"); - if (req->read) { if ((r = ide_wait_ready(1)) >= 0) insl(0x1F0, req->addr, 512/4); diff --git a/kalloc.c b/kalloc.c index 989e3e8..cb79130 100644 --- a/kalloc.c +++ b/kalloc.c @@ -23,8 +23,6 @@ struct run { }; struct run *freelist; -void ktest(void); - /* * initialize free list of physical pages. this code * cheats by just considering the one megabyte of pages @@ -43,7 +41,6 @@ kinit(void) mem = 256; // XXX cprintf("mem = %d\n", mem * PAGE); kfree(start, mem * PAGE); - ktest(); } void @@ -130,46 +127,6 @@ kalloc(int n) rr = &(*rr)->next; } release(&kalloc_lock); + cprintf("kalloc: out of memory\n"); return 0; } - -void -ktest(void) -{ - char *p1, *p2, *p3; - - // test coalescing - p1 = kalloc(4 * PAGE); - kfree(p1 + 3*PAGE, PAGE); - kfree(p1 + 2*PAGE, PAGE); - kfree(p1, PAGE); - kfree(p1 + PAGE, PAGE); - p2 = kalloc(4 * PAGE); - if(p2 != p1) - panic("ktest"); - kfree(p2, 4 * PAGE); - - // test finding first run that fits - p1 = kalloc(1 * PAGE); - p2 = kalloc(1 * PAGE); - kfree(p1, PAGE); - p3 = kalloc(2 * PAGE); - kfree(p2, PAGE); - kfree(p3, 2 * PAGE); - - // test running out of memory - p1 = 0; - while((p2 = kalloc(PAGE)) != 0){ - *(char**)p2 = p1; - p1 = p2; - } - while(p1){ - p2 = *(char **)p1; - kfree(p1, PAGE); - p1 = p2; - } - p1 = kalloc(PAGE * 20); - if(p1 == 0) - panic("ktest2"); - kfree(p1, PAGE * 20); -} diff --git a/proc.c b/proc.c index 401188e..80141db 100644 --- a/proc.c +++ b/proc.c @@ -113,7 +113,7 @@ copyproc(struct proc* p) // Copy trapframe registers from parent. np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1; - *np->tf = *p->tf; + memmove(np->tf, p->tf, sizeof(*np->tf)); // Clear %eax so that fork system call returns 0 in child. np->tf->eax = 0; diff --git a/string.c b/string.c index 98253ed..10ea805 100644 --- a/string.c +++ b/string.c @@ -57,21 +57,3 @@ strncmp(const char *p, const char *q, uint n) else return (int) ((uchar) *p - (uchar) *q); } - -// Memcpy is deprecated and should NOT be called. -// Use memmove instead, which has defined semantics -// when the two memory ranges overlap. -// Memcpy is here only because gcc compiles some -// structure assignments into calls to memcpy. -void * -memcpy(void *dst, void *src, uint n) -{ - char *d = (char *) dst; - char *s = (char *) src; - - while(n-- > 0) - *d++ = *s++; - - return dst; -} - diff --git a/syscall.c b/syscall.c index 2918bb0..2d08a0e 100644 --- a/syscall.c +++ b/syscall.c @@ -21,8 +21,6 @@ * Arguments on the stack, from the user call to the C * library system call function. The saved user %esp points * to a saved program counter, and then the first argument. - * - * Return value? Error indication? Errno? */ /* @@ -51,7 +49,6 @@ fetchbyte(struct proc *p, uint addr, char* c) return 0; } -// This arg is void* so that both int* and uint* can be passed. int fetcharg(int argno, void *ip) { @@ -366,9 +363,6 @@ sys_chdir(void) if((l = checkstring(arg0)) < 0) return -1; - if(l >= DIRSIZ) - return -1; - if ((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0) return -1; @@ -436,11 +430,8 @@ sys_dup(void) return -1; if(cp->fds[fd] == 0) return -1; - if (cp->fds[fd]->type != FD_PIPE && cp->fds[fd]->type != FD_FILE) + if ((ufd1 = fd_ualloc()) < 0) return -1; - if ((ufd1 = fd_ualloc()) < 0) { - return -1; - } cp->fds[ufd1] = cp->fds[fd]; fd_incref(cp->fds[ufd1]); return ufd1; diff --git a/vectors.pl b/vectors.pl index 368aad7..33cde90 100755 --- a/vectors.pl +++ b/vectors.pl @@ -2,8 +2,8 @@ # Generate vectors.S, the trap/interrupt entry points. # There has to be one entry point per interrupt number -# since otherwise there's no way to tell the interrupt -# number. +# since otherwise there's no way for trap() to discover +# the interrupt number. print "/* generated by vectors.pl */\n"; print "/* handlers */\n";