prune unneeded panics and debug output
This commit is contained in:
		
							parent
							
								
									d7ce6545e7
								
							
						
					
					
						commit
						dfcc5b997c
					
				
					 15 changed files with 85 additions and 173 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -70,7 +70,7 @@ PRINT =	\
 | 
				
			||||||
	string.c\
 | 
						string.c\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print: $(PRINT)
 | 
					print: $(PRINT)
 | 
				
			||||||
//	~/src/lgrind/source/lgrind -d ~/src/lgrind/lgrindef $(PRINT) > xv6.tex
 | 
						//~/src/lgrind/source/lgrind -d ~/src/lgrind/lgrindef $(PRINT) > xv6.tex
 | 
				
			||||||
	lgrind $(PRINT) > xv6.tex
 | 
						lgrind $(PRINT) > xv6.tex
 | 
				
			||||||
	latex xv6.tex
 | 
						latex xv6.tex
 | 
				
			||||||
	dvips -o xv61.ps xv6.dvi
 | 
						dvips -o xv61.ps xv6.dvi
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								asm.h
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								asm.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,3 +1,8 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// macros to create x86 segments from assembler
 | 
				
			||||||
 | 
					// from JOS
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SEG_NULL						\
 | 
					#define SEG_NULL						\
 | 
				
			||||||
	.word 0, 0;						\
 | 
						.word 0, 0;						\
 | 
				
			||||||
	.byte 0, 0, 0, 0
 | 
						.byte 0, 0, 0, 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,7 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# from JOS
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
#include "asm.h"
 | 
					#include "asm.h"
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
.set PROT_MODE_CSEG,0x8		# code segment selector
 | 
					.set PROT_MODE_CSEG,0x8		# code segment selector
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								elf.h
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								elf.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,3 +1,8 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// format of an ELF executable file
 | 
				
			||||||
 | 
					// from JOS
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ELF_MAGIC 0x464C457FU	/* "\x7FELF" in little endian */
 | 
					#define ELF_MAGIC 0x464C457FU	/* "\x7FELF" in little endian */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct elfhdr {
 | 
					struct elfhdr {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								init.c
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								init.c
									
										
									
									
									
								
							| 
						 | 
					@ -13,20 +13,25 @@ main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int pid;
 | 
					  int pid;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if(open("console", 0) < 0){
 | 
					  if(open("console", O_RDWR) < 0){
 | 
				
			||||||
    mknod("console", T_DEV, 1, 1);
 | 
					    mknod("console", T_DEV, 1, 1);
 | 
				
			||||||
    open("console", 0);
 | 
					    open("console", O_RDWR);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  open("console", 1);
 | 
					  dup(0);
 | 
				
			||||||
  open("console", 1);
 | 
					  dup(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while(1){
 | 
					  while(1){
 | 
				
			||||||
    pid = fork();
 | 
					    pid = fork();
 | 
				
			||||||
    if(pid == 0){
 | 
					    if(pid < 0){
 | 
				
			||||||
      exec("sh", sh_args);
 | 
					      puts("init: fork failed\n");
 | 
				
			||||||
      exit();
 | 
					      exit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(pid > 0)
 | 
					    if(pid == 0){
 | 
				
			||||||
 | 
					      exec("sh", sh_args);
 | 
				
			||||||
 | 
					      puts("init: exec sh failed\n");
 | 
				
			||||||
 | 
					      exit();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
      wait();
 | 
					      wait();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								lapic.c
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								lapic.c
									
										
									
									
									
								
							| 
						 | 
					@ -110,7 +110,6 @@ lapic_write(int r, int data)
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
lapic_timerinit(void)
 | 
					lapic_timerinit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  cprintf("cpu%d: init timer\n", cpu());
 | 
					 | 
				
			||||||
  lapic_write(LAPIC_TDCR, LAPIC_X1);
 | 
					  lapic_write(LAPIC_TDCR, LAPIC_X1);
 | 
				
			||||||
  lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER));
 | 
					  lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER));
 | 
				
			||||||
  lapic_write(LAPIC_TCCR, 10000000);
 | 
					  lapic_write(LAPIC_TCCR, 10000000);
 | 
				
			||||||
| 
						 | 
					@ -129,8 +128,6 @@ lapic_init(int c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint r, lvt;
 | 
					  uint r, lvt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cprintf("cpu%d: lapic_init %d\n", c);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register
 | 
					  lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register
 | 
				
			||||||
  r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID
 | 
					  r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID
 | 
				
			||||||
  lapic_write(LAPIC_LDR, (1<<r)<<24);  // set logical destination register to r
 | 
					  lapic_write(LAPIC_LDR, (1<<r)<<24);  // set logical destination register to r
 | 
				
			||||||
| 
						 | 
					@ -157,8 +154,6 @@ lapic_init(int c)
 | 
				
			||||||
  lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
 | 
					  lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
 | 
				
			||||||
  while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
 | 
					  while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  cprintf("cpu%d: apic init done\n", cpu());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -204,7 +199,7 @@ lapic_startap(uchar apicid, int v)
 | 
				
			||||||
  // in p9 code, this was i < 2, which is what the spec says on page B-3
 | 
					  // in p9 code, this was i < 2, which is what the spec says on page B-3
 | 
				
			||||||
  for(i = 0; i < 1; i++){
 | 
					  for(i = 0; i < 1; i++){
 | 
				
			||||||
    lapic_write(LAPIC_ICRHI, crhi);
 | 
					    lapic_write(LAPIC_ICRHI, crhi);
 | 
				
			||||||
    lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/PGSIZE));
 | 
					    lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/4096));
 | 
				
			||||||
    while (j++ < 100000) {;}
 | 
					    while (j++ < 100000) {;}
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										45
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								main.c
									
										
									
									
									
								
							| 
						 | 
					@ -13,7 +13,7 @@
 | 
				
			||||||
extern char edata[], end[];
 | 
					extern char edata[], end[];
 | 
				
			||||||
extern uchar _binary_init_start[], _binary_init_size[];
 | 
					extern uchar _binary_init_start[], _binary_init_size[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main00();
 | 
					void process0();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CPU 0 starts running C code here.
 | 
					// CPU 0 starts running C code here.
 | 
				
			||||||
// This is called main0 not main so that it can have
 | 
					// This is called main0 not main so that it can have
 | 
				
			||||||
| 
						 | 
					@ -32,43 +32,33 @@ main0(void)
 | 
				
			||||||
  asm volatile("movl %0, %%esp" : : "r" (cpus[0].mpstack + MPSTACK - 32));
 | 
					  asm volatile("movl %0, %%esp" : : "r" (cpus[0].mpstack + MPSTACK - 32));
 | 
				
			||||||
  asm volatile("movl %0, %%ebp" : : "r" (cpus[0].mpstack + MPSTACK));
 | 
					  asm volatile("movl %0, %%ebp" : : "r" (cpus[0].mpstack + MPSTACK));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Make sure interrupts stay disabled on all processors
 | 
					  // Prevent release() from enabling interrupts.
 | 
				
			||||||
  // until each signals it is ready, by pretending to hold
 | 
					  for(i=0; i<NCPU; i++)
 | 
				
			||||||
  // an extra lock.
 | 
					    cpus[i].nlock = 1;
 | 
				
			||||||
  // xxx maybe replace w/ acquire remembering if FL_IF was already clear
 | 
					 | 
				
			||||||
  for(i=0; i<NCPU; i++){
 | 
					 | 
				
			||||||
    cpus[i].nlock++;
 | 
					 | 
				
			||||||
    cpus[i].guard1 = 0xdeadbeef;
 | 
					 | 
				
			||||||
    cpus[i].guard2 = 0xdeadbeef;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mp_init(); // collect info about this machine
 | 
					  mp_init(); // collect info about this machine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lapic_init(mp_bcpu());
 | 
					  lapic_init(mp_bcpu());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cprintf("\n\ncpu%d: booting xv6\n\n", cpu());
 | 
					  cprintf("\ncpu%d: starting xv6\n\n", cpu());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinit();
 | 
					  pinit(); // process table
 | 
				
			||||||
  binit();
 | 
					  binit(); // buffer cache
 | 
				
			||||||
  pic_init(); // initialize PIC
 | 
					  pic_init();
 | 
				
			||||||
  ioapic_init();
 | 
					  ioapic_init();
 | 
				
			||||||
  kinit(); // physical memory allocator
 | 
					  kinit(); // physical memory allocator
 | 
				
			||||||
  tvinit(); // trap vectors
 | 
					  tvinit(); // trap vectors
 | 
				
			||||||
  idtinit(); // this CPU's idt register
 | 
					  idtinit(); // this CPU's interrupt descriptor table
 | 
				
			||||||
  fd_init();
 | 
					  fd_init();
 | 
				
			||||||
  iinit();
 | 
					  iinit(); // i-node table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // initialize process 0
 | 
					  // initialize process 0
 | 
				
			||||||
  p = &proc[0];
 | 
					  p = &proc[0];
 | 
				
			||||||
  p->state = RUNNABLE;
 | 
					  p->state = RUNNABLE;
 | 
				
			||||||
  p->sz = 4 * PAGE;
 | 
					 | 
				
			||||||
  p->mem = kalloc(p->sz);
 | 
					 | 
				
			||||||
  memset(p->mem, 0, p->sz);
 | 
					 | 
				
			||||||
  p->kstack = kalloc(KSTACKSIZE);
 | 
					  p->kstack = kalloc(KSTACKSIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // cause proc[0] to start in kernel at main00
 | 
					  // cause proc[0] to start in kernel at process0
 | 
				
			||||||
  memset(&p->jmpbuf, 0, sizeof p->jmpbuf);
 | 
					  p->jmpbuf.eip = (uint) process0;
 | 
				
			||||||
  p->jmpbuf.eip = (uint)main00;
 | 
					 | 
				
			||||||
  p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4);
 | 
					  p->jmpbuf.esp = (uint) (p->kstack + KSTACKSIZE - 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // make sure there's a TSS
 | 
					  // make sure there's a TSS
 | 
				
			||||||
| 
						 | 
					@ -78,6 +68,7 @@ main0(void)
 | 
				
			||||||
  console_init();
 | 
					  console_init();
 | 
				
			||||||
  ide_init(); 
 | 
					  ide_init(); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // start other CPUs
 | 
				
			||||||
  mp_startthem();
 | 
					  mp_startthem();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // turn on timer and enable interrupts on the local APIC
 | 
					  // turn on timer and enable interrupts on the local APIC
 | 
				
			||||||
| 
						 | 
					@ -118,7 +109,7 @@ mpmain(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// proc[0] starts here, called by scheduler() in the ordinary way.
 | 
					// proc[0] starts here, called by scheduler() in the ordinary way.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
main00()
 | 
					process0()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  struct proc *p0 = &proc[0];
 | 
					  struct proc *p0 = &proc[0];
 | 
				
			||||||
  struct proc *p1;
 | 
					  struct proc *p1;
 | 
				
			||||||
| 
						 | 
					@ -130,10 +121,13 @@ main00()
 | 
				
			||||||
  p0->cwd = iget(rootdev, 1);
 | 
					  p0->cwd = iget(rootdev, 1);
 | 
				
			||||||
  iunlock(p0->cwd);
 | 
					  iunlock(p0->cwd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // dummy user memory to make copyproc() happy
 | 
				
			||||||
 | 
					  p0->sz = 4 * PAGE;
 | 
				
			||||||
 | 
					  p0->mem = kalloc(p0->sz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // fake a trap frame as if a user process had made a system
 | 
					  // fake a trap frame as if a user process had made a system
 | 
				
			||||||
  // call, so that copyproc will have a place for the new
 | 
					  // call, so that copyproc will have a place for the new
 | 
				
			||||||
  // process to return to.
 | 
					  // process to return to.
 | 
				
			||||||
  p0 = &proc[0];
 | 
					 | 
				
			||||||
  p0->tf = &tf;
 | 
					  p0->tf = &tf;
 | 
				
			||||||
  memset(p0->tf, 0, sizeof(struct trapframe));
 | 
					  memset(p0->tf, 0, sizeof(struct trapframe));
 | 
				
			||||||
  p0->tf->es = p0->tf->ds = p0->tf->ss = (SEG_UDATA << 3) | 3;
 | 
					  p0->tf->es = p0->tf->ds = p0->tf->ss = (SEG_UDATA << 3) | 3;
 | 
				
			||||||
| 
						 | 
					@ -141,7 +135,7 @@ main00()
 | 
				
			||||||
  p0->tf->eflags = FL_IF;
 | 
					  p0->tf->eflags = FL_IF;
 | 
				
			||||||
  p0->tf->esp = p0->sz;
 | 
					  p0->tf->esp = p0->sz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  p1 = copyproc(&proc[0]);
 | 
					  p1 = copyproc(p0);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  load_icode(p1, _binary_init_start, (uint) _binary_init_size);
 | 
					  load_icode(p1, _binary_init_start, (uint) _binary_init_size);
 | 
				
			||||||
  p1->state = RUNNABLE;
 | 
					  p1->state = RUNNABLE;
 | 
				
			||||||
| 
						 | 
					@ -157,7 +151,6 @@ load_icode(struct proc *p, uchar *binary, uint size)
 | 
				
			||||||
  struct elfhdr *elf;
 | 
					  struct elfhdr *elf;
 | 
				
			||||||
  struct proghdr *ph;
 | 
					  struct proghdr *ph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Check magic number on binary
 | 
					 | 
				
			||||||
  elf = (struct elfhdr*) binary;
 | 
					  elf = (struct elfhdr*) binary;
 | 
				
			||||||
  if (elf->magic != ELF_MAGIC)
 | 
					  if (elf->magic != ELF_MAGIC)
 | 
				
			||||||
    panic("load_icode: not an ELF binary");
 | 
					    panic("load_icode: not an ELF binary");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										73
									
								
								mmu.h
									
										
									
									
									
								
							
							
						
						
									
										73
									
								
								mmu.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,15 +1,8 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This file contains definitions for the x86 memory management unit (MMU),
 | 
					 * This file contains definitions for the x86 memory management unit (MMU).
 | 
				
			||||||
 * including paging- and segmentation-related data structures and constants,
 | 
					 * from JOS.
 | 
				
			||||||
 * the %cr0, %cr4, and %eflags registers, and traps.
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *	Register flags and fundamental constants.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PGSIZE		4096		// bytes mapped by a page
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Eflags register
 | 
					// Eflags register
 | 
				
			||||||
#define FL_CF		0x00000001	// Carry Flag
 | 
					#define FL_CF		0x00000001	// Carry Flag
 | 
				
			||||||
#define FL_PF		0x00000004	// Parity Flag
 | 
					#define FL_PF		0x00000004	// Parity Flag
 | 
				
			||||||
| 
						 | 
					@ -33,33 +26,7 @@
 | 
				
			||||||
#define FL_VIP		0x00100000	// Virtual Interrupt Pending
 | 
					#define FL_VIP		0x00100000	// Virtual Interrupt Pending
 | 
				
			||||||
#define FL_ID		0x00200000	// ID flag
 | 
					#define FL_ID		0x00200000	// ID flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Page fault error codes
 | 
					// Segment Descriptor
 | 
				
			||||||
#define FEC_PR		0x1	// Page fault caused by protection violation
 | 
					 | 
				
			||||||
#define FEC_WR		0x2	// Page fault caused by a write
 | 
					 | 
				
			||||||
#define FEC_U		0x4	// Page fault occured while in user mode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *	Segmentation data structures and constants.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __ASSEMBLER__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Macros to build GDT entries in assembly.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define SEG_NULL						\
 | 
					 | 
				
			||||||
	.word 0, 0;						\
 | 
					 | 
				
			||||||
	.byte 0, 0, 0, 0
 | 
					 | 
				
			||||||
#define SEG(type,base,lim)					\
 | 
					 | 
				
			||||||
	.word (((lim) >> 12) & 0xffff), ((base) & 0xffff);	\
 | 
					 | 
				
			||||||
	.byte (((base) >> 16) & 0xff), (0x90 | (type)),		\
 | 
					 | 
				
			||||||
		(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#else	// not __ASSEMBLER__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Segment Descriptors
 | 
					 | 
				
			||||||
struct segdesc {
 | 
					struct segdesc {
 | 
				
			||||||
	uint lim_15_0 : 16;  // Low bits of segment limit
 | 
						uint lim_15_0 : 16;  // Low bits of segment limit
 | 
				
			||||||
	uint base_15_0 : 16; // Low bits of segment base address
 | 
						uint base_15_0 : 16; // Low bits of segment base address
 | 
				
			||||||
| 
						 | 
					@ -75,22 +42,21 @@ struct segdesc {
 | 
				
			||||||
	uint g : 1;          // Granularity: limit scaled by 4K when set
 | 
						uint g : 1;          // Granularity: limit scaled by 4K when set
 | 
				
			||||||
	uint base_31_24 : 8; // High bits of segment base address
 | 
						uint base_31_24 : 8; // High bits of segment base address
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Null segment
 | 
					// Null segment
 | 
				
			||||||
#define SEG_NULL	(struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 | 
					#define SEG_NULL	(struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 | 
				
			||||||
// Segment that is loadable but faults when used
 | 
					
 | 
				
			||||||
#define SEG_FAULT	(struct segdesc){ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }
 | 
					 | 
				
			||||||
// Normal segment
 | 
					// Normal segment
 | 
				
			||||||
#define SEG(type, base, lim, dpl) (struct segdesc)			\
 | 
					#define SEG(type, base, lim, dpl) (struct segdesc)			\
 | 
				
			||||||
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,	\
 | 
					{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,	\
 | 
				
			||||||
    type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1,		\
 | 
					    type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1,		\
 | 
				
			||||||
    (uint) (base) >> 24 }
 | 
					    (uint) (base) >> 24 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SEG16(type, base, lim, dpl) (struct segdesc)			\
 | 
					#define SEG16(type, base, lim, dpl) (struct segdesc)			\
 | 
				
			||||||
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,		\
 | 
					{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,		\
 | 
				
			||||||
    type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0,		\
 | 
					    type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0,		\
 | 
				
			||||||
    (uint) (base) >> 24 }
 | 
					    (uint) (base) >> 24 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !__ASSEMBLER__ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Application segment type bits
 | 
					// Application segment type bits
 | 
				
			||||||
#define STA_X		0x8	    // Executable segment
 | 
					#define STA_X		0x8	    // Executable segment
 | 
				
			||||||
#define STA_E		0x4	    // Expand down (non-executable segments)
 | 
					#define STA_E		0x4	    // Expand down (non-executable segments)
 | 
				
			||||||
| 
						 | 
					@ -113,16 +79,7 @@ struct segdesc {
 | 
				
			||||||
#define STS_IG32	0xE	    // 32-bit Interrupt Gate
 | 
					#define STS_IG32	0xE	    // 32-bit Interrupt Gate
 | 
				
			||||||
#define STS_TG32	0xF	    // 32-bit Trap Gate
 | 
					#define STS_TG32	0xF	    // 32-bit Trap Gate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Task state segment format
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *	Traps.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __ASSEMBLER__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Task state segment format (as described by the Pentium architecture book)
 | 
					 | 
				
			||||||
struct taskstate {
 | 
					struct taskstate {
 | 
				
			||||||
	uint link;	// Old ts selector
 | 
						uint link;	// Old ts selector
 | 
				
			||||||
	uint esp0;	// Stack pointers and segment selectors
 | 
						uint esp0;	// Stack pointers and segment selectors
 | 
				
			||||||
| 
						 | 
					@ -197,19 +154,3 @@ struct gatedesc {
 | 
				
			||||||
	(gate).off_31_16 = (uint) (off) >> 16;		\
 | 
						(gate).off_31_16 = (uint) (off) >> 16;		\
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set up a call gate descriptor.
 | 
					 | 
				
			||||||
#define SETCALLGATE(gate, ss, off, d)           	        \
 | 
					 | 
				
			||||||
{								\
 | 
					 | 
				
			||||||
	(gate).off_15_0 = (uint) (off) & 0xffff;		\
 | 
					 | 
				
			||||||
	(gate).ss = (ss);					\
 | 
					 | 
				
			||||||
	(gate).args = 0;					\
 | 
					 | 
				
			||||||
	(gate).rsv1 = 0;					\
 | 
					 | 
				
			||||||
	(gate).type = STS_CG32;				\
 | 
					 | 
				
			||||||
	(gate).s = 0;					\
 | 
					 | 
				
			||||||
	(gate).dpl = (d);					\
 | 
					 | 
				
			||||||
	(gate).p = 1;					\
 | 
					 | 
				
			||||||
	(gate).off_31_16 = (uint) (off) >> 16;		\
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* !__ASSEMBLER__ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								mp.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								mp.c
									
										
									
									
									
								
							| 
						 | 
					@ -42,7 +42,6 @@ mp_scan(uchar *addr, int len)
 | 
				
			||||||
  uchar *e, *p, sum;
 | 
					  uchar *e, *p, sum;
 | 
				
			||||||
  int i;
 | 
					  int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cprintf("scanning: 0x%x\n", (uint)addr);
 | 
					 | 
				
			||||||
  e = addr+len;
 | 
					  e = addr+len;
 | 
				
			||||||
  for(p = addr; p < e; p += sizeof(struct mp)){
 | 
					  for(p = addr; p < e; p += sizeof(struct mp)){
 | 
				
			||||||
    if(memcmp(p, "_MP_", 4))
 | 
					    if(memcmp(p, "_MP_", 4))
 | 
				
			||||||
| 
						 | 
					@ -131,8 +130,6 @@ mp_init(void)
 | 
				
			||||||
  ncpu = 0;
 | 
					  ncpu = 0;
 | 
				
			||||||
  if ((r = mp_detect()) != 0) return;
 | 
					  if ((r = mp_detect()) != 0) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cprintf("Mp spec rev #: %x imcrp 0x%x\n", mp->specrev, mp->imcrp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Run through the table saving information needed for starting
 | 
					   * Run through the table saving information needed for starting
 | 
				
			||||||
   * application processors and initialising any I/O APICs. The table
 | 
					   * application processors and initialising any I/O APICs. The table
 | 
				
			||||||
| 
						 | 
					@ -140,7 +137,6 @@ mp_init(void)
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  mpctb = (struct mpctb *) mp->physaddr;
 | 
					  mpctb = (struct mpctb *) mp->physaddr;
 | 
				
			||||||
  lapicaddr = (uint *) mpctb->lapicaddr;
 | 
					  lapicaddr = (uint *) mpctb->lapicaddr;
 | 
				
			||||||
  cprintf("apicaddr: %x\n", lapicaddr);
 | 
					 | 
				
			||||||
  p = ((uchar*)mpctb)+sizeof(struct mpctb);
 | 
					  p = ((uchar*)mpctb)+sizeof(struct mpctb);
 | 
				
			||||||
  e = ((uchar*)mpctb)+mpctb->length;
 | 
					  e = ((uchar*)mpctb)+mpctb->length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,7 +145,6 @@ mp_init(void)
 | 
				
			||||||
    case MPPROCESSOR:
 | 
					    case MPPROCESSOR:
 | 
				
			||||||
      proc = (struct mppe *) p;
 | 
					      proc = (struct mppe *) p;
 | 
				
			||||||
      cpus[ncpu].apicid = proc->apicid;
 | 
					      cpus[ncpu].apicid = proc->apicid;
 | 
				
			||||||
      cprintf("a processor %x\n", cpus[ncpu].apicid);
 | 
					 | 
				
			||||||
      if (proc->flags & MPBP) {
 | 
					      if (proc->flags & MPBP) {
 | 
				
			||||||
	bcpu = &cpus[ncpu];
 | 
						bcpu = &cpus[ncpu];
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -162,18 +157,15 @@ mp_init(void)
 | 
				
			||||||
	if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
 | 
						if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
 | 
				
			||||||
	  break;
 | 
						  break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      cprintf("a bus %d\n", i);
 | 
					 | 
				
			||||||
      p += sizeof(struct mpbe);
 | 
					      p += sizeof(struct mpbe);
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    case MPIOAPIC:
 | 
					    case MPIOAPIC:
 | 
				
			||||||
      ioapic = (struct mpioapic *) p;
 | 
					      ioapic = (struct mpioapic *) p;
 | 
				
			||||||
      cprintf("an I/O APIC: id %d %x\n", ioapic->apicno, ioapic->flags);
 | 
					 | 
				
			||||||
      ioapic_id = ioapic->apicno;
 | 
					      ioapic_id = ioapic->apicno;
 | 
				
			||||||
      p += sizeof(struct mpioapic);
 | 
					      p += sizeof(struct mpioapic);
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    case MPIOINTR:
 | 
					    case MPIOINTR:
 | 
				
			||||||
      intr = (struct mpie *) p;
 | 
					      intr = (struct mpie *) p;
 | 
				
			||||||
      // cprintf("an I/O intr: type %d flags 0x%x bus %d souce bus irq %d dest ioapic id %d dest ioapic intin %d\n", intr->intr, intr->flags, intr->busno, intr->irq, intr->apicno, intr->intin);
 | 
					 | 
				
			||||||
      p += sizeof(struct mpie);
 | 
					      p += sizeof(struct mpie);
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
| 
						 | 
					@ -192,8 +184,6 @@ mp_init(void)
 | 
				
			||||||
    byte |= 0x01;	/* mask external INTR */
 | 
					    byte |= 0x01;	/* mask external INTR */
 | 
				
			||||||
    outb(0x23, byte);	/* disconnect 8259s/NMI */
 | 
					    outb(0x23, byte);	/* disconnect 8259s/NMI */
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -219,7 +209,6 @@ mp_startthem(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(c = 0; c < ncpu; c++){
 | 
					  for(c = 0; c < ncpu; c++){
 | 
				
			||||||
    if (c == cpu()) continue;
 | 
					    if (c == cpu()) continue;
 | 
				
			||||||
    cprintf ("cpu%d: starting processor %d\n", cpu(), c);
 | 
					 | 
				
			||||||
    *(uint *)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp
 | 
					    *(uint *)(APBOOTCODE-4) = (uint) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp
 | 
				
			||||||
    *(uint *)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to
 | 
					    *(uint *)(APBOOTCODE-8) = (uint)mpmain; // tell it where to jump to
 | 
				
			||||||
    lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
 | 
					    lapic_startap(cpus[c].apicid, (uint) APBOOTCODE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										29
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
					@ -169,18 +169,11 @@ scheduler(void)
 | 
				
			||||||
  struct proc *p;
 | 
					  struct proc *p;
 | 
				
			||||||
  int i;
 | 
					  int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(cpus[cpu()].nlock != 0){
 | 
					 | 
				
			||||||
    cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease   );
 | 
					 | 
				
			||||||
    panic("holding locks at first entry to scheduler");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for(;;){
 | 
					  for(;;){
 | 
				
			||||||
    // Loop over process table looking for process to run.
 | 
					    // Loop over process table looking for process to run.
 | 
				
			||||||
    acquire(&proc_table_lock);
 | 
					    acquire(&proc_table_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(i = 0; i < NPROC; i++){
 | 
					    for(i = 0; i < NPROC; i++){
 | 
				
			||||||
      if(cpus[cpu()].guard1 != 0xdeadbeef || 
 | 
					 | 
				
			||||||
         cpus[cpu()].guard2 != 0xdeadbeef)
 | 
					 | 
				
			||||||
        panic("cpu guard");
 | 
					 | 
				
			||||||
      p = &proc[i];
 | 
					      p = &proc[i];
 | 
				
			||||||
      if(p->state != RUNNABLE)
 | 
					      if(p->state != RUNNABLE)
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
| 
						 | 
					@ -198,31 +191,11 @@ scheduler(void)
 | 
				
			||||||
      // Process is done running for now. 
 | 
					      // Process is done running for now. 
 | 
				
			||||||
      // It should have changed its p->state before coming back.
 | 
					      // It should have changed its p->state before coming back.
 | 
				
			||||||
      curproc[cpu()] = 0;
 | 
					      curproc[cpu()] = 0;
 | 
				
			||||||
      if(p->state == RUNNING)
 | 
					 | 
				
			||||||
        panic("swtch to scheduler with state=RUNNING");
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      if(!holding(&proc_table_lock)){
 | 
					 | 
				
			||||||
        cprintf("back to scheduler without proc_table_lock (pid=%d state=%d)", p->pid, p->state);
 | 
					 | 
				
			||||||
        panic("scheduler lock");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if(cpus[cpu()].nlock != 1){
 | 
					 | 
				
			||||||
        cprintf("holding %d locks in scheduler (pid=%d state=%d)\n", cpus[cpu()].nlock, p->pid, p->state);
 | 
					 | 
				
			||||||
        panic("scheduler lock");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      setupsegs(0);
 | 
					      setupsegs(0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    release(&proc_table_lock);
 | 
					    release(&proc_table_lock);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(cpus[cpu()].nlock != 0)
 | 
					 | 
				
			||||||
      panic("holding locks in scheduler");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // With proc_table_lock released, there are no 
 | 
					 | 
				
			||||||
    // locks held on this cpu, so interrupts are enabled.
 | 
					 | 
				
			||||||
    // Hardware interrupts can happen here.
 | 
					 | 
				
			||||||
    // Also, releasing the lock here lets the other CPUs
 | 
					 | 
				
			||||||
    // look for runnable processes too.
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								proc.h
									
										
									
									
									
								
							| 
						 | 
					@ -66,13 +66,9 @@ struct cpu {
 | 
				
			||||||
  struct jmpbuf jmpbuf;
 | 
					  struct jmpbuf jmpbuf;
 | 
				
			||||||
  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];
 | 
				
			||||||
  int guard1;
 | 
					 | 
				
			||||||
  char mpstack[MPSTACK]; // per-cpu start-up stack
 | 
					  char mpstack[MPSTACK]; // per-cpu start-up stack
 | 
				
			||||||
  int guard2;
 | 
					 | 
				
			||||||
  volatile int booted;
 | 
					  volatile int booted;
 | 
				
			||||||
  int nlock; // # of locks currently held
 | 
					  int nlock; // # of locks currently held
 | 
				
			||||||
  struct spinlock *lastacquire; // xxx debug
 | 
					 | 
				
			||||||
  struct spinlock *lastrelease; // xxx debug
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct cpu cpus[NCPU];
 | 
					extern struct cpu cpus[NCPU];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,6 @@ acquire(struct spinlock * lock)
 | 
				
			||||||
  cpuid(0, 0, 0, 0, 0);	// memory barrier
 | 
					  cpuid(0, 0, 0, 0, 0);	// memory barrier
 | 
				
			||||||
  getcallerpcs(&lock, lock->pcs);
 | 
					  getcallerpcs(&lock, lock->pcs);
 | 
				
			||||||
  lock->cpu = cpu() + 10;
 | 
					  lock->cpu = cpu() + 10;
 | 
				
			||||||
  cpus[cpu()].lastacquire = lock;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -53,7 +52,6 @@ release(struct spinlock * lock)
 | 
				
			||||||
  if(!holding(lock))
 | 
					  if(!holding(lock))
 | 
				
			||||||
    panic("release");
 | 
					    panic("release");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cpus[cpu()].lastrelease = lock;
 | 
					 | 
				
			||||||
  lock->pcs[0] = 0;
 | 
					  lock->pcs[0] = 0;
 | 
				
			||||||
  lock->cpu = 0xffffffff;
 | 
					  lock->cpu = 0xffffffff;
 | 
				
			||||||
  cpuid(0, 0, 0, 0, 0);	// memory barrier
 | 
					  cpuid(0, 0, 0, 0, 0);	// memory barrier
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,7 +473,7 @@ sys_getpid(void)
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
sys_sbrk(void)
 | 
					sys_sbrk(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  unsigned addr;
 | 
					  uint addr;
 | 
				
			||||||
  int n;
 | 
					  int n;
 | 
				
			||||||
  struct proc *cp = curproc[cpu()];
 | 
					  struct proc *cp = curproc[cpu()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,3 @@
 | 
				
			||||||
#include "mmu.h"
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
	.text
 | 
						.text
 | 
				
			||||||
.globl trap
 | 
					.globl trap
 | 
				
			||||||
.globl trapret1
 | 
					.globl trapret1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										48
									
								
								usertests.c
									
										
									
									
									
								
							
							
						
						
									
										48
									
								
								usertests.c
									
										
									
									
									
								
							| 
						 | 
					@ -13,7 +13,10 @@ pipe1(void)
 | 
				
			||||||
  int fds[2], pid;
 | 
					  int fds[2], pid;
 | 
				
			||||||
  int seq = 0, i, n, cc, total;
 | 
					  int seq = 0, i, n, cc, total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipe(fds);
 | 
					  if(pipe(fds) != 0){
 | 
				
			||||||
 | 
					    puts("pipe() failed\n");
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  pid = fork();
 | 
					  pid = fork();
 | 
				
			||||||
  if(pid == 0){
 | 
					  if(pid == 0){
 | 
				
			||||||
    close(fds[0]);
 | 
					    close(fds[0]);
 | 
				
			||||||
| 
						 | 
					@ -26,7 +29,7 @@ pipe1(void)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    exit();
 | 
					    exit();
 | 
				
			||||||
  } else {
 | 
					  } else if(pid > 0){
 | 
				
			||||||
    close(fds[1]);
 | 
					    close(fds[1]);
 | 
				
			||||||
    total = 0;
 | 
					    total = 0;
 | 
				
			||||||
    cc = 1;
 | 
					    cc = 1;
 | 
				
			||||||
| 
						 | 
					@ -43,9 +46,12 @@ pipe1(void)
 | 
				
			||||||
        cc = sizeof(buf);
 | 
					        cc = sizeof(buf);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(total != 5 * 1033)
 | 
					    if(total != 5 * 1033)
 | 
				
			||||||
      printf(1, "pipe1 oops 3\n");
 | 
					      printf(1, "pipe1 oops 3 total %d\n", total);
 | 
				
			||||||
    close(fds[0]);
 | 
					    close(fds[0]);
 | 
				
			||||||
    wait();
 | 
					    wait();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    puts("fork() failed\n");
 | 
				
			||||||
 | 
					    exit();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  puts("pipe1 ok\n");
 | 
					  puts("pipe1 ok\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -121,26 +127,30 @@ void
 | 
				
			||||||
mem(void)
 | 
					mem(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  void *m1, *m2;
 | 
					  void *m1, *m2;
 | 
				
			||||||
 | 
					  int pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  m1 = 0;
 | 
					  if((pid = fork()) == 0){
 | 
				
			||||||
  while ((m2 = malloc(1024)) != 0) {
 | 
					    m1 = 0;
 | 
				
			||||||
    printf(1, "malloc %x\n", m2);
 | 
					    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);
 | 
				
			||||||
 | 
					      m1 = m2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m1 = malloc(1024*20);
 | 
				
			||||||
 | 
					    if (m1 == 0) {
 | 
				
			||||||
 | 
					      puts("couldn't allocate mem?!!\n");
 | 
				
			||||||
 | 
					      exit();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    free(m1);
 | 
					    free(m1);
 | 
				
			||||||
    m1 = m2;
 | 
					    printf(1, "mem ok\n");
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  m1 = malloc(1024*20);
 | 
					 | 
				
			||||||
  if (m1 == 0) {
 | 
					 | 
				
			||||||
    puts("couldn't allocate mem?!!\n");
 | 
					 | 
				
			||||||
    exit();
 | 
					    exit();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    wait();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  free(m1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  printf(1, "mem ok\n");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue