示例#1
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	//panic("fork not implemented");
	extern void _pgfault_upcall(void);
	set_pgfault_handler(pgfault);
	envid_t id = sys_exofork();
	int r;
	if (id < 0)
		panic("exofork: child");
	if (id == 0)
	{
		thisenv = envs + ENVX(sys_getenvid());
		return 0;
	}
//	cprintf("fork id: %x",id);
	if ((r=sys_page_alloc(id, (void*)(UXSTACKTOP-PGSIZE), PTE_U | PTE_W | PTE_P))<0)
		return r;
	int i;
	for (i=0;i<UTOP-PGSIZE;i+=PGSIZE)
		if ((vpd[PDX(i)] & PTE_P) && (vpt[PGNUM(i)] & PTE_P))
		{
//			cprintf("i:%x ",i);
			if ((r=duppage(id,PGNUM(i)))<0)
				return r;
		}
	if ((r=sys_env_set_pgfault_upcall(id,(void*)_pgfault_upcall))<0)
		return r;
	if ((r=sys_env_set_status(id, ENV_RUNNABLE))<0)
		return r;
	return id;
}
示例#2
0
文件: testsfork.c 项目: nollaG/jos
void
umain(int argc, char **argv)
{
  envid_t env;
	cprintf("Father:%04x", sys_getenvid());
  a=1;
  if ((env = sfork()) == 0) {
    while (1) {
      cprintf("child:a=%d\n",a);
      sys_yield();
    }
    exit();
  }
  sys_yield();
  sys_yield();
  sys_yield();
  sys_yield();
  sys_yield();
  sys_yield();
  cprintf("Father:a changed\n");
  a=2;
  sys_yield();
  sys_yield();
  sys_yield();
  sys_yield();
  sys_yield();
  sys_yield();
  cprintf("Killing the child\n");
  sys_env_destroy(env);
}
示例#3
0
void
umain(void)
{
	envid_t ns_envid = sys_getenvid();
	int i, r;

	binaryname = "testoutput";

	output_envid = fork();
	
	//cprintf("ns: %d, out:%d\n",ns_envid,output_envid);
	
	if (output_envid < 0)
		panic("error forking");
	else if (output_envid == 0) {
		output(ns_envid);
		return;
	}

	for (i = 0; i < TESTOUTPUT_COUNT; i++) {
		if ((r = sys_page_alloc(0, pkt, PTE_P|PTE_U|PTE_W)) < 0)
			panic("sys_page_alloc: %e", r);
		pkt->jp_len = snprintf(pkt->jp_data,
				       PGSIZE - sizeof(pkt->jp_len),
				       "Packet %02d", i);
		cprintf("Transmitting packet %d\n", i);
		ipc_send(output_envid, NSREQ_OUTPUT, pkt, PTE_P|PTE_W|PTE_U);
		sys_page_unmap(0, pkt);
	}

	// Spin for a while, just in case IPC's or packets need to be flushed
	for (i = 0; i < TESTOUTPUT_COUNT*2; i++)
		sys_yield();
}
示例#4
0
文件: fs.c 项目: darfux/jos
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	char *addr;
	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.

	// We will use the VM hardware to keep track of whether a 
	// disk block has been modified since it was last read from 
	// or written to disk. To see whether a block needs writing, 
	// we can just look to see if the PTE_D "dirty" bit is set 
	// in the vpt entry.
	addr = diskaddr(blockno);
	if(!va_is_dirty(addr)) return;

	
	int error;
	int secno = blockno*BLKSECTS;
	error = ide_write(secno, addr, BLKSECTS);
	if(error<0) panic("write block error on writing");

	int env_id = sys_getenvid();
	error = sys_page_map(env_id, addr, 
		env_id, addr, ((PTE_U|PTE_P|PTE_W) & ~PTE_D));
	if(error<0) panic("write block error on clearing PTE_D");



	// panic("write_block not implemented");
}
示例#5
0
void
libmain(int argc, char **argv)
{
	// set env to point at our env structure in envs[].
	// LAB 3: Your code here.
	envid_t pid;

	env = 0;
	pid = sys_getenvid();
	env = (struct Env *)envs;
	env = env + ENVX(pid);
	// Debug info
	// cprintf("pid %u\n", pid);
	// cprintf("off %u\n", ENVX(pid));
	LOG(DEBUG_LIBMAIN, "In libmain, about to start user program %x\n", pid);

	// save the name of the program so that panic() can use it
	if (argc > 0)
		binaryname = argv[0];

	// call user main routine
	umain(argc, argv);

	// exit gracefully
	exit();
}
示例#6
0
文件: pgfault.c 项目: ajsbu/cse506
//
// Set the page fault handler function.
// If there isn't one yet, _pgfault_handler will be 0.
// The first time we register a handler, we need to
// allocate an exception stack (one page of memory with its top
// at UXSTACKTOP), and tell the kernel to call the assembly-language
// _pgfault_upcall routine when a page fault occurs.
//
void
set_pgfault_handler(void (*handler)(struct UTrapframe *utf))
{
	int r;

	//cprintf("inside page fault handler, _pgfault_handler = %0x\n", _pgfault_handler);
	if (_pgfault_handler == 0) {
		// First time through!
		// LAB 4: Your code here.
		envid_t envid = sys_getenvid();
		r = sys_page_alloc(envid, (void*) (UXSTACKTOP - PGSIZE), PTE_P|PTE_U|PTE_W);
		r = sys_page_alloc(envid, (void*) (UXSTACKTOP - 2*PGSIZE), PTE_P|PTE_U|PTE_W);
		if(r < 0)
			panic("page_alloc: %e", r);
		//cprintf("setting the upcall\n");
		r = sys_env_set_pgfault_upcall(envid, _pgfault_upcall);
		//cprintf("set the upcall with result = %d\n", r);
		if(r < 0)
			panic("pgfault_upcall: %e", r);
		//panic("set_pgfault_handler not implemented");
	}

	// Save handler pointer for assembly to call.
	_pgfault_handler = handler;
}
示例#7
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use uvpd, uvpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
  extern void _pgfault_upcall();
  // LAB 4: Your code here.
  set_pgfault_handler(pgfault);

  envid_t envid = sys_exofork();
  if (envid == 0) {
    thisenv = &envs[ENVX(sys_getenvid())];
    return 0;
  }
  if (envid < 0) {
    panic("sys_exofork failed: %e", envid);
  }

  uint32_t addr;
  for (addr = 0; addr < USTACKTOP; addr += PGSIZE) {
    if ((uvpd[PDX(addr)] & PTE_P) && (uvpt[PGNUM(addr)] & PTE_P) && (uvpt[PGNUM(addr)] & PTE_U)) {
      duppage(envid, PGNUM(addr));
    }
  }
  int alloc_err = sys_page_alloc(envid, (void *)(UXSTACKTOP-PGSIZE), PTE_U|PTE_W|PTE_P);
  if (alloc_err) {
    panic("sys_page_alloc failed with error: %e", alloc_err);
  }
  sys_env_set_pgfault_upcall(envid, _pgfault_upcall);
  int set_status_err = sys_env_set_status(envid, ENV_RUNNABLE);
  if (set_status_err) {
    panic("sys_env_set_status");
  }
  return envid;
}
示例#8
0
文件: pgfault.c 项目: yahu/JOS
//
// Set the page fault handler function.
// If there isn't one yet, _pgfault_handler will be 0.
// The first time we register a handler, we need to
// allocate an exception stack (one page of memory with its top
// at UXSTACKTOP), and tell the kernel to call the assembly-language
// _pgfault_upcall routine when a page fault occurs.
//
void
set_pgfault_handler(void (*handler)(struct UTrapframe *utf))
{
	int r;
    int re;
    envid_t envid = sys_getenvid();

	if (_pgfault_handler == 0) {
		// First time through!
		// LAB 4: Your code here.

		sys_env_set_pgfault_upcall(envid, _pgfault_upcall);
		re = sys_page_alloc(envid, (void *)(UXSTACKTOP - PGSIZE),PTE_U | PTE_P |PTE_W);
        if( re < 0){
            cprintf("process %x,sys_page_alloc fail\n",envid);
            sys_env_destroy(envid);
        }

		//panic("set_pgfault_handler not implemented");
	}

	// Save handler pointer for assembly to call.

	_pgfault_handler = handler;
	//cprintf("_pgfault_handler = %x\n",(uint32_t)_pgfault_handler);
}
示例#9
0
文件: fork.c 项目: zbh24/JosLab
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use uvpd, uvpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	set_pgfault_handler (pgfault);
	envid_t envid;
	uint32_t addr;
	int r;
	envid = sys_exofork();
	if (envid < 0)
		panic("sys_exofork: %e", envid);
	// We’re the child
	if (envid == 0) {
		env = &envs[ENVX(sys_getenvid())];
		return 0;
	}
	// We’re the parent.
	for (addr = UTEXT; addr < UXSTACKTOP - PGSIZE; addr += PGSIZE) {
	if ((vpd[VPD(addr)] & PTE_P) > 0 && (vpt[VPN(addr)] & PTE_P) > 0 && (vpt[
		VPN(addr)] & PTE_U) > 0)
		duppage (envid, VPN(addr));
	}

	if ((r = sys_page_alloc (envid, (void *)(UXSTACKTOP - PGSIZE), PTE_U|PTE_W|PTE_P)) < 0)
		panic ("fork: page allocation failed : %e", r);
	extern void _pgfault_upcall (void);
	sys_env_set_pgfault_upcall (envid, _pgfault_upcall);
	// Start the child environment running
	if ((r = sys_env_set_status(envid, ENV_RUNNABLE)) < 0)
		panic("fork: set child env status failed : %e", r);
	return envid;
	//panic("fork not implemented");
}
示例#10
0
// Dispatches to the correct kernel function, passing the arguments.
int64_t
syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
//	panic("syscall not implemented");

	switch (syscallno) {

	case SYS_cputs:
			sys_cputs((const char *)a1, (size_t)a2);
			return 0;
	case SYS_cgetc:
			return sys_cgetc();
        case SYS_getenvid:
			return sys_getenvid();
        case SYS_env_destroy:
			return sys_env_destroy(a1);
	case SYS_yield:
			sys_yield();
			return 0;			
	case SYS_page_alloc:
        		return sys_page_alloc((envid_t)a1, (void *)a2,(int)a3);
	case SYS_page_map:
			return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);        
	case SYS_page_unmap:
			return sys_page_unmap((envid_t)a1, (void *)a2);        
	case SYS_exofork:
			return sys_exofork();        
	case SYS_env_set_status:
			return sys_env_set_status((envid_t)a1, a2);	
	case SYS_env_set_pgfault_upcall:
			return sys_env_set_pgfault_upcall((envid_t)a1,(void *)a2);		
	case SYS_ipc_try_send:
			return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, a4);
	case SYS_ipc_recv:
			return sys_ipc_recv((void *)a1);	
	case SYS_env_set_trapframe:
			return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
	case SYS_time_msec:
			return sys_time_msec();
	case SYS_packet_transmit:
			return sys_packet_transmit((char*)a1,(size_t)a2);
	case SYS_packet_receive:
                        return sys_packet_receive((char *)a1);
	//lab 7 code from here
	case SYS_insmod:
			return sys_insmod((char *)a1, (char *)a2,(char *)a3);
	case SYS_rmmod:
			return sys_rmmod((char *)a1);
	case SYS_lsmod:
			return sys_lsmod();
	case SYS_depmod:
			return sys_depmod((char *)a1);
	//lab7 code ends here
	default:
		return -E_NO_SYS;
	}
}
示例#11
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
    envid_t
