0 Replies - 1070 Views - Last Post: 15 November 2012 - 04:24 PM Rate Topic: -----

#1 CabsContra04  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 15-November 12

fork fails when returning to usermode in OS161

Posted 15 November 2012 - 04:24 PM

I am attempting to implement the sys_fork functionality into OS161. The general idea is simple from the way that I understand it. However, I'm finding that when I attempt to fork, the parent see's the proper PID for the child process, but when the child attempts to call mips_usermode(&tf) the system hangs and eventually crashes. I do not get any sort of TLB miss error or anything else that causes a panic. It simply hangs and I can't see what the issue(s) may be.

Thne idea here is that the parent will call fork which results in a trap to sys_fork(). This will then create a new thread via thread_fork() which will be given md_forkentry as the entry point. This is intended to be the child process and should return to usermode at the very end via mips_usermode(&tf). But like I said, the entire system hangs right at the mips_usermode call. Note that I am engineer by degree and I haves a few years of work experience coding but my C is a bit rusty to say the least.


void
md_forkentry(struct trapframe *temptf, unsigned long vmspace)
{
	/*
	 * This is the entry point for the child process
	 */

	kprintf("Hello! I'm the child!\n");
	
	// Store the heap trapframe
	struct trapframe tf = *temptf;
	
	// Set the child's address space to the one set up by fork
	curthread->t_vmspace = (struct addrspace *)vmspace;
	
	// Set the trapframe values so that the user sees the correct
	// return values.  Also increment the program counter so we don't
	// continue to call the trap code.
	tf.tf_v0 = 0;
	tf.tf_a3 = 0;
	tf.tf_epc += 4;
	
	// Esure that the structure copied into the heap is freed
	kfree(temptf);
	
	// Pass control back to user mode
	kprintf("About to enter user mode\n");
	mips_usermode(&tf);
}

/*
 * This is the implementation of fork.  It is placed here because it goes along with
 * thread_fork and other kernel level thread functions
*/
int
sys_fork(struct trapframe *tf, int32_t *retval)
{
	// This function is responsible for copying the address space
	// of the calling process and changing the PID for the child.
	// It needs to be aware that the calling process may reside in
	// userspace and therefore must use the protected memory copy
	// methods to ensure kernel stability.  This is acomplished by
	// calling copyin to make a copy of the calling address space.
	// We can then use as_copy to copy the memory of the parent
	// process into the child's address.  Finally, we call
	// thread_fork with the arguments for md_forkentry which is
	// the user level process entry point.
	
	kprintf("Entering sys_fork\n");
	// Create a new thread
	struct thread *newguy;
	newguy = thread_create("Child");
	
	// Copy the address space of the parent using as_copy
	// I think this is a protected copy (?)
	as_copy(curthread->t_vmspace,&newguy->t_vmspace);
	
	// Copy the trapframe to the heap so it's available to the child
	struct trapframe *temptf;
	temptf = kmalloc(sizeof(tf));
	memcpy(tf,temptf,sizeof(tf));
	
	// Call thread_fork
	int result = thread_fork("Child Process",                  /* Function Description */
		  	         temptf,                           /* Trapframe            */
			         (unsigned long)newguy->t_vmspace, /* Child Thread address */
			         md_forkentry,                     /* Child entry point    */
			         NULL);                            /* Return thread        */
	
	// Return the pid of the child to the parent process
	*retval = &newguy->pid->pid;
	return 0;
}




Is This A Good Question/Topic? 0
  • +

Page 1 of 1