I am working on the implementation of system call sys_fork() on the kernel level. I did the copying of the parent process to the child process as per requirements. The problem is how to copy the child's trapframe (copy of the parent trapframe) onto the child's kernel stack to pass the assertion in mips_usermode()?
2 Answers
I figured out my problem.
But what I am going to say is related to OS161 system. So anyone working on this system, this will be helpful.
Ok, there is a function on the kernel side which deals with context switch. This function stores all the data related to context switch frame onto the threads kernel stack.
So all you need to do is follow the same steps and instead of switch frame structure, you need to replace it with trap frame structure.
Here is the implementation for it:-
vaddr_t stacktop;
struct trapframe *tf;
stacktop = ((vaddr_t)thread->t_stack) + STACK_SIZE; //t_stack is the kernel stack
tf = ((struct trapframe *) stacktop) - 1;
t_stack is just a chunk of memory on the kernel side to store anything related to exceptions or context switch.
Be sure to first clean out the t_stack before you load it with trapframe as it will contain data related to context switch frame incase of sys_fork implementation.
Any corrections or comments on this are welcomed.

- 700,868
- 160
- 1,392
- 1,356

- 31
- 1
- 4
-
I like the way you find the trap frame for the parent thread. I am doing the same assignment, but am struggling on how to manipulate the pointer for the child process. Can you please help me out ? – Nov 24 '11 at 00:54
I'm working on OS161 too. Here is how I tackle the problem.
In sys_fork, I copy parent's trapframe into a kernel heap space allocated via kmalloc:
struct trapframe* ctf = (struct trapframe*)kmalloc(sizeof(struct trapframe));
*ctf = *tf; // tf points to parent's trapframe;
Then I use thread_fork to create a child thread:
// passing address space using the second parameter of
// child_forkentry, quite dirty
thread_fork(curthread->t_name, child_forkentry, ctf, (unsigned long)as, NULL);
In child_forkentry, which is the first function called by the child, I do the following:
struct trapframe tf; // tf will be allocated on child's kernel stack
tf = *ctf
misp_usermode(&tf);
This will pass the stack check in mips_usermode.

- 1,077
- 2
- 10
- 15