fork(void)
{
    // LAB 4: Your code here.
    envid_t envid;
        uint64_t addr;
        uint32_t err;
        extern unsigned char end[];
        int r;

        set_pgfault_handler(pgfault);
        envid = sys_exofork();

        if (envid < 0)
                panic("sys_exofork: %e", envid);
        if (envid == 0) {
                // We're the child.
                // The copied value of the global variable 'thisenv'
                // is no longer valid (it refers to the parent!).
                // Fix it and return 0.

                thisenv = &envs[ENVX(sys_getenvid())];
                return 0;
        }

        //Allocate exception stack for the child
        if ((err = sys_page_alloc(envid, (void *) (UXSTACKTOP - PGSIZE), PTE_P|PTE_U|PTE_W)) < 0)
                panic("Error in sys_page_alloc: %e", err);

        // We're the parent.
        // Map our entire address space into the child.
        for (addr = UTEXT; addr < USTACKTOP-PGSIZE; addr += PGSIZE) {
               if((vpml4e[VPML4E(addr)] & PTE_P) && (vpde[VPDPE(addr)] & PTE_P)
                        && (vpd[VPD(addr)] & PTE_P) && (vpt[VPN(addr)] & PTE_P)) {
                       duppage(envid, VPN(addr));
                }
        }

        //Allocate a new stack for the child and copy the contents of parent on to it.
        addr = USTACKTOP-PGSIZE;
	if ((r = sys_page_alloc(0, (void *)PFTEMP, PTE_P|PTE_U|PTE_W)) < 0)
                panic("sys_page_alloc failed: %e\n", r);
        memcpy(PFTEMP, (void *) ROUNDDOWN(addr, PGSIZE), PGSIZE);
        void *vaTemp = (void *) ROUNDDOWN(addr, PGSIZE);
        if ((r = sys_page_map(0, (void *)PFTEMP, envid, vaTemp, PTE_P|PTE_U|PTE_W)) < 0)
                panic("sys_page_map failed: %e\n", r);
        if ((r = sys_page_unmap(0, (void *)PFTEMP)) < 0)
                panic("sys_page_unmap failed: %e\n", r);

        //Set child's page fault handler
        if ((err = sys_env_set_pgfault_upcall(envid, _pgfault_upcall) < 0))
                panic("Error in sys_env_set_pgfault_upcall: %e",err);

        //Set the child ready to run
        if ((err = sys_env_set_status(envid, ENV_RUNNABLE)) < 0)
                panic("sys_env_set_status: %e", err);

        return envid;
    panic("fork not implemented");
}
void _main(void)
{
	char arr[PAGE_SIZE*10];

	uint32 kilo = 1024;

	int envID = sys_getenvid();
//	cprintf("envID = %d\n",envID);

	volatile struct Env* myEnv;
	myEnv = &(envs[envID]);

	int freePages = sys_calculate_free_frames();
	int usedDiskPages = sys_pf_calculate_allocated_pages();

	int i ;
	for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2)
		arr[i] = -1 ;


	cprintf("checking REPLACEMENT fault handling of STACK pages... \n");
	{
		for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2)
			if( arr[i] != -1) panic("modified stack page(s) not restored correctly");

		if( (sys_pf_calculate_allocated_pages() - usedDiskPages) !=  9) panic("Unexpected extra/less pages have been added to page file");

		if( (freePages - (sys_calculate_free_frames() + sys_calculate_modified_frames())) != 0 ) panic("Extra memory are wrongly allocated... It's REplacement: expected that no extra frames are allocated");
	}

	cprintf("Congratulations: stack pages created, modified and read successfully!\n\n");


	return;
}
示例#13
0
文件: spawn.c 项目: jguo2013/smallOS
// Copy the mappings for shared pages into the child address space.
static int
copy_shared_pages(envid_t child)
{
	// LAB 5: Your code here.
	int i,j,ret;
	uintptr_t addr;
	envid_t curr_envid = sys_getenvid();
	
	for(i=0;i<PDX(UTOP);i++)
	{
		if(uvpd[i] & PTE_P && i != PDX(UVPT))
		{
			addr = i << PDXSHIFT;

			for(j=0;j<NPTENTRIES;j++)
			{
				addr = (i<<PDXSHIFT)+(j<<PGSHIFT);
				
				if((uvpt[addr>>PGSHIFT] & PTE_P) && (uvpt[addr>>PGSHIFT] & PTE_SHARE))
				{
					ret = sys_page_map(curr_envid, (void *)addr, child,(void *)addr,PTE_AVAIL|PTE_P|PTE_U|PTE_W);
					if(ret) panic("sys_page_map: %e", ret);
					//cprintf("addr %x is shared\n",addr);
				}				
			}
		}
	}	
示例#14
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
    // Call the function corresponding to the 'syscallno' parameter.
    // Return any appropriate return value.
    // LAB 3: Your code here.
    //
    // TBD: gain 10+ percent of performance improvement 
    // by using goto-label-array.
    switch(syscallno) {
    case SYS_cputs:
	sys_cputs((char *) a1, (size_t) a2);
	break;
    case SYS_cgetc:
	return sys_cgetc();
    case SYS_getenvid:
	return sys_getenvid();
    case SYS_env_destroy:
	sys_env_destroy(a1);
	break;
    case SYS_exofork:
	return sys_exofork();
    case SYS_env_set_status:
	return sys_env_set_status(a1, a2);
    default:
	cprintf("Error syscall(%u)\n", syscallno);
	panic("syscall not implemented");
	return -E_INVAL;
    }
    return 0;
}
示例#15
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	/*stone's solution for lab3-B*/
	int32_t ret = -E_INVAL;
	switch (syscallno){
		case SYS_cputs:
			sys_cputs((char*)a1, a2);
			ret = 0;
			break;
		case SYS_cgetc:
			ret = sys_cgetc();
			break;
		case SYS_getenvid:
			ret = sys_getenvid();
			break;
		case SYS_env_destroy:
			ret = sys_env_destroy(a1);
			break;
		case SYS_map_kernel_page:
			ret = sys_map_kernel_page((void*)a1, (void*)a2);
			break;
		case SYS_sbrk:
			ret = sys_sbrk(a1);
			break;
		default:
			break;
	}
	return ret;
	//panic("syscall not implemented");
}
示例#16
0
void
umain(int argc, char **argv)
{
	int i, j;
	int seen;
	envid_t parent = sys_getenvid();

	// Fork several environments
	for (i = 0; i < 20; i++)
		if (fork() == 0)
			break;
	if (i == 20) {
		sys_yield();
		return;
	}

	// Wait for the parent to finish forking
	while (envs[ENVX(parent)].env_status != ENV_FREE)
		asm volatile("pause");

	// Check that one environment doesn't run on two CPUs at once
	for (i = 0; i < 10; i++) {
		sys_yield();
		for (j = 0; j < 10000; j++)
			counter++;
	}

	if (counter != 10*10000)
		panic("ran on two CPUs at once (counter is %d)", counter);

	// Check that we see environments running on different CPUs
	cprintf("[%08x] stresssched on CPU %d\n", thisenv->env_id, thisenv->env_cpunum);

}
示例#17
0
文件: pgfault.c 项目: MG47/JOS-MG
//
// Set the page fault handler function.
// If there isn't one yet, _pgfault_handler will be 0.
// The first time we register a handler, we need to
// allocate an exception stack (one page of memory with its top
// at UXSTACKTOP), and tell the kernel to call the assembly-language
// _pgfault_upcall routine when a page fault occurs.
//
void
set_pgfault_handler(void (*handler)(struct UTrapframe *utf))
{
	int r;

	if (_pgfault_handler == 0) {
		// First time through!
		// code for lab 4 -M.G
        //	panic("set_pgfault_handler not implemented");

        envid_t cur_envid = sys_getenvid();
        uintptr_t ux_stack_top = UXSTACKTOP - PGSIZE;
        
        if (sys_page_alloc(cur_envid, (void *)ux_stack_top, PTE_P | PTE_U | PTE_W) < 0)
        {        
            panic("ERROR: Cannot allocate memory for exception stack!!");
        }
        
        if (sys_env_set_pgfault_upcall(cur_envid, _pgfault_upcall) < 0)
        {
            panic("ERROR: Cannot set pagefault handler!!");
        }
	}

	// Save handler pointer for assembly to call.
	_pgfault_handler = handler;
}
示例#18
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use uvpd, uvpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
    set_pgfault_handler(pgfault);
    int r, childid;
    childid = sys_exofork();
    if (childid <0)
            panic("exofork error in fork()!\n");
    else if (childid ==0)
    {
            thisenv = &envs[ENVX(sys_getenvid())];
            return 0;
    } else
    {
        int addr;
        for (addr = UTEXT; addr<UXSTACKTOP-PGSIZE; addr+=PGSIZE)
        {
                int pn = PGNUM(addr);
                if (((uvpd[PDX(addr)] & PTE_P) >0) &&
                    ((uvpt[pn] & PTE_P) >0) &&
                    ((uvpt[pn] & PTE_U) > 0))
                        duppage(childid, pn);
        }
        extern void _pgfault_upcall();
        sys_page_alloc(childid, (void*) (UXSTACKTOP - PGSIZE),  PTE_U|PTE_W|PTE_P);
        sys_env_set_pgfault_upcall(childid, _pgfault_upcall);
        sys_env_set_status(childid, ENV_RUNNABLE);
        return childid;
    }
}
void _main(void)
{
	int envID = sys_getenvid();
//	cprintf("envID = %d\n",envID);

	volatile struct Env* myEnv;
	myEnv = &(envs[envID]);

	//("STEP 0: checking Initial WS entries ...\n");
	{
		if( ROUNDDOWN(myEnv->__uptr_pws[0].virtual_address,PAGE_SIZE) !=   0x200000)  	panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[1].virtual_address,PAGE_SIZE) !=   0x201000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[2].virtual_address,PAGE_SIZE) !=   0x202000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[3].virtual_address,PAGE_SIZE) !=   0x203000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[4].virtual_address,PAGE_SIZE) !=   0x204000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[5].virtual_address,PAGE_SIZE) !=   0x205000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[6].virtual_address,PAGE_SIZE) !=   0x800000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[7].virtual_address,PAGE_SIZE) !=   0x801000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( ROUNDDOWN(myEnv->__uptr_pws[8].virtual_address,PAGE_SIZE) !=   0xeebfd000)  panic("INITIAL PAGE WS entry checking failed! Review size of the WS..!!");
		if( myEnv->page_last_WS_index !=  0)  										panic("INITIAL PAGE WS last index checking failed! Review size of the WS..!!");
	}


	int freePages = sys_calculate_free_frames();
	int usedDiskPages = sys_pf_calculate_allocated_pages();

	//Reading (Not Modified)
	char garbage1 = arr[PAGE_SIZE*11-1];
	char garbage2 = arr[PAGE_SIZE*12-1];

	//Writing (Modified)
	int i;
	for (i = 0 ; i < PAGE_SIZE*10 ; i+=PAGE_SIZE/2)
	{
		arr[i] = -1 ;
		*ptr = *ptr2 ;
		ptr++ ; ptr2++ ;
	}

	//===================
	//cprintf("Checking PAGE FIFO algorithm... \n");
	{
		if( ROUNDDOWN(myEnv->__uptr_pws[0].virtual_address,PAGE_SIZE) !=  0x801000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[1].virtual_address,PAGE_SIZE) !=  0xeebfd000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[2].virtual_address,PAGE_SIZE) !=  0x809000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[3].virtual_address,PAGE_SIZE) !=  0x803000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[4].virtual_address,PAGE_SIZE) !=  0x804000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[5].virtual_address,PAGE_SIZE) !=  0x80a000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[6].virtual_address,PAGE_SIZE) !=  0x80b000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[7].virtual_address,PAGE_SIZE) !=  0x80c000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");
		if( ROUNDDOWN(myEnv->__uptr_pws[8].virtual_address,PAGE_SIZE) !=  0x800000)  panic("Page FIFO algo failed.. trace it by printing WS before and after page fault");

		if(myEnv->page_last_WS_index != 2) panic("wrong PAGE WS pointer location");

	}

	cprintf("Congratulations!! test PAGE replacement [FIFO Alg.] is completed successfully.\n");
	return;
}
示例#20
0
文件: syscall.c 项目: ichaos/jos
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
        curenv->env_syscalls++;
        switch(syscallno){
        case SYS_cputs:
                sys_cputs((char *)a1, (size_t)a2);break;
        case SYS_cgetc:
                sys_cgetc();break;
        case SYS_getenvid:
                return sys_getenvid();
        case SYS_env_destroy:
                return sys_env_destroy((envid_t)a1);
        case SYS_dump_env:
                sys_dump_env();break;
        case SYS_page_alloc:
                return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3);
        case SYS_page_map: {
                return sys_page_map((envid_t)a1, (void *)a2,
                                    (envid_t)a3, (void *)a4, (int)a5);
        }
        case SYS_page_unmap:
                return sys_page_unmap((envid_t)a1, (void *)a2);
        case SYS_exofork:
                return sys_exofork();
        case SYS_env_set_status:
                return sys_env_set_status((envid_t)a1,(int)a2);
        case SYS_env_set_trapframe:
                return sys_env_set_trapframe((envid_t)a1,
                                             (struct Trapframe *)a2);
        case SYS_env_set_pgfault_upcall:
                return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
        case SYS_yield:
                sys_yield();break;//new add syscall for lab4;
        case SYS_ipc_try_send:
                return sys_ipc_try_send((envid_t)a1, (uint32_t)a2,
                                        (void *)a3, (unsigned)a4);
        case SYS_ipc_recv:
                return sys_ipc_recv((void *)a1);
        case SYS_ide_read:
                sys_ide_read((uint32_t)a1, (void *)a2, (size_t)a3);
                break;
        case SYS_ide_write:
                sys_ide_write((uint32_t)a1, (void *)a2, (size_t)a3);
                break;
        case SYS_time_msec:
                return sys_time_msec();
        case NSYSCALLS:
                break;
        default:
                return -E_INVAL;
        }
        return 0;

	//panic("syscall not implemented");
}
示例#21
0
void
umain(int argc, char **argv)
{
	uint32_t i=0;
	for(i=0;i<3;i++)
	cprintf("[%8x] Priority Middle is Running!\n",sys_getenvid());
	return;
}
示例#22
0
文件: forktree.c 项目: gzs715/JOS
void
forktree(const char *cur)
{
	cprintf("%04x: I am '%s'\n", sys_getenvid(), cur);

	forkchild(cur, '0');
	forkchild(cur, '1');
}
示例#23
0
//
// User-level fork with copy-on-write.
// Set up our page fault handler appropriately.
// Create a child.
// Copy our address space and page fault handler setup to the child.
// Then mark the child as runnable and return.
//
// Returns: child's envid to the parent, 0 to the child, < 0 on error.
// It is also OK to panic on error.
//
// Hint:
//   Use vpd, vpt, and duppage.
//   Remember to fix "thisenv" in the child process.
//   Neither user exception stack should ever be marked copy-on-write,
//   so you must allocate a new page for the child's user exception stack.
//
envid_t
fork(void)
{
	// LAB 4: Your code here.
	int r;
	envid_t envid;
	set_pgfault_handler(pgfault);
	if((envid = sys_exofork())<0)
		panic("sys_exofork error: %e\n",envid);

	if(envid == 0){
		thisenv = &envs[ENVX(sys_getenvid())];
		return 0;
	}	
	


	uint32_t vaddr;
	extern unsigned char end[];

	for (vaddr = 0 ; vaddr < UTOP; vaddr += PGSIZE ){
		//Check sequentially
		if ((vpml4e[VPML4E(vaddr)] & PTE_P ) && (vpde[VPDPE(vaddr)] & PTE_P ) && (vpd[VPD(vaddr)] & PTE_P ) 
				&& (vpt[VPN(vaddr)] & PTE_P)){ //Order is imp...
			if ((vaddr != (UXSTACKTOP - PGSIZE)) && (vaddr != (USTACKTOP - PGSIZE))){
				duppage(envid, (uint64_t)vaddr / PGSIZE);
			}
		}	
	}


	if ((r = sys_page_alloc(envid,(void*)(USTACKTOP - PGSIZE), PTE_U | PTE_W | PTE_P ))<0){
		panic("error from sys_page_alloc: %e\n", r);

	}
	else 
	{
		if ((r = sys_page_alloc(0, PFTEMP, PTE_U|PTE_W|PTE_P)) < 0)
	        panic("error from sys_page_alloc: %e", r);

		memmove(PFTEMP, (void *)(USTACKTOP - PGSIZE), PGSIZE);

		if ((r = sys_page_map(0,PFTEMP, envid, (void *)(USTACKTOP - PGSIZE) , PTE_U|PTE_W|PTE_P)) < 0)
	        panic("error from sys_page_map: %e", r);
	}

	if((r = sys_page_alloc(envid,(void*)(UXSTACKTOP - PGSIZE), PTE_U | PTE_W | PTE_P ))<0)	
		panic("error from sys_page_alloc : %e\n",r);

	if((r=sys_env_set_pgfault_upcall(envid, thisenv->env_pgfault_upcall))!=0)
		panic("error from sys_env_set_pgfault_upcall : %e\n",r);

	if((r = sys_env_set_status(envid, ENV_RUNNABLE))<0)
		panic("error from sys_env_set_status : %e\n",r);
	
	return envid;

}
void _main(void)
{	
	int envID = sys_getenvid();

	volatile struct Env* myEnv;
	myEnv = &(envs[envID]);

	int Mega = 1024*1024;
	int kilo = 1024;
	char minByte = 1<<7;
	char maxByte = 0x7F;
	short minShort = 1<<15 ;
	short maxShort = 0x7FFF;
	int minInt = 1<<31 ;
	int maxInt = 0x7FFFFFFF;

	void* ptr_allocations[20] = {0};
	{
		ptr_allocations[0] = malloc(2*Mega-kilo);
		char *byteArr = (char *) ptr_allocations[0];
		int lastIndexOfByte = (2*Mega-kilo)/sizeof(char) - 1;
		byteArr[0] = minByte ;
		byteArr[lastIndexOfByte] = maxByte ;

		ptr_allocations[1] = malloc(2*Mega-kilo);
		short *shortArr = (short *) ptr_allocations[1];
		int lastIndexOfShort = (2*Mega-kilo)/sizeof(short) - 1;
		shortArr[0] = minShort;
		shortArr[lastIndexOfShort] = maxShort;

		ptr_allocations[2] = malloc(2*kilo);
		int *intArr = (int *) ptr_allocations[2];
		int lastIndexOfInt = (2*kilo)/sizeof(int) - 1;
		intArr[0] = minInt;
		intArr[lastIndexOfInt] = maxInt;

		ptr_allocations[3] = malloc(7*kilo);
		struct MyStruct *structArr = (struct MyStruct *) ptr_allocations[3];
		int lastIndexOfStruct = (7*kilo)/sizeof(struct MyStruct) - 1;
		structArr[0].a = minByte; structArr[0].b = minShort; structArr[0].c = minInt;
		structArr[lastIndexOfStruct].a = maxByte; structArr[lastIndexOfStruct].b = maxShort; structArr[lastIndexOfStruct].c = maxInt;

		//Check that the values are successfully stored
		if (byteArr[0] 	!= minByte 	|| byteArr[lastIndexOfByte] 	!= maxByte) panic("Wrong allocation: stored values are wrongly changed!");
		if (shortArr[0] != minShort || shortArr[lastIndexOfShort] 	!= maxShort) panic("Wrong allocation: stored values are wrongly changed!");
		if (intArr[0] 	!= minInt 	|| intArr[lastIndexOfInt] 		!= maxInt) panic("Wrong allocation: stored values are wrongly changed!");

		if (structArr[0].a != minByte 	|| structArr[lastIndexOfStruct].a != maxByte) 	panic("Wrong allocation: stored values are wrongly changed!");
		if (structArr[0].b != minShort 	|| structArr[lastIndexOfStruct].b != maxShort) 	panic("Wrong allocation: stored values are wrongly changed!");
		if (structArr[0].c != minInt 	|| structArr[lastIndexOfStruct].c != maxInt) 	panic("Wrong allocation: stored values are wrongly changed!");


	}

	cprintf("Congratulations!! test malloc (2) completed successfully.\n");

	return;
}
示例#25
0
文件: fork.c 项目: HVNT/6.828
//
// Custom page fault handler - if faulting page is copy-on-write,
// map in our own private writable copy.
//
static void
pgfault(struct UTrapframe *utf)
{
    void *addr = (void *) utf->utf_fault_va;
    uint32_t err = utf->utf_err;
    int r;

    // Check that the faulting access was (1) a write, and (2) to a
    // copy-on-write page.  If not, panic.
    // Hint:
    //   Use the read-only page table mappings at vpt
    //   (see <inc/memlayout.h>).

    // LAB 4: Your code here.
    // seanyliu
    if (!(err & FEC_WR) || !(vpt[VPN(addr)] & PTE_COW)) {
        panic("pgfault, err != FEC_WR or not copy-on-write page");
    }

    // Allocate a new page, map it at a temporary location (PFTEMP),
    // copy the data from the old page to the new page, then move the new
    // page to the old page's address.
    // Hint:
    //   You should make three system calls.
    //   No need to explicitly delete the old page's mapping.

    // LAB 4: Your code here.
    // seanyliu
    addr = ROUNDDOWN(addr, PGSIZE);
    // Allocate a new page, map it at a temporary location (PFTEMP),
    if ((r = sys_page_alloc(sys_getenvid(), (void *)PFTEMP, PTE_U | PTE_W | PTE_P)) < 0) {
        panic("pgfault: sys_page_alloc %d", r);
    }
    // copy the data from the old page to the new page
    memmove(PFTEMP, addr, PGSIZE);
    // move the new page to the old page's address.
    if ((r = sys_page_map(sys_getenvid(), PFTEMP, sys_getenvid(), addr, PTE_U | PTE_W | PTE_P)) < 0) {
        panic("pgfault: sys_page_map %d", r);
    }
    if ((r = sys_page_unmap(sys_getenvid(), PFTEMP)) < 0) {
        panic("pgfault: sys_page_unmap %d", r);
    }

    //panic("pgfault not implemented");
}
示例#26
0
//
// Set the page fault handler function.
// If there isn't one yet, _pgfault_handler will be 0.
// The first time we register a handler, we need to
// allocate an exception stack (one page of memory with its top
// at UXSTACKTOP), and tell the kernel to call the assembly-language
// _pgfault_upcall routine when a page fault occurs.
//
    void
