Analysis of implementation mechanism of JOS fork function
It's a little chick freeze. It was a very confusing moment before the place. Now, the chatter about the fork.
This article will focus on two implementation strategies for fork:
1. Do not use the cow policy to achieve dumbfork (very violent copy)
2. Fork using Cow Technology (copy-on-write, parent process, child process any process to the co-mapping of the space has changed, the copy action, changed which page copy which page, not all the user space copy).
As you know, in Unix class systems, the most common thing to create a child process is fork.
And there's a really nice, roaring technique called cow (copy on write) that's applied to it.
First, a connector detail is described. Each linker will be marked at the end of the BSS section when it generates the last executable program-end.
You can think of this end as a global variable, a pointer to the end of the BSS segment. (BSS is the end of all segments, so this pointer points to the end of the executable program: and the BSS section is almost no space, and then in fact point to the end of the data section.)
On the left is the obj/kern/kernel.sym part to the right is Obj/user/dumbfork.sym
Let's pay attention to the end tag. After each program has been compiled, end is appended to the BSS section.
In a user-space program, the end of user space is referenced, not the kernel.
This is a very necessary background. Let's analyze two fork strategies
1. DUMBFORK.C (I do not post all the code, only to do the important theoretical analysis, all the code can go to GitHub to see, so that the writing of something only makes sense)
Here Sys_exofork just assigns a new env struct to the new process to describe the new subprocess.
The child process's user space memory is not yet allocated.
D
Before I panicked here for a long time, I am very suspicious, why here dare to give the child process global variable thisenv assignment? The back will duppage the entire parent process's user-space data copy past. No, it's covered. Does this assignment work on white? I was very depressed at the time (young man, too too naive ...). You know, this sub-process is still not running! So it's not going to happen. Thisenv assignment operation, the child process is not running, and so the parent run is almost finished, will be set to the child runable. Then the sub-process will be run, and then enter if (Envid = = 0)
Go ahead and see how to copy the parent process to child process.
Call Duppage () to copy the address from Utext to end (Sir if you forget, go ahead)
In fact, here Utext ~ End only is not a large section of user space. (Suggest you go to cprintf, print out these two addresses, and then against the memlayout.h to see, instantly understand.) I've been in here a few days, all kinds of ruin three views)
Finally, we have copied the user's executable program, the global variable God horse (for loop inside the duppage). But we haven't copied the stack yet. The address of the stack is above end.
So there was Duppage (Envid, RoundDown (& addr, pgsize));
It panicked for a long time, because I didn't notice that he passed in the address of the pointer addr , not the address addr pointed to. I'm a guy, because here addr is a function local variable, which is on the stack. So use this address is a stack address, and then RoundDown find the lowest address of the stack, direct duppage. The copy of the user space stack is then taken care of. A copy of the process is also completed.
2. lib/fork.c
To understand this fork implementation must understand the User Space page fault handler mechanism. This is the basis of N-multi-strategy.
Portal: http://blog.csdn.net/cinmyheart/article/details/45271455
Look at the front and Dumbfork still very similar, are called Sys_exofork to get a new struct env.
The difference is in the back. How did you implement cow (copy on write)?
The next two-layer for loop, according to the page Directory also page table to the existence of the page (pte_p), in addition to the exception stack all mappings.
Then, the exception stack is two processes, the only memory area that is not shared before the write operation occurs. The memory is mapped separately to the exception stack.
or a duppage.
The strategy is awesome . First, regardless of whether the original page is writable (pte_w or Pte_cow), the page of the current process will be
Perm = Pte_u | Pte_p the map.
1. If there can be Pte_w or Pte_cow,
Then we all take perm = Pte_u | pte_p | Pte_cow mapping, be careful not to give pte_w permission.
2. If there is pte_cow in the perm, then perm = Pte_u | pte_p | Pte_cow re-mapping itself
When the Duppage is finished, two process space, the same virtual address all the permissions are the same (or apart from the exception stack).
In two processes, any process that attempts to write to a page will trigger page fault because there is no pte_w permission.
The page fault handler of user space here will pte_p | Pte_w | Pte_u permissions re-request a page of physical memory to add to the corresponding process.
Hey, feel so clear and intuitive mechanism, how I had to die before the tangled pinch .... Toss this fork for a long time. Today is an account of the ~
Analysis of implementation mechanism of JOS fork function