make new code like old code

Variable declarations at top of function,
separate from initialization.

Use == 0 instead of ! for checking pointers.

Consistent spacing around {, *, casts.

Declare 0-parameter functions as (void) not ().

Integer valued functions return -1 on failure, 0 on success.
This commit is contained in:
Russ Cox 2011-01-11 13:01:13 -05:00
parent 240679608c
commit 1a81e38b17
21 changed files with 227 additions and 199 deletions

View file

@ -33,7 +33,7 @@ bootmain(void)
// Load each program segment (ignores ph flags). // Load each program segment (ignores ph flags).
ph = (struct proghdr*)((uchar*)elf + elf->phoff); ph = (struct proghdr*)((uchar*)elf + elf->phoff);
eph = ph + elf->phnum; eph = ph + elf->phnum;
for(; ph < eph; ph++) { for(; ph < eph; ph++){
va = (uchar*)ph->va; va = (uchar*)ph->va;
readseg(va, ph->filesz, ph->offset); readseg(va, ph->filesz, ph->offset);
if(ph->memsz > ph->filesz) if(ph->memsz > ph->filesz)

View file

@ -27,15 +27,16 @@ printint(int xx, int base, int sgn)
{ {
static char digits[] = "0123456789abcdef"; static char digits[] = "0123456789abcdef";
char buf[16]; char buf[16];
int i = 0, neg = 0; int i, neg;
uint x; uint x;
if(sgn && xx < 0){ if(sgn && (neg = xx < 0)){
neg = 1; neg = 1;
x = -xx; x = -xx;
} else } else
x = xx; x = xx;
i = 0;
do{ do{
buf[i++] = digits[x % base]; buf[i++] = digits[x % base];
}while((x /= base) != 0); }while((x /= base) != 0);

8
defs.h
View file

@ -62,7 +62,7 @@ void ioapicinit(void);
// kalloc.c // kalloc.c
char* kalloc(void); char* kalloc(void);
void kfree(char*); void kfree(char*);
void kinit(); void kinit(void);
// kbd.c // kbd.c
void kbdintr(void); void kbdintr(void);
@ -117,8 +117,8 @@ void getcallerpcs(void*, uint*);
int holding(struct spinlock*); int holding(struct spinlock*);
void initlock(struct spinlock*, char*); void initlock(struct spinlock*, char*);
void release(struct spinlock*); void release(struct spinlock*);
void pushcli(); void pushcli(void);
void popcli(); void popcli(void);
// string.c // string.c
int memcmp(const void*, const void*, uint); int memcmp(const void*, const void*, uint);
@ -164,7 +164,7 @@ void inituvm(pde_t*, char*, uint);
int loaduvm(pde_t*, char*, struct inode *, uint, uint); int loaduvm(pde_t*, char*, struct inode *, uint, uint);
pde_t* copyuvm(pde_t*,uint); pde_t* copyuvm(pde_t*,uint);
void switchuvm(struct proc*); void switchuvm(struct proc*);
void switchkvm(); void switchkvm(void);
int copyout(pde_t *pgdir, uint va, void *buf, uint len); int copyout(pde_t *pgdir, uint va, void *buf, uint len);
// number of elements in fixed-size array // number of elements in fixed-size array

24
exec.c
View file

@ -10,16 +10,17 @@ int
exec(char *path, char **argv) exec(char *path, char **argv)
{ {
char *s, *last; char *s, *last;
int i, off; int i, off, argc;
uint sz = 0; uint sz, sp, strings[MAXARG];
struct elfhdr elf; struct elfhdr elf;
struct inode *ip = 0; struct inode *ip;
struct proghdr ph; struct proghdr ph;
pde_t *pgdir = 0, *oldpgdir; pde_t *pgdir, *oldpgdir;
if((ip = namei(path)) == 0) if((ip = namei(path)) == 0)
return -1; return -1;
ilock(ip); ilock(ip);
pgdir = 0;
// Check ELF header // Check ELF header
if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf)) if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
@ -27,10 +28,11 @@ exec(char *path, char **argv)
if(elf.magic != ELF_MAGIC) if(elf.magic != ELF_MAGIC)
goto bad; goto bad;
if(!(pgdir = setupkvm())) if((pgdir = setupkvm()) == 0)
goto bad; goto bad;
// Load program into memory. // Load program into memory.
sz = 0;
for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){ for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
goto bad; goto bad;
@ -38,9 +40,9 @@ exec(char *path, char **argv)
continue; continue;
if(ph.memsz < ph.filesz) if(ph.memsz < ph.filesz)
goto bad; goto bad;
if(!(sz = allocuvm(pgdir, sz, ph.va + ph.memsz))) if((sz = allocuvm(pgdir, sz, ph.va + ph.memsz)) == 0)
goto bad; goto bad;
if(!loaduvm(pgdir, (char *)ph.va, ip, ph.offset, ph.filesz)) if(loaduvm(pgdir, (char*)ph.va, ip, ph.offset, ph.filesz) < 0)
goto bad; goto bad;
} }
iunlockput(ip); iunlockput(ip);
@ -48,7 +50,7 @@ exec(char *path, char **argv)
// Allocate a one-page stack at the next page boundary // Allocate a one-page stack at the next page boundary
sz = PGROUNDUP(sz); sz = PGROUNDUP(sz);
if(!(sz = allocuvm(pgdir, sz, sz + PGSIZE))) if((sz = allocuvm(pgdir, sz, sz + PGSIZE)) == 0)
goto bad; goto bad;
// initialize stack content: // initialize stack content:
@ -64,24 +66,22 @@ exec(char *path, char **argv)
// argc -- argc argument to main() // argc -- argc argument to main()
// ffffffff -- return PC for main() call // ffffffff -- return PC for main() call
uint sp = sz; sp = sz;
// count arguments // count arguments
int argc;
for(argc = 0; argv[argc]; argc++) for(argc = 0; argv[argc]; argc++)
; ;
if(argc >= MAXARG) if(argc >= MAXARG)
goto bad; goto bad;
// push strings and remember where they are // push strings and remember where they are
uint strings[MAXARG];
for(i = argc - 1; i >= 0; --i){ for(i = argc - 1; i >= 0; --i){
sp -= strlen(argv[i]) + 1; sp -= strlen(argv[i]) + 1;
strings[i] = sp; strings[i] = sp;
copyout(pgdir, sp, argv[i], strlen(argv[i]) + 1); copyout(pgdir, sp, argv[i], strlen(argv[i]) + 1);
} }
#define PUSH(x) { int xx = (int)(x); sp -= 4; copyout(pgdir, sp, &xx, 4); } #define PUSH(x){ int xx = (int)(x); sp -= 4; copyout(pgdir, sp, &xx, 4); }
PUSH(0); // argv[argc] is zero PUSH(0); // argv[argc] is zero

4
ide.c
View file

@ -131,7 +131,7 @@ iderw(struct buf *b)
if((b->flags & (B_VALID|B_DIRTY)) == B_VALID) if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
panic("iderw: nothing to do"); panic("iderw: nothing to do");
if(b->dev != 0 && !havedisk1) if(b->dev != 0 && !havedisk1)
panic("idrw: ide disk 1 not present"); panic("iderw: ide disk 1 not present");
acquire(&idelock); acquire(&idelock);
@ -147,7 +147,7 @@ iderw(struct buf *b)
// Wait for request to finish. // Wait for request to finish.
// Assuming will not sleep too long: ignore proc->killed. // Assuming will not sleep too long: ignore proc->killed.
while((b->flags & (B_VALID|B_DIRTY)) != B_VALID) { while((b->flags & (B_VALID|B_DIRTY)) != B_VALID){
sleep(b, &idelock); sleep(b, &idelock);
} }

View file

@ -23,9 +23,11 @@ extern char end[]; // first address after kernel loaded from ELF file
void void
kinit(void) kinit(void)
{ {
char *p;
initlock(&kmem.lock, "kmem"); initlock(&kmem.lock, "kmem");
char *p = (char*)PGROUNDUP((uint)end); p = (char*)PGROUNDUP((uint)end);
for( ; p + PGSIZE - 1 < (char*) PHYSTOP; p += PGSIZE) for(; p + PGSIZE - 1 < (char*)PHYSTOP; p += PGSIZE)
kfree(p); kfree(p);
} }
@ -39,14 +41,14 @@ kfree(char *v)
{ {
struct run *r; struct run *r;
if(((uint) v) % PGSIZE || v < end || (uint)v >= PHYSTOP) if((uint)v % PGSIZE || v < end || (uint)v >= PHYSTOP)
panic("kfree"); panic("kfree");
// Fill with junk to catch dangling refs. // Fill with junk to catch dangling refs.
memset(v, 1, PGSIZE); memset(v, 1, PGSIZE);
acquire(&kmem.lock); acquire(&kmem.lock);
r = (struct run *) v; r = (struct run*)v;
r->next = kmem.freelist; r->next = kmem.freelist;
kmem.freelist = r; kmem.freelist = r;
release(&kmem.lock); release(&kmem.lock);
@ -56,7 +58,7 @@ kfree(char *v)
// Returns a pointer that the kernel can use. // Returns a pointer that the kernel can use.
// Returns 0 if the memory cannot be allocated. // Returns 0 if the memory cannot be allocated.
char* char*
kalloc() kalloc(void)
{ {
struct run *r; struct run *r;
@ -65,6 +67,6 @@ kalloc()
if(r) if(r)
kmem.freelist = r->next; kmem.freelist = r->next;
release(&kmem.lock); release(&kmem.lock);
return (char*) r; return (char*)r;
} }

30
main.c
View file

@ -7,7 +7,7 @@
static void bootothers(void); static void bootothers(void);
static void mpmain(void); static void mpmain(void);
void jkstack(void) __attribute__((noreturn)); void jmpkstack(void) __attribute__((noreturn));
void mainc(void); void mainc(void);
// Bootstrap processor starts running C code here. // Bootstrap processor starts running C code here.
@ -20,19 +20,20 @@ main(void)
lapicinit(mpbcpu()); lapicinit(mpbcpu());
seginit(); // set up segments seginit(); // set up segments
kinit(); // initialize memory allocator kinit(); // initialize memory allocator
jkstack(); // call mainc() on a properly-allocated stack jmpkstack(); // call mainc() on a properly-allocated stack
} }
void void
jkstack(void) jmpkstack(void)
{ {
char *kstack = kalloc(); char *kstack, *top;
if(!kstack)
panic("jkstack\n"); kstack = kalloc();
char *top = kstack + PGSIZE; if(kstack == 0)
asm volatile("movl %0,%%esp" : : "r" (top)); panic("jmpkstack kalloc");
asm volatile("call mainc"); top = kstack + PGSIZE;
panic("jkstack"); asm volatile("movl %0,%%esp; call mainc" : : "r" (top));
panic("jmpkstack");
} }
// Set up hardware and software. // Set up hardware and software.
@ -67,7 +68,7 @@ mainc(void)
static void static void
mpmain(void) mpmain(void)
{ {
if(cpunum() != mpbcpu()) { if(cpunum() != mpbcpu()){
seginit(); seginit();
lapicinit(cpunum()); lapicinit(cpunum());
} }
@ -87,9 +88,9 @@ bootothers(void)
struct cpu *c; struct cpu *c;
char *stack; char *stack;
// Write bootstrap code to unused memory at 0x7000. The linker has // Write bootstrap code to unused memory at 0x7000.
// placed the start of bootother.S there. // The linker has placed the image of bootother.S in _binary_bootother_start.
code = (uchar *) 0x7000; code = (uchar*)0x7000;
memmove(code, _binary_bootother_start, (uint)_binary_bootother_size); memmove(code, _binary_bootother_start, (uint)_binary_bootother_size);
for(c = cpus; c < cpus+ncpu; c++){ for(c = cpus; c < cpus+ncpu; c++){
@ -110,4 +111,3 @@ bootothers(void)
; ;
} }
} }

24
mkfs.c
View file

@ -35,7 +35,7 @@ ushort
xshort(ushort x) xshort(ushort x)
{ {
ushort y; ushort y;
uchar *a = (uchar*) &y; uchar *a = (uchar*)&y;
a[0] = x; a[0] = x;
a[1] = x >> 8; a[1] = x >> 8;
return y; return y;
@ -45,7 +45,7 @@ uint
xint(uint x) xint(uint x)
{ {
uint y; uint y;
uchar *a = (uchar*) &y; uchar *a = (uchar*)&y;
a[0] = x; a[0] = x;
a[1] = x >> 8; a[1] = x >> 8;
a[2] = x >> 16; a[2] = x >> 16;
@ -177,7 +177,7 @@ winode(uint inum, struct dinode *ip)
bn = i2b(inum); bn = i2b(inum);
rsect(bn, buf); rsect(bn, buf);
dip = ((struct dinode*) buf) + (inum % IPB); dip = ((struct dinode*)buf) + (inum % IPB);
*dip = *ip; *dip = *ip;
wsect(bn, buf); wsect(bn, buf);
} }
@ -191,7 +191,7 @@ rinode(uint inum, struct dinode *ip)
bn = i2b(inum); bn = i2b(inum);
rsect(bn, buf); rsect(bn, buf);
dip = ((struct dinode*) buf) + (inum % IPB); dip = ((struct dinode*)buf) + (inum % IPB);
*ip = *dip; *ip = *dip;
} }
@ -231,7 +231,7 @@ balloc(int used)
printf("balloc: first %d blocks have been allocated\n", used); printf("balloc: first %d blocks have been allocated\n", used);
assert(used < 512); assert(used < 512);
bzero(buf, 512); bzero(buf, 512);
for(i = 0; i < used; i++) { for(i = 0; i < used; i++){
buf[i/8] = buf[i/8] | (0x1 << (i%8)); buf[i/8] = buf[i/8] | (0x1 << (i%8));
} }
printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3); printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3);
@ -243,7 +243,7 @@ balloc(int used)
void void
iappend(uint inum, void *xp, int n) iappend(uint inum, void *xp, int n)
{ {
char *p = (char*) xp; char *p = (char*)xp;
uint fbn, off, n1; uint fbn, off, n1;
struct dinode din; struct dinode din;
char buf[512]; char buf[512];
@ -256,24 +256,24 @@ iappend(uint inum, void *xp, int n)
while(n > 0){ while(n > 0){
fbn = off / 512; fbn = off / 512;
assert(fbn < MAXFILE); assert(fbn < MAXFILE);
if(fbn < NDIRECT) { if(fbn < NDIRECT){
if(xint(din.addrs[fbn]) == 0) { if(xint(din.addrs[fbn]) == 0){
din.addrs[fbn] = xint(freeblock++); din.addrs[fbn] = xint(freeblock++);
usedblocks++; usedblocks++;
} }
x = xint(din.addrs[fbn]); x = xint(din.addrs[fbn]);
} else { } else {
if(xint(din.addrs[NDIRECT]) == 0) { if(xint(din.addrs[NDIRECT]) == 0){
// printf("allocate indirect block\n"); // printf("allocate indirect block\n");
din.addrs[NDIRECT] = xint(freeblock++); din.addrs[NDIRECT] = xint(freeblock++);
usedblocks++; usedblocks++;
} }
// printf("read indirect block\n"); // printf("read indirect block\n");
rsect(xint(din.addrs[NDIRECT]), (char*) indirect); rsect(xint(din.addrs[NDIRECT]), (char*)indirect);
if(indirect[fbn - NDIRECT] == 0) { if(indirect[fbn - NDIRECT] == 0){
indirect[fbn - NDIRECT] = xint(freeblock++); indirect[fbn - NDIRECT] = xint(freeblock++);
usedblocks++; usedblocks++;
wsect(xint(din.addrs[NDIRECT]), (char*) indirect); wsect(xint(din.addrs[NDIRECT]), (char*)indirect);
} }
x = xint(indirect[fbn-NDIRECT]); x = xint(indirect[fbn-NDIRECT]);
} }

14
mmu.h
View file

@ -98,18 +98,18 @@ struct segdesc {
// \--- PDX(la) --/ \--- PTX(la) --/ // \--- PDX(la) --/ \--- PTX(la) --/
// page directory index // page directory index
#define PDX(la) ((((uint) (la)) >> PDXSHIFT) & 0x3FF) #define PDX(la) (((uint)(la) >> PDXSHIFT) & 0x3FF)
// page table index // page table index
#define PTX(la) ((((uint) (la)) >> PTXSHIFT) & 0x3FF) #define PTX(la) (((uint)(la) >> PTXSHIFT) & 0x3FF)
// construct linear address from indexes and offset // construct linear address from indexes and offset
#define PGADDR(d, t, o) ((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) #define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// turn a kernel linear address into a physical address. // turn a kernel linear address into a physical address.
// all of the kernel data structures have linear and // all of the kernel data structures have linear and
// physical addresses that are equal. // physical addresses that are equal.
#define PADDR(a) ((uint) a) #define PADDR(a) ((uint)(a))
// Page directory and page table constants. // Page directory and page table constants.
#define NPDENTRIES 1024 // page directory entries per page directory #define NPDENTRIES 1024 // page directory entries per page directory
@ -136,7 +136,7 @@ struct segdesc {
#define PTE_MBZ 0x180 // Bits must be zero #define PTE_MBZ 0x180 // Bits must be zero
// Address in page table or page directory entry // Address in page table or page directory entry
#define PTE_ADDR(pte) ((uint) (pte) & ~0xFFF) #define PTE_ADDR(pte) ((uint)(pte) & ~0xFFF)
typedef uint pte_t; typedef uint pte_t;
@ -205,7 +205,7 @@ struct gatedesc {
// this interrupt/trap gate explicitly using an int instruction. // this interrupt/trap gate explicitly using an int instruction.
#define SETGATE(gate, istrap, sel, off, d) \ #define SETGATE(gate, istrap, sel, off, d) \
{ \ { \
(gate).off_15_0 = (uint) (off) & 0xffff; \ (gate).off_15_0 = (uint)(off) & 0xffff; \
(gate).cs = (sel); \ (gate).cs = (sel); \
(gate).args = 0; \ (gate).args = 0; \
(gate).rsv1 = 0; \ (gate).rsv1 = 0; \
@ -213,6 +213,6 @@ struct gatedesc {
(gate).s = 0; \ (gate).s = 0; \
(gate).dpl = (d); \ (gate).dpl = (d); \
(gate).p = 1; \ (gate).p = 1; \
(gate).off_31_16 = (uint) (off) >> 16; \ (gate).off_31_16 = (uint)(off) >> 16; \
} }

4
mp.c
View file

@ -113,8 +113,8 @@ mpinit(void)
switch(*p){ switch(*p){
case MPPROC: case MPPROC:
proc = (struct mpproc*)p; proc = (struct mpproc*)p;
if(ncpu != proc->apicid) { if(ncpu != proc->apicid){
cprintf("mpinit: ncpu=%d apicpid=%d", ncpu, proc->apicid); cprintf("mpinit: ncpu=%d apicpid=%d\n", ncpu, proc->apicid);
panic("mpinit"); panic("mpinit");
} }
if(proc->flags & MPBOOT) if(proc->flags & MPBOOT)

4
pipe.c
View file

@ -66,7 +66,7 @@ pipeclose(struct pipe *p, int writable)
p->readopen = 0; p->readopen = 0;
wakeup(&p->nwrite); wakeup(&p->nwrite);
} }
if(p->readopen == 0 && p->writeopen == 0) { if(p->readopen == 0 && p->writeopen == 0){
release(&p->lock); release(&p->lock);
kfree((char*)p); kfree((char*)p);
} else } else
@ -81,7 +81,7 @@ pipewrite(struct pipe *p, char *addr, int n)
acquire(&p->lock); acquire(&p->lock);
for(i = 0; i < n; i++){ for(i = 0; i < n; i++){
while(p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full
if(p->readopen == 0 || proc->killed){ if(p->readopen == 0 || proc->killed){
release(&p->lock); release(&p->lock);
return -1; return -1;

12
proc.c
View file

@ -120,7 +120,7 @@ userinit(void)
p = allocproc(); p = allocproc();
initproc = p; initproc = p;
if(!(p->pgdir = setupkvm())) if((p->pgdir = setupkvm()) == 0)
panic("userinit: out of memory?"); panic("userinit: out of memory?");
inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size); inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
p->sz = PGSIZE; p->sz = PGSIZE;
@ -144,12 +144,14 @@ userinit(void)
int int
growproc(int n) growproc(int n)
{ {
uint sz = proc->sz; uint sz;
sz = proc->sz;
if(n > 0){ if(n > 0){
if(!(sz = allocuvm(proc->pgdir, sz, sz + n))) if((sz = allocuvm(proc->pgdir, sz, sz + n)) == 0)
return -1; return -1;
} else if(n < 0){ } else if(n < 0){
if(!(sz = deallocuvm(proc->pgdir, sz, sz + n))) if((sz = deallocuvm(proc->pgdir, sz, sz + n)) == 0)
return -1; return -1;
} }
proc->sz = sz; proc->sz = sz;
@ -171,7 +173,7 @@ fork(void)
return -1; return -1;
// Copy process state from p. // Copy process state from p.
if(!(np->pgdir = copyuvm(proc->pgdir, proc->sz))){ if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){
kfree(np->kstack); kfree(np->kstack);
np->kstack = 0; np->kstack = 0;
np->state = UNUSED; np->state = UNUSED;

View file

@ -71,7 +71,7 @@ getcallerpcs(void *v, uint pcs[])
ebp = (uint*)v - 2; ebp = (uint*)v - 2;
for(i = 0; i < 10; i++){ for(i = 0; i < 10; i++){
if(ebp == 0 || ebp < (uint *) 0x100000 || ebp == (uint*)0xffffffff) if(ebp == 0 || ebp < (uint*)0x100000 || ebp == (uint*)0xffffffff)
break; break;
pcs[i] = ebp[1]; // saved %eip pcs[i] = ebp[1]; // saved %eip
ebp = (uint*)ebp[0]; // saved %ebp ebp = (uint*)ebp[0]; // saved %ebp

View file

@ -14,20 +14,19 @@
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int i; int fd, i;
char path[] = "stressfs0";
printf(1, "stressfs starting\n"); printf(1, "stressfs starting\n");
for(i = 0; i < 4; i++){ for(i = 0; i < 4; i++)
if(fork() > 0){ if(fork() > 0)
break; break;
}
}
printf(1, "%d\n", i); printf(1, "%d\n", i);
char path[] = "stressfs0";
path[8] += i; path[8] += i;
int fd = open(path, O_CREATE | O_RDWR); fd = open(path, O_CREATE | O_RDWR);
for(i = 0; i < 100; i++) for(i = 0; i < 100; i++)
printf(fd, "%d\n", i); printf(fd, "%d\n", i);
close(fd); close(fd);

View file

@ -32,8 +32,8 @@ fetchstr(struct proc *p, uint addr, char **pp)
if(addr >= p->sz) if(addr >= p->sz)
return -1; return -1;
*pp = (char *) addr; *pp = (char*)addr;
ep = (char *) p->sz; ep = (char*)p->sz;
for(s = *pp; s < ep; s++) for(s = *pp; s < ep; s++)
if(*s == 0) if(*s == 0)
return s - *pp; return s - *pp;
@ -44,8 +44,7 @@ fetchstr(struct proc *p, uint addr, char **pp)
int int
argint(int n, int *ip) argint(int n, int *ip)
{ {
int x = fetchint(proc, proc->tf->esp + 4 + 4*n, ip); return fetchint(proc, proc->tf->esp + 4 + 4*n, ip);
return x;
} }
// Fetch the nth word-sized system call argument as a pointer // Fetch the nth word-sized system call argument as a pointer
@ -60,7 +59,7 @@ argptr(int n, char **pp, int size)
return -1; return -1;
if((uint)i >= proc->sz || (uint)i+size >= proc->sz) if((uint)i >= proc->sz || (uint)i+size >= proc->sz)
return -1; return -1;
*pp = (char *) i; *pp = (char*)i;
return 0; return 0;
} }

View file

@ -348,7 +348,7 @@ sys_exec(void)
int i; int i;
uint uargv, uarg; uint uargv, uarg;
if(argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0) { if(argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0){
return -1; return -1;
} }
memset(argv, 0, sizeof(argv)); memset(argv, 0, sizeof(argv));

2
ulib.c
View file

@ -45,7 +45,7 @@ strchr(const char *s, char c)
{ {
for(; *s; s++) for(; *s; s++)
if(*s == c) if(*s == c)
return (char*) s; return (char*)s;
return 0; return 0;
} }

View file

@ -26,7 +26,7 @@ free(void *ap)
{ {
Header *bp, *p; Header *bp, *p;
bp = (Header*) ap - 1; bp = (Header*)ap - 1;
for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break; break;
@ -52,7 +52,7 @@ morecore(uint nu)
if(nu < 4096) if(nu < 4096)
nu = 4096; nu = 4096;
p = sbrk(nu * sizeof(Header)); p = sbrk(nu * sizeof(Header));
if(p == (char*) -1) if(p == (char*)-1)
return 0; return 0;
hp = (Header*)p; hp = (Header*)p;
hp->s.size = nu; hp->s.size = nu;
@ -81,7 +81,7 @@ malloc(uint nbytes)
p->s.size = nunits; p->s.size = nunits;
} }
freep = prevp; freep = prevp;
return (void*) (p + 1); return (void*)(p + 1);
} }
if(p == freep) if(p == freep)
if((p = morecore(nunits)) == 0) if((p = morecore(nunits)) == 0)

4
user.h
View file

@ -18,10 +18,10 @@ int link(char*, char*);
int mkdir(char*); int mkdir(char*);
int chdir(char*); int chdir(char*);
int dup(int); int dup(int);
int getpid(); int getpid(void);
char* sbrk(int); char* sbrk(int);
int sleep(int); int sleep(int);
int uptime(); int uptime(void);
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);

View file

@ -47,12 +47,12 @@ writetest(void)
printf(stdout, "error: creat small failed!\n"); printf(stdout, "error: creat small failed!\n");
exit(); exit();
} }
for(i = 0; i < 100; i++) { for(i = 0; i < 100; i++){
if(write(fd, "aaaaaaaaaa", 10) != 10) { if(write(fd, "aaaaaaaaaa", 10) != 10){
printf(stdout, "error: write aa %d new file failed\n", i); printf(stdout, "error: write aa %d new file failed\n", i);
exit(); exit();
} }
if(write(fd, "bbbbbbbbbb", 10) != 10) { if(write(fd, "bbbbbbbbbb", 10) != 10){
printf(stdout, "error: write bb %d new file failed\n", i); printf(stdout, "error: write bb %d new file failed\n", i);
exit(); exit();
} }
@ -67,7 +67,7 @@ writetest(void)
exit(); exit();
} }
i = read(fd, buf, 2000); i = read(fd, buf, 2000);
if(i == 2000) { if(i == 2000){
printf(stdout, "read succeeded ok\n"); printf(stdout, "read succeeded ok\n");
} else { } else {
printf(stdout, "read failed\n"); printf(stdout, "read failed\n");
@ -75,7 +75,7 @@ writetest(void)
} }
close(fd); close(fd);
if(unlink("small") < 0) { if(unlink("small") < 0){
printf(stdout, "unlink small failed\n"); printf(stdout, "unlink small failed\n");
exit(); exit();
} }
@ -95,9 +95,9 @@ writetest1(void)
exit(); exit();
} }
for(i = 0; i < MAXFILE; i++) { for(i = 0; i < MAXFILE; i++){
((int*) buf)[0] = i; ((int*)buf)[0] = i;
if(write(fd, buf, 512) != 512) { if(write(fd, buf, 512) != 512){
printf(stdout, "error: write big file failed\n", i); printf(stdout, "error: write big file failed\n", i);
exit(); exit();
} }
@ -112,19 +112,19 @@ writetest1(void)
} }
n = 0; n = 0;
for(;;) { for(;;){
i = read(fd, buf, 512); i = read(fd, buf, 512);
if(i == 0) { if(i == 0){
if(n == MAXFILE - 1) { if(n == MAXFILE - 1){
printf(stdout, "read only %d blocks from big", n); printf(stdout, "read only %d blocks from big", n);
exit(); exit();
} }
break; break;
} else if(i != 512) { } else if(i != 512){
printf(stdout, "read failed %d\n", i); printf(stdout, "read failed %d\n", i);
exit(); exit();
} }
if(((int*)buf)[0] != n) { if(((int*)buf)[0] != n){
printf(stdout, "read content of block %d is %d\n", printf(stdout, "read content of block %d is %d\n",
n, ((int*)buf)[0]); n, ((int*)buf)[0]);
exit(); exit();
@ -132,7 +132,7 @@ writetest1(void)
n++; n++;
} }
close(fd); close(fd);
if(unlink("big") < 0) { if(unlink("big") < 0){
printf(stdout, "unlink big failed\n"); printf(stdout, "unlink big failed\n");
exit(); exit();
} }
@ -148,14 +148,14 @@ createtest(void)
name[0] = 'a'; name[0] = 'a';
name[2] = '\0'; name[2] = '\0';
for(i = 0; i < 52; i++) { for(i = 0; i < 52; i++){
name[1] = '0' + i; name[1] = '0' + i;
fd = open(name, O_CREATE|O_RDWR); fd = open(name, O_CREATE|O_RDWR);
close(fd); close(fd);
} }
name[0] = 'a'; name[0] = 'a';
name[2] = '\0'; name[2] = '\0';
for(i = 0; i < 52; i++) { for(i = 0; i < 52; i++){
name[1] = '0' + i; name[1] = '0' + i;
unlink(name); unlink(name);
} }
@ -166,22 +166,22 @@ void dirtest(void)
{ {
printf(stdout, "mkdir test\n"); printf(stdout, "mkdir test\n");
if(mkdir("dir0") < 0) { if(mkdir("dir0") < 0){
printf(stdout, "mkdir failed\n"); printf(stdout, "mkdir failed\n");
exit(); exit();
} }
if(chdir("dir0") < 0) { if(chdir("dir0") < 0){
printf(stdout, "chdir dir0 failed\n"); printf(stdout, "chdir dir0 failed\n");
exit(); exit();
} }
if(chdir("..") < 0) { if(chdir("..") < 0){
printf(stdout, "chdir .. failed\n"); printf(stdout, "chdir .. failed\n");
exit(); exit();
} }
if(unlink("dir0") < 0) { if(unlink("dir0") < 0){
printf(stdout, "unlink dir0 failed\n"); printf(stdout, "unlink dir0 failed\n");
exit(); exit();
} }
@ -192,7 +192,7 @@ void
exectest(void) exectest(void)
{ {
printf(stdout, "exec test\n"); printf(stdout, "exec test\n");
if(exec("echo", echoargv) < 0) { if(exec("echo", echoargv) < 0){
printf(stdout, "exec echo failed\n"); printf(stdout, "exec echo failed\n");
exit(); exit();
} }
@ -330,17 +330,17 @@ mem(void)
ppid = getpid(); ppid = getpid();
if((pid = fork()) == 0){ if((pid = fork()) == 0){
m1 = 0; m1 = 0;
while((m2 = malloc(10001)) != 0) { while((m2 = malloc(10001)) != 0){
*(char**) m2 = m1; *(char**)m2 = m1;
m1 = m2; m1 = m2;
} }
while(m1) { while(m1){
m2 = *(char**)m1; m2 = *(char**)m1;
free(m1); free(m1);
m1 = m2; m1 = m2;
} }
m1 = malloc(1024*20); m1 = malloc(1024*20);
if(m1 == 0) { if(m1 == 0){
printf(1, "couldn't allocate mem?!!\n"); printf(1, "couldn't allocate mem?!!\n");
kill(ppid); kill(ppid);
exit(); exit();
@ -1237,16 +1237,18 @@ forktest(void)
void void
sbrktest(void) sbrktest(void)
{ {
int pid; int fds[2], pid, pids[32], ppid;
char *oldbrk = sbrk(0); char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch;
uint amt;
printf(stdout, "sbrk test\n"); printf(stdout, "sbrk test\n");
oldbrk = sbrk(0);
// can one sbrk() less than a page? // can one sbrk() less than a page?
char *a = sbrk(0); a = sbrk(0);
int i; int i;
for(i = 0; i < 5000; i++){ for(i = 0; i < 5000; i++){
char *b = sbrk(1); b = sbrk(1);
if(b != a){ if(b != a){
printf(stdout, "sbrk test failed %d %x %x\n", i, a, b); printf(stdout, "sbrk test failed %d %x %x\n", i, a, b);
exit(); exit();
@ -1259,7 +1261,7 @@ sbrktest(void)
printf(stdout, "sbrk test fork failed\n"); printf(stdout, "sbrk test fork failed\n");
exit(); exit();
} }
char *c = sbrk(1); c = sbrk(1);
c = sbrk(1); c = sbrk(1);
if(c != a + 1){ if(c != a + 1){
printf(stdout, "sbrk test failed post-fork\n"); printf(stdout, "sbrk test failed post-fork\n");
@ -1271,18 +1273,18 @@ sbrktest(void)
// can one allocate the full 640K? // can one allocate the full 640K?
a = sbrk(0); a = sbrk(0);
uint amt = (640 * 1024) - (uint) a; amt = (640 * 1024) - (uint)a;
char *p = sbrk(amt); p = sbrk(amt);
if(p != a){ if(p != a){
printf(stdout, "sbrk test failed 640K test, p %x a %x\n", p, a); printf(stdout, "sbrk test failed 640K test, p %x a %x\n", p, a);
exit(); exit();
} }
char *lastaddr = (char *)(640 * 1024 - 1); lastaddr = (char*)(640 * 1024 - 1);
*lastaddr = 99; *lastaddr = 99;
// is one forbidden from allocating more than 640K? // is one forbidden from allocating more than 640K?
c = sbrk(4096); c = sbrk(4096);
if(c != (char *) 0xffffffff){ if(c != (char*)0xffffffff){
printf(stdout, "sbrk allocated more than 640K, c %x\n", c); printf(stdout, "sbrk allocated more than 640K, c %x\n", c);
exit(); exit();
} }
@ -1290,7 +1292,7 @@ sbrktest(void)
// can one de-allocate? // can one de-allocate?
a = sbrk(0); a = sbrk(0);
c = sbrk(-4096); c = sbrk(-4096);
if(c == (char *) 0xffffffff){ if(c == (char*)0xffffffff){
printf(stdout, "sbrk could not deallocate\n"); printf(stdout, "sbrk could not deallocate\n");
exit(); exit();
} }
@ -1314,15 +1316,15 @@ sbrktest(void)
} }
c = sbrk(4096); c = sbrk(4096);
if(c != (char *) 0xffffffff){ if(c != (char*)0xffffffff){
printf(stdout, "sbrk was able to re-allocate beyond 640K, c %x\n", c); printf(stdout, "sbrk was able to re-allocate beyond 640K, c %x\n", c);
exit(); exit();
} }
// can we read the kernel's memory? // can we read the kernel's memory?
for(a = (char*)(640*1024); a < (char *)2000000; a += 50000){ for(a = (char*)(640*1024); a < (char*)2000000; a += 50000){
int ppid = getpid(); ppid = getpid();
int pid = fork(); pid = fork();
if(pid < 0){ if(pid < 0){
printf(stdout, "fork failed\n"); printf(stdout, "fork failed\n");
exit(); exit();
@ -1338,21 +1340,18 @@ sbrktest(void)
// if we run the system out of memory, does it clean up the last // if we run the system out of memory, does it clean up the last
// failed allocation? // failed allocation?
sbrk(-(sbrk(0) - oldbrk)); sbrk(-(sbrk(0) - oldbrk));
int pids[32];
int fds[2];
if(pipe(fds) != 0){ if(pipe(fds) != 0){
printf(1, "pipe() failed\n"); printf(1, "pipe() failed\n");
exit(); exit();
} }
for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
if((pids[i] = fork()) == 0) { if((pids[i] = fork()) == 0){
// allocate the full 640K // allocate the full 640K
sbrk((640 * 1024) - (uint)sbrk(0)); sbrk((640 * 1024) - (uint)sbrk(0));
write(fds[1], "x", 1); write(fds[1], "x", 1);
// sit around until killed // sit around until killed
for(;;) sleep(1000); for(;;) sleep(1000);
} }
char scratch;
if(pids[i] != -1) if(pids[i] != -1)
read(fds[0], &scratch, 1); read(fds[0], &scratch, 1);
} }
@ -1365,7 +1364,7 @@ sbrktest(void)
kill(pids[i]); kill(pids[i]);
wait(); wait();
} }
if(c == (char*)0xffffffff) { if(c == (char*)0xffffffff){
printf(stdout, "failed sbrk leaked memory\n"); printf(stdout, "failed sbrk leaked memory\n");
exit(); exit();
} }
@ -1392,14 +1391,14 @@ validateint(int *p)
void void
validatetest(void) validatetest(void)
{ {
int hi = 1100*1024; int hi, pid;
uint p;
printf(stdout, "validate test\n"); printf(stdout, "validate test\n");
hi = 1100*1024;
uint p; for(p = 0; p <= (uint)hi; p += 4096){
for (p = 0; p <= (uint)hi; p += 4096) { if((pid = fork()) == 0){
int pid;
if ((pid = fork()) == 0) {
// try to crash the kernel by passing in a badly placed integer // try to crash the kernel by passing in a badly placed integer
validateint((int*)p); validateint((int*)p);
exit(); exit();
@ -1410,7 +1409,7 @@ validatetest(void)
wait(); wait();
// try to crash the kernel by passing in a bad string pointer // try to crash the kernel by passing in a bad string pointer
if (link("nosuchfile", (char*)p) != -1) { if(link("nosuchfile", (char*)p) != -1){
printf(stdout, "link should not succeed\n"); printf(stdout, "link should not succeed\n");
exit(); exit();
} }
@ -1425,6 +1424,7 @@ void
bsstest(void) bsstest(void)
{ {
int i; int i;
printf(stdout, "bss test\n"); printf(stdout, "bss test\n");
for(i = 0; i < sizeof(uninit); i++){ for(i = 0; i < sizeof(uninit); i++){
if(uninit[i] != '\0'){ if(uninit[i] != '\0'){

143
vm.c
View file

@ -42,23 +42,21 @@ seginit(void)
static pte_t * static pte_t *
walkpgdir(pde_t *pgdir, const void *va, int create) walkpgdir(pde_t *pgdir, const void *va, int create)
{ {
uint r;
pde_t *pde; pde_t *pde;
pte_t *pgtab; pte_t *pgtab;
pde = &pgdir[PDX(va)]; pde = &pgdir[PDX(va)];
if(*pde & PTE_P){ if(*pde & PTE_P){
pgtab = (pte_t*) PTE_ADDR(*pde); pgtab = (pte_t*)PTE_ADDR(*pde);
} else if(!create || !(r = (uint) kalloc())) } else {
return 0; if(!create || (pgtab = (pte_t*)kalloc()) == 0)
else { return 0;
pgtab = (pte_t*) r;
// Make sure all those PTE_P bits are zero. // Make sure all those PTE_P bits are zero.
memset(pgtab, 0, PGSIZE); memset(pgtab, 0, PGSIZE);
// The permissions here are overly generous, but they can // The permissions here are overly generous, but they can
// be further restricted by the permissions in the page table // be further restricted by the permissions in the page table
// entries, if necessary. // entries, if necessary.
*pde = PADDR(r) | PTE_P | PTE_W | PTE_U; *pde = PADDR(pgtab) | PTE_P | PTE_W | PTE_U;
} }
return &pgtab[PTX(va)]; return &pgtab[PTX(va)];
} }
@ -69,13 +67,16 @@ walkpgdir(pde_t *pgdir, const void *va, int create)
static int static int
mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm) mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
{ {
char *a = PGROUNDDOWN(la); char *a, *last;
char *last = PGROUNDDOWN(la + size - 1); pte_t *pte;
a = PGROUNDDOWN(la);
last = PGROUNDDOWN(la + size - 1);
while(1){ for(;;){
pte_t *pte = walkpgdir(pgdir, a, 1); pte = walkpgdir(pgdir, a, 1);
if(pte == 0) if(pte == 0)
return 0; return -1;
if(*pte & PTE_P) if(*pte & PTE_P)
panic("remap"); panic("remap");
*pte = pa | perm | PTE_P; *pte = pa | perm | PTE_P;
@ -84,7 +85,7 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
a += PGSIZE; a += PGSIZE;
pa += PGSIZE; pa += PGSIZE;
} }
return 1; return 0;
} }
// The mappings from logical to linear are one to one (i.e., // The mappings from logical to linear are one to one (i.e.,
@ -122,23 +123,26 @@ kvmalloc(void)
pde_t* pde_t*
setupkvm(void) setupkvm(void)
{ {
pde_t *pgdir;
extern char etext[]; extern char etext[];
char *rwstart = PGROUNDDOWN(etext); char *rwstart;
uint rwlen = (uint)rwstart - 0x100000; pde_t *pgdir;
uint rwlen;
rwstart = PGROUNDDOWN(etext);
rwlen = (uint)rwstart - 0x100000;
// Allocate page directory // Allocate page directory
if(!(pgdir = (pde_t *) kalloc())) if((pgdir = (pde_t*)kalloc()) == 0)
return 0; return 0;
memset(pgdir, 0, PGSIZE); memset(pgdir, 0, PGSIZE);
if(// Map IO space from 640K to 1Mbyte if(// Map IO space from 640K to 1Mbyte
!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W) || mappages(pgdir, (void*)USERTOP, 0x60000, USERTOP, PTE_W) < 0 ||
// Map kernel instructions // Map kernel instructions
!mappages(pgdir, (void *)0x100000, rwlen, 0x100000, 0) || mappages(pgdir, (void*)0x100000, rwlen, 0x100000, 0) < 0 ||
// Map kernel data and free memory pool // Map kernel data and free memory pool
!mappages(pgdir, rwstart, PHYSTOP-(uint)rwstart, (uint)rwstart, PTE_W) || mappages(pgdir, rwstart, PHYSTOP-(uint)rwstart, (uint)rwstart, PTE_W) < 0 ||
// Map devices such as ioapic, lapic, ... // Map devices such as ioapic, lapic, ...
!mappages(pgdir, (void *)0xFE000000, 0x2000000, 0xFE000000, PTE_W)) mappages(pgdir, (void*)0xFE000000, 0x2000000, 0xFE000000, PTE_W) < 0)
return 0; return 0;
return pgdir; return pgdir;
} }
@ -189,14 +193,15 @@ switchuvm(struct proc *p)
// processes directly. // processes directly.
char* char*
uva2ka(pde_t *pgdir, char *uva) uva2ka(pde_t *pgdir, char *uva)
{ {
pte_t *pte = walkpgdir(pgdir, uva, 0); pte_t *pte;
pte = walkpgdir(pgdir, uva, 0);
if((*pte & PTE_P) == 0) if((*pte & PTE_P) == 0)
return 0; return 0;
if((*pte & PTE_U) == 0) if((*pte & PTE_U) == 0)
return 0; return 0;
uint pa = PTE_ADDR(*pte); return (char*)PTE_ADDR(*pte);
return (char *)pa;
} }
// Load the initcode into address 0 of pgdir. // Load the initcode into address 0 of pgdir.
@ -204,9 +209,11 @@ uva2ka(pde_t *pgdir, char *uva)
void void
inituvm(pde_t *pgdir, char *init, uint sz) inituvm(pde_t *pgdir, char *init, uint sz)
{ {
char *mem = kalloc(); char *mem;
if (sz >= PGSIZE)
if(sz >= PGSIZE)
panic("inituvm: more than a page"); panic("inituvm: more than a page");
mem = kalloc();
memset(mem, 0, PGSIZE); memset(mem, 0, PGSIZE);
mappages(pgdir, 0, PGSIZE, PADDR(mem), PTE_W|PTE_U); mappages(pgdir, 0, PGSIZE, PADDR(mem), PTE_W|PTE_U);
memmove(mem, init, sz); memmove(mem, init, sz);
@ -223,15 +230,17 @@ loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz)
if((uint)addr % PGSIZE != 0) if((uint)addr % PGSIZE != 0)
panic("loaduvm: addr must be page aligned\n"); panic("loaduvm: addr must be page aligned\n");
for(i = 0; i < sz; i += PGSIZE){ for(i = 0; i < sz; i += PGSIZE){
if(!(pte = walkpgdir(pgdir, addr+i, 0))) if((pte = walkpgdir(pgdir, addr+i, 0)) == 0)
panic("loaduvm: address should exist\n"); panic("loaduvm: address should exist\n");
pa = PTE_ADDR(*pte); pa = PTE_ADDR(*pte);
if(sz - i < PGSIZE) n = sz - i; if(sz - i < PGSIZE)
else n = PGSIZE; n = sz - i;
if(readi(ip, (char *)pa, offset+i, n) != n) else
return 0; n = PGSIZE;
if(readi(ip, (char*)pa, offset+i, n) != n)
return -1;
} }
return 1; return 0;
} }
// Allocate memory to the process to bring its size from oldsz to // Allocate memory to the process to bring its size from oldsz to
@ -241,12 +250,17 @@ loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz)
int int
allocuvm(pde_t *pgdir, uint oldsz, uint newsz) allocuvm(pde_t *pgdir, uint oldsz, uint newsz)
{ {
char *a, *last, *mem;
if(newsz > USERTOP) if(newsz > USERTOP)
return 0; return 0;
char *a = (char *)PGROUNDUP(oldsz); if(newsz < oldsz)
char *last = PGROUNDDOWN(newsz - 1); return oldsz;
for (; a <= last; a += PGSIZE){
char *mem = kalloc(); a = (char*)PGROUNDUP(oldsz);
last = PGROUNDDOWN(newsz - 1);
for(; a <= last; a += PGSIZE){
mem = kalloc();
if(mem == 0){ if(mem == 0){
cprintf("allocuvm out of memory\n"); cprintf("allocuvm out of memory\n");
deallocuvm(pgdir, newsz, oldsz); deallocuvm(pgdir, newsz, oldsz);
@ -255,7 +269,7 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz)
memset(mem, 0, PGSIZE); memset(mem, 0, PGSIZE);
mappages(pgdir, a, PGSIZE, PADDR(mem), PTE_W|PTE_U); mappages(pgdir, a, PGSIZE, PADDR(mem), PTE_W|PTE_U);
} }
return newsz > oldsz ? newsz : oldsz; return newsz;
} }
// Deallocate user pages to bring the process size from oldsz to // Deallocate user pages to bring the process size from oldsz to
@ -265,19 +279,26 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz)
int int
deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) deallocuvm(pde_t *pgdir, uint oldsz, uint newsz)
{ {
char *a = (char *)PGROUNDUP(newsz); char *a, *last;
char *last = PGROUNDDOWN(oldsz - 1); pte_t *pte;
uint pa;
if(newsz >= oldsz)
return oldsz;
a = (char*)PGROUNDUP(newsz);
last = PGROUNDDOWN(oldsz - 1);
for(; a <= last; a += PGSIZE){ for(; a <= last; a += PGSIZE){
pte_t *pte = walkpgdir(pgdir, a, 0); pte = walkpgdir(pgdir, a, 0);
if(pte && (*pte & PTE_P) != 0){ if(pte && (*pte & PTE_P) != 0){
uint pa = PTE_ADDR(*pte); pa = PTE_ADDR(*pte);
if(pa == 0) if(pa == 0)
panic("kfree"); panic("kfree");
kfree((void *) pa); kfree((char*)pa);
*pte = 0; *pte = 0;
} }
} }
return newsz < oldsz ? newsz : oldsz; return newsz;
} }
// Free a page table and all the physical memory pages // Free a page table and all the physical memory pages
@ -287,14 +308,14 @@ freevm(pde_t *pgdir)
{ {
uint i; uint i;
if(!pgdir) if(pgdir == 0)
panic("freevm: no pgdir"); panic("freevm: no pgdir");
deallocuvm(pgdir, USERTOP, 0); deallocuvm(pgdir, USERTOP, 0);
for(i = 0; i < NPDENTRIES; i++){ for(i = 0; i < NPDENTRIES; i++){
if(pgdir[i] & PTE_P) if(pgdir[i] & PTE_P)
kfree((void *) PTE_ADDR(pgdir[i])); kfree((char*)PTE_ADDR(pgdir[i]));
} }
kfree((void *) pgdir); kfree((char*)pgdir);
} }
// Given a parent process's page table, create a copy // Given a parent process's page table, create a copy
@ -302,22 +323,23 @@ freevm(pde_t *pgdir)
pde_t* pde_t*
copyuvm(pde_t *pgdir, uint sz) copyuvm(pde_t *pgdir, uint sz)
{ {
pde_t *d = setupkvm(); pde_t *d;
pte_t *pte; pte_t *pte;
uint pa, i; uint pa, i;
char *mem; char *mem;
if(!d) return 0; if((d = setupkvm()) == 0)
return 0;
for(i = 0; i < sz; i += PGSIZE){ for(i = 0; i < sz; i += PGSIZE){
if(!(pte = walkpgdir(pgdir, (void *)i, 0))) if((pte = walkpgdir(pgdir, (void*)i, 0)) == 0)
panic("copyuvm: pte should exist\n"); panic("copyuvm: pte should exist\n");
if(!(*pte & PTE_P)) if(!(*pte & PTE_P))
panic("copyuvm: page not present\n"); panic("copyuvm: page not present\n");
pa = PTE_ADDR(*pte); pa = PTE_ADDR(*pte);
if(!(mem = kalloc())) if((mem = kalloc()) == 0)
goto bad; goto bad;
memmove(mem, (char *)pa, PGSIZE); memmove(mem, (char*)pa, PGSIZE);
if(!mappages(d, (void *)i, PGSIZE, PADDR(mem), PTE_W|PTE_U)) if(mappages(d, (void*)i, PGSIZE, PADDR(mem), PTE_W|PTE_U) < 0)
goto bad; goto bad;
} }
return d; return d;
@ -334,13 +356,16 @@ bad:
int int
copyout(pde_t *pgdir, uint va, void *xbuf, uint len) copyout(pde_t *pgdir, uint va, void *xbuf, uint len)
{ {
char *buf = (char *) xbuf; char *buf, *pa0;
uint n, va0;
buf = (char*)xbuf;
while(len > 0){ while(len > 0){
uint va0 = (uint)PGROUNDDOWN(va); va0 = (uint)PGROUNDDOWN(va);
char *pa0 = uva2ka(pgdir, (char*) va0); pa0 = uva2ka(pgdir, (char*)va0);
if(pa0 == 0) if(pa0 == 0)
return 0; return -1;
uint n = PGSIZE - (va - va0); n = PGSIZE - (va - va0);
if(n > len) if(n > len)
n = len; n = len;
memmove(pa0 + (va - va0), buf, n); memmove(pa0 + (va - va0), buf, n);
@ -348,5 +373,5 @@ copyout(pde_t *pgdir, uint va, void *xbuf, uint len)
buf += n; buf += n;
va = va0 + PGSIZE; va = va0 + PGSIZE;
} }
return 1; return 0;
} }