set_pgfault_handler(void (*handler)(struct UTrapframe *utf))
{
    int r;

    if (_pgfault_handler == 0) {
        // First time through!
        // LAB 4: Your code here.
	if ((r = sys_page_alloc(sys_getenvid(), (void*)(UXSTACKTOP-PGSIZE), PTE_P|PTE_U|PTE_W)) <  0)
                       panic("error sys_page_alloc: %e\n",r);

        if ((r = sys_env_set_pgfault_upcall(sys_getenvid(), _pgfault_upcall)) < 0)
        	panic("error sys_env_set_pgfault_upcall: %e\n",r);
    }

    // Save handler pointer for assembly to call.
    _pgfault_handler = handler;
}
示例#27
0
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
	int32_t ret = -E_INVAL;
	switch(syscallno) {
		case SYS_cputs:
			sys_cputs((char *)a1, a2);
			break;
		case SYS_cgetc:
			ret = sys_cgetc();
			break;
		case SYS_getenvid:
			ret = sys_getenvid();
			break;
		case SYS_env_destroy:
			ret = sys_env_destroy(a1);
			break;
		case SYS_yield:
			sys_yield();
			ret = 0;
			break;
		case SYS_map_kernel_page:
			ret = sys_map_kernel_page((void *)a1, (void *)a2);
			break;
		case SYS_sbrk:
			ret = sys_sbrk(a1);
			break;
		case SYS_exofork:
			ret = sys_exofork();
			break;
		case SYS_env_set_status:
			ret = sys_env_set_status(a1,a2);
			break;
		case SYS_page_alloc:
			ret = sys_page_alloc(a1,(void*)a2,a3);
			break;
		case SYS_page_map:
			ret = sys_page_map(a1,(void*)a2,a3,(void*)a4,a5);
			break;
		case SYS_page_unmap:
			ret = sys_page_unmap(a1,(void*)a2);
			break;
		case SYS_env_set_pgfault_upcall:
			ret = sys_env_set_pgfault_upcall(a1,(void*)a2);
			break;
		case SYS_ipc_try_send:
			ret = sys_ipc_try_send(a1,a2,(void*)a3,a4);
			break;
		case SYS_ipc_recv:
			ret = sys_ipc_recv((void*)a1);
	}
	return ret;
