complain if no disk 1
lots of cleanup
This commit is contained in:
parent
18432ed5ed
commit
2aa4c3bc29
1
Notes
1
Notes
|
@ -120,3 +120,4 @@ echo foo > bar should truncate bar
|
||||||
make it work on one cpu
|
make it work on one cpu
|
||||||
make it work on a real machine
|
make it work on a real machine
|
||||||
release before acquire at end of sleep?
|
release before acquire at end of sleep?
|
||||||
|
check 2nd disk (i.e. if not in .bochsrc)
|
||||||
|
|
3
bio.c
3
bio.c
|
@ -75,9 +75,8 @@ bread(uint dev, uint sector)
|
||||||
extern struct spinlock ide_lock;
|
extern struct spinlock ide_lock;
|
||||||
|
|
||||||
b = getblk(dev, sector);
|
b = getblk(dev, sector);
|
||||||
if(b->flags & B_VALID){
|
if(b->flags & B_VALID)
|
||||||
return b;
|
return b;
|
||||||
}
|
|
||||||
|
|
||||||
acquire(&ide_lock);
|
acquire(&ide_lock);
|
||||||
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
|
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
|
||||||
|
|
1
defs.h
1
defs.h
|
@ -116,6 +116,7 @@ void iinit(void);
|
||||||
struct inode * iget(uint dev, uint inum);
|
struct inode * iget(uint dev, uint inum);
|
||||||
void ilock(struct inode *ip);
|
void ilock(struct inode *ip);
|
||||||
void iunlock(struct inode *ip);
|
void iunlock(struct inode *ip);
|
||||||
|
void itrunc(struct inode *ip);
|
||||||
void idecref(struct inode *ip);
|
void idecref(struct inode *ip);
|
||||||
void iincref(struct inode *ip);
|
void iincref(struct inode *ip);
|
||||||
void iput(struct inode *ip);
|
void iput(struct inode *ip);
|
||||||
|
|
44
fs.c
44
fs.c
|
@ -24,6 +24,9 @@ iinit(void)
|
||||||
initlock(&inode_table_lock, "inode_table");
|
initlock(&inode_table_lock, "inode_table");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* allocate a disk block
|
||||||
|
*/
|
||||||
static uint
|
static uint
|
||||||
balloc(uint dev)
|
balloc(uint dev)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +55,7 @@ balloc(uint dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (b >= size)
|
if (b >= size)
|
||||||
panic("balloc: out of blocks\n");
|
panic("balloc: out of blocks");
|
||||||
|
|
||||||
bp->data[bi/8] |= 0x1 << (bi % 8);
|
bp->data[bi/8] |= 0x1 << (bi % 8);
|
||||||
bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk
|
bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk
|
||||||
|
@ -87,7 +90,11 @@ bfree(int dev, uint b)
|
||||||
brelse(bp);
|
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 *
|
struct inode *
|
||||||
iget(uint dev, uint inum)
|
iget(uint dev, uint inum)
|
||||||
{
|
{
|
||||||
|
@ -180,8 +187,9 @@ ialloc(uint dev, short type)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inum >= ninodes)
|
if (inum >= ninodes)
|
||||||
panic ("ialloc: no inodes left\n");
|
panic ("ialloc: no inodes left");
|
||||||
|
|
||||||
|
memset(dip, 0, sizeof(*dip));
|
||||||
dip->type = type;
|
dip->type = type;
|
||||||
bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk
|
bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
|
@ -254,12 +262,11 @@ bmap(struct inode *ip, uint bn)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iunlink(struct inode *ip)
|
itrunc(struct inode *ip)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
struct buf *inbp;
|
struct buf *inbp;
|
||||||
|
|
||||||
// free inode, its blocks, and remove dir entry
|
|
||||||
for (i = 0; i < NADDRS; i++) {
|
for (i = 0; i < NADDRS; i++) {
|
||||||
if (ip->addrs[i] != 0) {
|
if (ip->addrs[i] != 0) {
|
||||||
if (i == INDIRECT) {
|
if (i == INDIRECT) {
|
||||||
|
@ -278,10 +285,7 @@ iunlink(struct inode *ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ip->size = 0;
|
ip->size = 0;
|
||||||
ip->major = 0;
|
|
||||||
ip->minor = 0;
|
|
||||||
iupdate(ip);
|
iupdate(ip);
|
||||||
ifree(ip); // is this the right order?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// caller is releasing a reference to this inode.
|
// caller is releasing a reference to this inode.
|
||||||
|
@ -292,8 +296,10 @@ iput(struct inode *ip)
|
||||||
if(ip->count < 1 || ip->busy != 1)
|
if(ip->count < 1 || ip->busy != 1)
|
||||||
panic("iput");
|
panic("iput");
|
||||||
|
|
||||||
if ((ip->count == 1) && (ip->nlink == 0))
|
if ((ip->count == 1) && (ip->nlink == 0)) {
|
||||||
iunlink(ip);
|
itrunc(ip);
|
||||||
|
ifree(ip);
|
||||||
|
}
|
||||||
|
|
||||||
acquire(&inode_table_lock);
|
acquire(&inode_table_lock);
|
||||||
|
|
||||||
|
@ -425,7 +431,7 @@ writei(struct inode *ip, char *addr, uint off, uint n)
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
panic ("writei: unknown type\n");
|
panic ("writei: unknown type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,10 +457,6 @@ namei(char *path, int mode, uint *ret_off, char **ret_last, struct inode **ret_i
|
||||||
int i, atend;
|
int i, atend;
|
||||||
unsigned ninum;
|
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)
|
if(ret_off)
|
||||||
*ret_off = 0xffffffff;
|
*ret_off = 0xffffffff;
|
||||||
if(ret_last)
|
if(ret_last)
|
||||||
|
@ -550,9 +552,6 @@ wdir(struct inode *dp, char *name, uint ino)
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(name[0] == '\0')
|
|
||||||
panic("wdir no name");
|
|
||||||
|
|
||||||
for(off = 0; off < dp->size; off += sizeof(de)){
|
for(off = 0; off < dp->size; off += sizeof(de)){
|
||||||
if(readi(dp, (char *) &de, off, sizeof(de)) != sizeof(de))
|
if(readi(dp, (char *) &de, off, sizeof(de)) != sizeof(de))
|
||||||
panic("wdir read");
|
panic("wdir read");
|
||||||
|
@ -561,11 +560,8 @@ wdir(struct inode *dp, char *name, uint ino)
|
||||||
}
|
}
|
||||||
|
|
||||||
de.inum = ino;
|
de.inum = ino;
|
||||||
for(i = 0; i < DIRSIZ && name[i]; i++){
|
for(i = 0; i < DIRSIZ && name[i]; i++)
|
||||||
if(name[i] == '/')
|
|
||||||
panic("wdir /");
|
|
||||||
de.name[i] = name[i];
|
de.name[i] = name[i];
|
||||||
}
|
|
||||||
for( ; i < DIRSIZ; i++)
|
for( ; i < DIRSIZ; i++)
|
||||||
de.name[i] = '\0';
|
de.name[i] = '\0';
|
||||||
|
|
||||||
|
@ -595,10 +591,8 @@ mknod1(struct inode *dp, char *name, short type, short major, short minor)
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
|
|
||||||
ip = ialloc(dp->dev, type);
|
ip = ialloc(dp->dev, type);
|
||||||
if (ip == 0) {
|
if (ip == 0)
|
||||||
iput(dp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
ip->major = major;
|
ip->major = major;
|
||||||
ip->minor = minor;
|
ip->minor = minor;
|
||||||
ip->size = 0;
|
ip->size = 0;
|
||||||
|
|
28
ide.c
28
ide.c
|
@ -1,7 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Minimal PIO-based (non-interrupt-driven) IDE driver code.
|
* Simple PIO-based (non-DMA) IDE driver code.
|
||||||
* For information about what all this IDE/ATA magic means,
|
|
||||||
* see the materials available on the class references page.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
@ -27,9 +25,11 @@ struct ide_request {
|
||||||
struct ide_request request[NREQUEST];
|
struct ide_request request[NREQUEST];
|
||||||
int head, tail;
|
int head, tail;
|
||||||
struct spinlock ide_lock;
|
struct spinlock ide_lock;
|
||||||
|
int disk_1_present;
|
||||||
int disk_channel;
|
int disk_channel;
|
||||||
|
|
||||||
|
int ide_probe_disk1(void);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ide_wait_ready(int check_error)
|
ide_wait_ready(int check_error)
|
||||||
{
|
{
|
||||||
|
@ -47,11 +47,9 @@ void
|
||||||
ide_init(void)
|
ide_init(void)
|
||||||
{
|
{
|
||||||
initlock(&ide_lock, "ide");
|
initlock(&ide_lock, "ide");
|
||||||
if (ncpu < 2) {
|
ioapic_enable (IRQ_IDE, ncpu - 1);
|
||||||
panic ("ide_init: disk interrupt is going to the second cpu\n");
|
|
||||||
}
|
|
||||||
ioapic_enable (IRQ_IDE, 1);
|
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
|
disk_1_present = ide_probe_disk1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -80,7 +78,6 @@ ide_probe_disk1(void)
|
||||||
// switch back to Device 0
|
// switch back to Device 0
|
||||||
outb(0x1F6, 0xE0 | (0<<4));
|
outb(0x1F6, 0xE0 | (0<<4));
|
||||||
|
|
||||||
cprintf("Device 1 presence: %d\n", (x < 1000));
|
|
||||||
return (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;
|
struct ide_request *r;
|
||||||
|
|
||||||
if(!holding(&ide_lock))
|
if(diskno && !disk_1_present)
|
||||||
panic("ide_start_read: not holding ide_lock");
|
panic("ide disk 1 not present");
|
||||||
|
|
||||||
if(nsecs > 1)
|
|
||||||
panic("ide_start_read: nsecs too large");
|
|
||||||
|
|
||||||
while ((head + 1) % NREQUEST == tail)
|
while ((head + 1) % NREQUEST == tail)
|
||||||
sleep (&disk_channel, &ide_lock);
|
sleep (&disk_channel, &ide_lock);
|
||||||
|
@ -140,12 +134,6 @@ ide_finish(void *c)
|
||||||
int r;
|
int r;
|
||||||
struct ide_request *req = (struct ide_request *) c;
|
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 (req->read) {
|
||||||
if ((r = ide_wait_ready(1)) >= 0)
|
if ((r = ide_wait_ready(1)) >= 0)
|
||||||
insl(0x1F0, req->addr, 512/4);
|
insl(0x1F0, req->addr, 512/4);
|
||||||
|
|
45
kalloc.c
45
kalloc.c
|
@ -23,8 +23,6 @@ struct run {
|
||||||
};
|
};
|
||||||
struct run *freelist;
|
struct run *freelist;
|
||||||
|
|
||||||
void ktest(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize free list of physical pages. this code
|
* initialize free list of physical pages. this code
|
||||||
* cheats by just considering the one megabyte of pages
|
* cheats by just considering the one megabyte of pages
|
||||||
|
@ -43,7 +41,6 @@ kinit(void)
|
||||||
mem = 256; // XXX
|
mem = 256; // XXX
|
||||||
cprintf("mem = %d\n", mem * PAGE);
|
cprintf("mem = %d\n", mem * PAGE);
|
||||||
kfree(start, mem * PAGE);
|
kfree(start, mem * PAGE);
|
||||||
ktest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -130,46 +127,6 @@ kalloc(int n)
|
||||||
rr = &(*rr)->next;
|
rr = &(*rr)->next;
|
||||||
}
|
}
|
||||||
release(&kalloc_lock);
|
release(&kalloc_lock);
|
||||||
|
cprintf("kalloc: out of memory\n");
|
||||||
return 0;
|
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);
|
|
||||||
}
|
|
||||||
|
|
2
proc.c
2
proc.c
|
@ -113,7 +113,7 @@ copyproc(struct proc* p)
|
||||||
|
|
||||||
// Copy trapframe registers from parent.
|
// Copy trapframe registers from parent.
|
||||||
np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1;
|
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.
|
// Clear %eax so that fork system call returns 0 in child.
|
||||||
np->tf->eax = 0;
|
np->tf->eax = 0;
|
||||||
|
|
18
string.c
18
string.c
|
@ -57,21 +57,3 @@ strncmp(const char *p, const char *q, uint n)
|
||||||
else
|
else
|
||||||
return (int) ((uchar) *p - (uchar) *q);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
11
syscall.c
11
syscall.c
|
@ -21,8 +21,6 @@
|
||||||
* Arguments on the stack, from the user call to the C
|
* Arguments on the stack, from the user call to the C
|
||||||
* library system call function. The saved user %esp points
|
* library system call function. The saved user %esp points
|
||||||
* to a saved program counter, and then the first argument.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This arg is void* so that both int* and uint* can be passed.
|
|
||||||
int
|
int
|
||||||
fetcharg(int argno, void *ip)
|
fetcharg(int argno, void *ip)
|
||||||
{
|
{
|
||||||
|
@ -366,9 +363,6 @@ sys_chdir(void)
|
||||||
if((l = checkstring(arg0)) < 0)
|
if((l = checkstring(arg0)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(l >= DIRSIZ)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0)
|
if ((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -436,11 +430,8 @@ sys_dup(void)
|
||||||
return -1;
|
return -1;
|
||||||
if(cp->fds[fd] == 0)
|
if(cp->fds[fd] == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (cp->fds[fd]->type != FD_PIPE && cp->fds[fd]->type != FD_FILE)
|
if ((ufd1 = fd_ualloc()) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if ((ufd1 = fd_ualloc()) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
cp->fds[ufd1] = cp->fds[fd];
|
cp->fds[ufd1] = cp->fds[fd];
|
||||||
fd_incref(cp->fds[ufd1]);
|
fd_incref(cp->fds[ufd1]);
|
||||||
return ufd1;
|
return ufd1;
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
# Generate vectors.S, the trap/interrupt entry points.
|
# Generate vectors.S, the trap/interrupt entry points.
|
||||||
# There has to be one entry point per interrupt number
|
# There has to be one entry point per interrupt number
|
||||||
# since otherwise there's no way to tell the interrupt
|
# since otherwise there's no way for trap() to discover
|
||||||
# number.
|
# the interrupt number.
|
||||||
|
|
||||||
print "/* generated by vectors.pl */\n";
|
print "/* generated by vectors.pl */\n";
|
||||||
print "/* handlers */\n";
|
print "/* handlers */\n";
|
||||||
|
|
Loading…
Reference in a new issue