diff --git a/Makefile b/Makefile index 5943a7ee15..fe091dbf79 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,7 @@ PRINT = runoff.list $(FILES) xv6.pdf: $(PRINT) ./runoff + ls -l xv6.pdf print: xv6.pdf diff --git a/bootother.S b/bootother.S index 47f547e7e5..9005d48346 100644 --- a/bootother.S +++ b/bootother.S @@ -38,7 +38,7 @@ start: //PAGEBREAK! # Switch from real to protected mode, using a bootstrap GDT # and segment translation that makes virtual addresses - # identical to their physical addresses, so that the + # identical to physical addresses, so that the # effective memory map does not change during the switch. lgdt gdtdesc movl %cr0, %eax @@ -47,10 +47,10 @@ start: # Jump to next instruction, but in 32-bit code segment. # Switches processor into 32-bit mode. - ljmp $(SEG_KCODE<<3), $protcseg + ljmp $(SEG_KCODE<<3), $start32 - .code32 # Assemble for 32-bit mode -protcseg: +.code32 # Assemble for 32-bit mode +start32: # Set up the protected-mode data segment registers movw $(SEG_KDATA<<3), %ax # Our data segment selector movw %ax, %ds # -> DS: Data Segment @@ -60,11 +60,11 @@ protcseg: movw %ax, %fs # -> FS movw %ax, %gs # -> GS + # Set up the stack pointer and call into C. movl start-4, %esp - movl start-8, %eax - call *%eax + call *(start-8) - # If bootmain returns (it shouldn't), trigger a Bochs + # If the call returns (it shouldn't), trigger a Bochs # breakpoint if running under Bochs, then loop. movw $0x8a00, %ax # 0x8a00 -> port 0x8a00 movw %ax, %dx diff --git a/console.c b/console.c index 6834c6a1ef..9d2ef607f8 100644 --- a/console.c +++ b/console.c @@ -7,69 +7,22 @@ #include "param.h" #include "traps.h" #include "spinlock.h" -#include "dev.h" +#include "fs.h" +#include "file.h" #include "mmu.h" #include "proc.h" #include "x86.h" -#define CRTPORT 0x3d4 -#define BACKSPACE 0x100 +static void consputc(int); -static ushort *crt = (ushort*)0xb8000; // CGA memory +static int panicked = 0; static struct { struct spinlock lock; int locking; } cons; -static int panicked = 0; - static void -cgaputc(int c) -{ - int pos; - - // Cursor position: col + 80*row. - outb(CRTPORT, 14); - pos = inb(CRTPORT+1) << 8; - outb(CRTPORT, 15); - pos |= inb(CRTPORT+1); - - if(c == '\n') - pos += 80 - pos%80; - else if(c == BACKSPACE){ - if(pos > 0) - crt[--pos] = ' ' | 0x0700; - } else - crt[pos++] = (c&0xff) | 0x0700; // black on white - - if((pos/80) >= 24){ // Scroll up. - memmove(crt, crt+80, sizeof(crt[0])*23*80); - pos -= 80; - memset(crt+pos, 0, sizeof(crt[0])*(24*80 - pos)); - } - - outb(CRTPORT, 14); - outb(CRTPORT+1, pos>>8); - outb(CRTPORT, 15); - outb(CRTPORT+1, pos); - crt[pos] = ' ' | 0x0700; -} - -void -consputc(int c) -{ - if(panicked){ - cli(); - for(;;) - ; - } - - uartputc(c); - cgaputc(c); -} - -void printint(int xx, int base, int sgn) { static char digits[] = "0123456789abcdef"; @@ -79,10 +32,9 @@ printint(int xx, int base, int sgn) if(sgn && xx < 0){ neg = 1; - x = 0 - xx; - } else { + x = -xx; + } else x = xx; - } do{ buf[i++] = digits[x % base]; @@ -94,6 +46,7 @@ printint(int xx, int base, int sgn) consputc(buf[i]); } +//PAGEBREAK: 50 // Print to the console. only understands %d, %x, %p, %s. void cprintf(char *fmt, ...) @@ -108,42 +61,35 @@ cprintf(char *fmt, ...) argp = (uint*)(void*)&fmt + 1; state = 0; - for(i = 0; fmt[i]; i++){ - c = fmt[i] & 0xff; - switch(state){ - case 0: - if(c == '%') - state = '%'; - else - consputc(c); + for(i = 0; (c = fmt[i] & 0xff) != 0; i++){ + if(c != '%'){ + consputc(c); + continue; + } + c = fmt[++i] & 0xff; + if(c == 0) + break; + switch(c){ + case 'd': + printint(*argp++, 10, 1); + break; + case 'x': + case 'p': + printint(*argp++, 16, 0); + break; + case 's': + if((s = (char*)*argp++) == 0) + s = "(null)"; + for(; *s; s++) + consputc(*s); break; - case '%': - switch(c){ - case 'd': - printint(*argp++, 10, 1); - break; - case 'x': - case 'p': - printint(*argp++, 16, 0); - break; - case 's': - s = (char*)*argp++; - if(s == 0) - s = "(null)"; - for(; *s; s++) - consputc(*s); - break; - case '%': - consputc('%'); - break; - default: - // Print unknown % sequence to draw attention. - consputc('%'); - consputc(c); - break; - } - state = 0; + consputc('%'); + break; + default: + // Print unknown % sequence to draw attention. + consputc('%'); + consputc(c); break; } } @@ -152,21 +98,76 @@ cprintf(char *fmt, ...) release(&cons.lock); } -int -consolewrite(struct inode *ip, char *buf, int n) +void +panic(char *s) { int i; + uint pcs[10]; + + cli(); + cons.locking = 0; + cprintf("cpu%d: panic: ", cpu()); + cprintf(s); + cprintf("\n"); + getcallerpcs(&s, pcs); + for(i=0; i<10; i++) + cprintf(" %p", pcs[i]); + panicked = 1; // freeze other CPU + for(;;) + ; +} - iunlock(ip); - acquire(&cons.lock); - for(i = 0; i < n; i++) - consputc(buf[i] & 0xff); - release(&cons.lock); - ilock(ip); +//PAGEBREAK: 50 +#define BACKSPACE 0x100 +#define CRTPORT 0x3d4 +static ushort *crt = (ushort*)0xb8000; // CGA memory - return n; +static void +cgaputc(int c) +{ + int pos; + + // Cursor position: col + 80*row. + outb(CRTPORT, 14); + pos = inb(CRTPORT+1) << 8; + outb(CRTPORT, 15); + pos |= inb(CRTPORT+1); + + if(c == '\n') + pos += 80 - pos%80; + else if(c == BACKSPACE){ + if(pos > 0) + crt[--pos] = ' ' | 0x0700; + } else + crt[pos++] = (c&0xff) | 0x0700; // black on white + + if((pos/80) >= 24){ // Scroll up. + memmove(crt, crt+80, sizeof(crt[0])*23*80); + pos -= 80; + memset(crt+pos, 0, sizeof(crt[0])*(24*80 - pos)); + } + + outb(CRTPORT, 14); + outb(CRTPORT+1, pos>>8); + outb(CRTPORT, 15); + outb(CRTPORT+1, pos); + crt[pos] = ' ' | 0x0700; +} + +void +consputc(int c) +{ + if(panicked){ + cli(); + for(;;) + ; + } + + uartputc(c); + cgaputc(c); } +//PAGEBREAK: 50 #define INPUT_BUF 128 struct { struct spinlock lock; @@ -255,6 +256,21 @@ consoleread(struct inode *ip, char *dst, int n) return target - n; } +int +consolewrite(struct inode *ip, char *buf, int n) +{ + int i; + + iunlock(ip); + acquire(&cons.lock); + for(i = 0; i < n; i++) + consputc(buf[i] & 0xff); + release(&cons.lock); + ilock(ip); + + return n; +} + void consoleinit(void) { @@ -269,22 +285,3 @@ consoleinit(void) ioapicenable(IRQ_KBD, 0); } -void -panic(char *s) -{ - int i; - uint pcs[10]; - - cli(); - cons.locking = 0; - cprintf("cpu%d: panic: ", cpu()); - cprintf(s); - cprintf("\n"); - getcallerpcs(&s, pcs); - for(i=0; i<10; i++) - cprintf(" %p", pcs[i]); - panicked = 1; // freeze other CPU - for(;;) - ; -} - diff --git a/defs.h b/defs.h index 09fa467564..12d04aae53 100644 --- a/defs.h +++ b/defs.h @@ -91,6 +91,7 @@ void pipeclose(struct pipe*, int); int piperead(struct pipe*, char*, int); int pipewrite(struct pipe*, char*, int); +//PAGEBREAK: 16 // proc.c struct proc* copyproc(struct proc*); void exit(void); diff --git a/dev.h b/dev.h deleted file mode 100644 index 48d31d35ce..0000000000 --- a/dev.h +++ /dev/null @@ -1,8 +0,0 @@ -struct devsw { - int (*read)(struct inode*, char*, int); - int (*write)(struct inode*, char*, int); -}; - -extern struct devsw devsw[]; - -#define CONSOLE 1 diff --git a/elf.h b/elf.h index 28bbd23d93..17f83219dc 100644 --- a/elf.h +++ b/elf.h @@ -40,21 +40,3 @@ struct proghdr { #define ELF_PROG_FLAG_EXEC 1 #define ELF_PROG_FLAG_WRITE 2 #define ELF_PROG_FLAG_READ 4 - - - - - - - - - - - - - - - - - -// Blank page. diff --git a/exec.c b/exec.c index 3be3eeda7d..bee960e90c 100644 --- a/exec.c +++ b/exec.c @@ -11,7 +11,7 @@ exec(char *path, char **argv) { char *mem, *s, *last; int i, argc, arglen, len, off; - uint sz, sp, argp; + uint sz, sp, argp, x; struct elfhdr elf; struct inode *ip; struct proghdr ph; @@ -67,7 +67,9 @@ exec(char *path, char **argv) goto bad; if(ph.type != ELF_PROG_LOAD) continue; - if(ph.va + ph.memsz < ph.va || ph.va + ph.memsz > sz || ph.memsz < ph.filesz) + if(ph.va + ph.memsz < ph.va || ph.va + ph.memsz > sz) + goto bad; + if(ph.memsz < ph.filesz) goto bad; if(readi(ip, mem + ph.va, ph.offset, ph.filesz) != ph.filesz) goto bad; diff --git a/file.c b/file.c index 12b1561ab6..e10b824921 100644 --- a/file.c +++ b/file.c @@ -1,9 +1,9 @@ #include "types.h" #include "defs.h" #include "param.h" +#include "fs.h" #include "file.h" #include "spinlock.h" -#include "dev.h" struct devsw devsw[NDEV]; struct { diff --git a/file.h b/file.h index 1d56145674..55918cc178 100644 --- a/file.h +++ b/file.h @@ -7,3 +7,35 @@ struct file { struct inode *ip; uint off; }; + + +// in-core file system types + +struct inode { + uint dev; // Device number + uint inum; // Inode number + int ref; // Reference count + int flags; // I_BUSY, I_VALID + + short type; // copy of disk inode + short major; + short minor; + short nlink; + uint size; + uint addrs[NDIRECT+1]; +}; + +#define I_BUSY 0x1 +#define I_VALID 0x2 + + +// device implementations + +struct devsw { + int (*read)(struct inode*, char*, int); + int (*write)(struct inode*, char*, int); +}; + +extern struct devsw devsw[]; + +#define CONSOLE 1 diff --git a/fs.c b/fs.c index fe65338be8..15b0bfee59 100644 --- a/fs.c +++ b/fs.c @@ -19,8 +19,7 @@ #include "spinlock.h" #include "buf.h" #include "fs.h" -#include "fsvar.h" -#include "dev.h" +#include "file.h" #define min(a, b) ((a) < (b) ? (a) : (b)) static void itrunc(struct inode*); diff --git a/fsvar.h b/fsvar.h deleted file mode 100644 index 7f135a9c62..0000000000 --- a/fsvar.h +++ /dev/null @@ -1,18 +0,0 @@ -// in-core file system types - -struct inode { - uint dev; // Device number - uint inum; // Inode number - int ref; // Reference count - int flags; // I_BUSY, I_VALID - - short type; // copy of disk inode - short major; - short minor; - short nlink; - uint size; - uint addrs[NDIRECT+1]; -}; - -#define I_BUSY 0x1 -#define I_VALID 0x2 diff --git a/picirq.c b/picirq.c index ff86831311..1230c13187 100644 --- a/picirq.c +++ b/picirq.c @@ -82,3 +82,32 @@ picinit(void) if(irqmask != 0xFFFF) picsetmask(irqmask); } + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Blank page. diff --git a/pipe.c b/pipe.c index 3032775f41..29c01b2b0e 100644 --- a/pipe.c +++ b/pipe.c @@ -3,6 +3,7 @@ #include "param.h" #include "mmu.h" #include "proc.h" +#include "fs.h" #include "file.h" #include "spinlock.h" @@ -72,7 +73,7 @@ pipeclose(struct pipe *p, int writable) release(&p->lock); } -//PAGEBREAK: 30 +//PAGEBREAK: 40 int pipewrite(struct pipe *p, char *addr, int n) { diff --git a/proc.c b/proc.c index 43335122c2..d111008354 100644 --- a/proc.c +++ b/proc.c @@ -23,6 +23,79 @@ pinit(void) initlock(&ptable.lock, "ptable"); } +//PAGEBREAK: 36 +// Print a process listing to console. For debugging. +// Runs when user types ^P on console. +// No lock to avoid wedging a stuck machine further. +void +procdump(void) +{ + static char *states[] = { + [UNUSED] "unused", + [EMBRYO] "embryo", + [SLEEPING] "sleep ", + [RUNNABLE] "runble", + [RUNNING] "run ", + [ZOMBIE] "zombie" + }; + int i; + struct proc *p; + char *state; + uint pc[10]; + + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ + if(p->state == UNUSED) + continue; + if(p->state >= 0 && p->state < NELEM(states) && states[p->state]) + state = states[p->state]; + else + state = "???"; + cprintf("%d %s %s", p->pid, state, p->name); + if(p->state == SLEEPING){ + getcallerpcs((uint*)p->context->ebp+2, pc); + for(i=0; i<10 && pc[i] != 0; i++) + cprintf(" %p", pc[i]); + } + cprintf("\n"); + } +} + +// Set up CPU's kernel segment descriptors. +// Run once at boot time on each CPU. +void +ksegment(void) +{ + struct cpu *c1; + + c1 = &cpus[cpu()]; + c1->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0); + c1->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); + c1->gdt[SEG_KCPU] = SEG(STA_W, (uint)(&c1->tls+1), 0xffffffff, 0); + lgdt(c1->gdt, sizeof(c1->gdt)); + loadfsgs(SEG_KCPU << 3); + + // Initialize cpu-local variables. + c = c1; + cp = 0; +} + +// Set up CPU's segment descriptors and current process task state. +// If cp==0, set up for "idle" state for when scheduler() is running. +void +usegment(void) +{ + pushcli(); + c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)cp->mem, cp->sz-1, DPL_USER); + c->gdt[SEG_UDATA] = SEG(STA_W, (uint)cp->mem, cp->sz-1, DPL_USER); + c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0); + c->gdt[SEG_TSS].s = 0; + c->ts.ss0 = SEG_KDATA << 3; + c->ts.esp0 = (uint)cp->kstack + KSTACKSIZE; + ltr(SEG_TSS << 3); + popcli(); +} + +//PAGEBREAK: 15 // Look in the process table for an UNUSED proc. // If found, change state to EMBRYO and return it. // Otherwise return 0. @@ -67,6 +140,37 @@ allocproc(void) return p; } +// Set up first user process. +void +userinit(void) +{ + struct proc *p; + extern char _binary_initcode_start[], _binary_initcode_size[]; + + p = allocproc(); + initproc = p; + + // Initialize memory from initcode.S + p->sz = PAGE; + p->mem = kalloc(p->sz); + memset(p->mem, 0, p->sz); + memmove(p->mem, _binary_initcode_start, (int)_binary_initcode_size); + + memset(p->tf, 0, sizeof(*p->tf)); + p->tf->cs = (SEG_UCODE << 3) | DPL_USER; + p->tf->ds = (SEG_UDATA << 3) | DPL_USER; + p->tf->es = p->tf->ds; + p->tf->ss = p->tf->ds; + p->tf->eflags = FL_IF; + p->tf->esp = p->sz; + p->tf->eip = 0; // beginning of initcode.S + + safestrcpy(p->name, "initcode", sizeof(p->name)); + p->cwd = namei("/"); + + p->state = RUNNABLE; +} + // Grow current process's memory by n bytes. // Return 0 on success, -1 on failure. int @@ -86,41 +190,6 @@ growproc(int n) return 0; } -// Set up CPU's kernel segment descriptors. -// Run once at boot time on each CPU. -void -ksegment(void) -{ - struct cpu *c1; - - c1 = &cpus[cpu()]; - c1->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0); - c1->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); - c1->gdt[SEG_KCPU] = SEG(STA_W, (uint)(&c1->tls+1), 0xffffffff, 0); - lgdt(c1->gdt, sizeof(c1->gdt)); - loadfsgs(SEG_KCPU << 3); - - // Initialize cpu-local variables. - c = c1; - cp = 0; -} - -// Set up CPU's segment descriptors and task state for the current process. -// If cp==0, set up for "idle" state for when scheduler() is running. -void -usegment(void) -{ - pushcli(); - c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)cp->mem, cp->sz-1, DPL_USER); - c->gdt[SEG_UDATA] = SEG(STA_W, (uint)cp->mem, cp->sz-1, DPL_USER); - c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0); - c->gdt[SEG_TSS].s = 0; - c->ts.ss0 = SEG_KDATA << 3; - c->ts.esp0 = (uint)cp->kstack + KSTACKSIZE; - ltr(SEG_TSS << 3); - popcli(); -} - // Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. @@ -160,37 +229,6 @@ fork(void) return pid; } -// Set up first user process. -void -userinit(void) -{ - struct proc *p; - extern char _binary_initcode_start[], _binary_initcode_size[]; - - p = allocproc(); - initproc = p; - - // Initialize memory from initcode.S - p->sz = PAGE; - p->mem = kalloc(p->sz); - memset(p->mem, 0, p->sz); - memmove(p->mem, _binary_initcode_start, (int)_binary_initcode_size); - - memset(p->tf, 0, sizeof(*p->tf)); - p->tf->cs = (SEG_UCODE << 3) | DPL_USER; - p->tf->ds = (SEG_UDATA << 3) | DPL_USER; - p->tf->es = p->tf->ds; - p->tf->ss = p->tf->ds; - p->tf->eflags = FL_IF; - p->tf->esp = p->sz; - p->tf->eip = 0; // beginning of initcode.S - - safestrcpy(p->name, "initcode", sizeof(p->name)); - p->cwd = namei("/"); - - p->state = RUNNABLE; -} - //PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. @@ -440,39 +478,3 @@ wait(void) } } -// Print a process listing to console. For debugging. -// Runs when user types ^P on console. -// No lock to avoid wedging a stuck machine further. -void -procdump(void) -{ - static char *states[] = { - [UNUSED] "unused", - [EMBRYO] "embryo", - [SLEEPING] "sleep ", - [RUNNABLE] "runble", - [RUNNING] "run ", - [ZOMBIE] "zombie" - }; - int i; - struct proc *p; - char *state; - uint pc[10]; - - for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ - if(p->state == UNUSED) - continue; - if(p->state >= 0 && p->state < NELEM(states) && states[p->state]) - state = states[p->state]; - else - state = "???"; - cprintf("%d %s %s", p->pid, state, p->name); - if(p->state == SLEEPING){ - getcallerpcs((uint*)p->context->ebp+2, pc); - for(i=0; i<10 && pc[i] != 0; i++) - cprintf(" %p", pc[i]); - } - cprintf("\n"); - } -} - diff --git a/runoff b/runoff index 3da62b4c56..21ee8ed5eb 100755 --- a/runoff +++ b/runoff @@ -45,6 +45,7 @@ cat toc.ftr >>fmt/toc # check for bad alignments perl -e ' + $leftwarn = 0; while(<>){ chomp; s!#.*!!; @@ -75,12 +76,35 @@ perl -e ' print STDERR "Have no toc for $file\n"; next; } - if($toc{$file} =~ /^\d\d[^5]/){ + if($toc{$file} !~ /^\d\d5/){ print STDERR "$file does not start on a second half page.\n"; } next; } + if(/(left|right): (.*)/){ + $what = $1; + $file = $2; + if(!defined($toc{$file})){ + print STDERR "Have no toc for $file\n"; + next; + } + # this assumes that sheet 1 of code is a left page + # double-check the PDF + if(!$leftwarn++) { + print STDERR "assuming that sheet 1 is a left page. double-check!\n"; + } + if($what eq "left" && !($toc{$file} =~ /^\d[13579]0/)){ + print STDERR "$file does not start on a fresh left page [$toc{$file}]\n"; + } + # why does this not work if I inline $x in the if? + $x = ($toc{$file} =~ /^\d[02468]0/); + if($what eq "right" && !$x){ + print STDERR "$file does not start on a fresh right page [$toc{$file}] [$x]\n"; + } + next; + } + print STDERR "Unknown spec: $_\n"; } ' fmt/tocdata runoff.spec diff --git a/runoff.list b/runoff.list index 5a8a2f92f4..3bf6c874b1 100644 --- a/runoff.list +++ b/runoff.list @@ -34,12 +34,10 @@ sysproc.c # file system buf.h -dev.h fcntl.h stat.h -file.h fs.h -fsvar.h +file.h ide.c bio.c fs.c diff --git a/runoff.spec b/runoff.spec index 76ecb73bf1..dbd6d5c421 100644 --- a/runoff.spec +++ b/runoff.spec @@ -12,20 +12,27 @@ even: bootother.S # mild preference # bootmain.c either even: main.c # mp.c don't care at all -even: initcode.S -odd: init.c +# even: initcode.S +# odd: init.c # spinlock.h either # spinlock.c either even: proc.h # mild preference -even: proc.c # VERY important + +# goal is to have two action-packed 2-page spreads, +# one with +# ksegment usegment allocproc userinit growproc fork +# and another with +# scheduler sched yield forkret sleep wakeup1 wakeup +right: proc.c # VERY important + # setjmp.S either # kalloc.c either # syscall.h either # trapasm.S either # traps.h either -even: trap.c # important +# even: trap.c # vectors.pl either # syscall.c either # sysproc.c either @@ -37,7 +44,7 @@ even: trap.c # important # file.h either # fs.h either # fsvar.h either -# even: ide.c +left: ide.c # odd: bio.c odd: fs.c # VERY important # file.c either @@ -46,5 +53,6 @@ odd: fs.c # VERY important # even: pipe.c # mild preference # string.c either +left: kbd.h even: console.c odd: sh.c diff --git a/sysfile.c b/sysfile.c index 4d891c19a7..ae7d07cc3a 100644 --- a/sysfile.c +++ b/sysfile.c @@ -5,7 +5,6 @@ #include "mmu.h" #include "proc.h" #include "fs.h" -#include "fsvar.h" #include "file.h" #include "fcntl.h" diff --git a/timer.c b/timer.c index 8fdecee0cd..8df75a98df 100644 --- a/timer.c +++ b/timer.c @@ -30,36 +30,3 @@ timerinit(void) outb(IO_TIMER1, TIMER_DIV(100) / 256); picenable(IRQ_TIMER); } - - - - - - - - - - - - - - - - - - -// Blank page - - - - - - - - - - - - - - diff --git a/trap.c b/trap.c index 5f1cafb1ee..651a9d622d 100644 --- a/trap.c +++ b/trap.c @@ -31,6 +31,7 @@ idtinit(void) lidt(idt, sizeof(idt)); } +//PAGEBREAK: 41 void trap(struct trapframe *tf) { diff --git a/uart.c b/uart.c index 4cd1e0f41a..576e254db9 100644 --- a/uart.c +++ b/uart.c @@ -5,7 +5,8 @@ #include "param.h" #include "traps.h" #include "spinlock.h" -#include "dev.h" +#include "fs.h" +#include "file.h" #include "mmu.h" #include "proc.h" #include "x86.h" diff --git a/x86.h b/x86.h index 934b9eced0..e754b28ed4 100644 --- a/x86.h +++ b/x86.h @@ -122,6 +122,7 @@ sti(void) asm volatile("sti"); } +//PAGEBREAK: 36 // Layout of the trap frame built on the stack by the // hardware and by trapasm.S, and passed to trap(). struct trapframe { diff --git a/xv6.pdf b/xv6.pdf index 16f6d54c26..fd4efdecc4 100644 Binary files a/xv6.pdf and b/xv6.pdf differ diff --git a/xv6.ps b/xv6.ps index 4a90f7badc..8a4868ea11 100644 Binary files a/xv6.ps and b/xv6.ps differ