//	panic("syscall not implemented");
}
示例#28
0
文件: syscall.c 项目: dannoy/JOS
// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
    /* lj */
    int ret = 0;
    switch(syscallno) {
        case SYS_cputs:
            sys_cputs((const char *)a1, a2);
        break;
        case SYS_cgetc:
            ret = sys_cgetc();
        break;
        case SYS_getenvid:
            ret = sys_getenvid();
        break;
        case SYS_env_destroy:
            ret = sys_env_destroy(a1);
        break;
        case SYS_yield:
            sys_yield();
        break;
        case SYS_exofork:
            ret = sys_exofork();
        break;
        case SYS_env_set_status:
            ret = sys_env_set_status((envid_t)a1, a2);
        break;
        case SYS_page_alloc:
            ret = sys_page_alloc((envid_t)a1, (void *)a2, a3);
        break;
        case SYS_page_map:
            ret = sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, a5);
        break;
        case SYS_page_unmap:
            ret = sys_page_unmap((envid_t)a1, (void *)a2);
        break;
        case SYS_env_set_pgfault_upcall:
            ret = sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2);
        break;
        case SYS_ipc_try_send:
            ret = sys_ipc_try_send((envid_t)a1, a2, (void *)a3, a4);
        break;
        case SYS_ipc_recv:
            ret = sys_ipc_recv((void *)a1);
        break;
        default:
            ret = -E_INVAL;
        break;
    }

    //panic("syscall not implemented");
    //cprintf("%d return to user %d\n", syscallno, ret);
    return ret;
}
示例#29
0
    void
handler(struct UTrapframe *utf)
{
    cprintf("\n IN FAULT DIE HANDLER \n");
    void *addr = (void*)utf->utf_fault_va;
    uint32_t err = utf->utf_err;
    cprintf("i faulted at va %x, err %x\n", addr, err & 7);
    sys_env_destroy(sys_getenvid());
}
void umain(int argc, char **argv)
{
	sys_env_set_priority(0, PRIORITY_SUPER);
	int i;
	int n = 3;
	for (i = 0; i < n; i++) {
		cprintf("[%08x] Super Priority Process is Running\n", sys_getenvid());
	}
	return;
}