Understanding the linux kernel-ch3-Creating Processes
2008-07-01 20:59
633 查看
Traditional Unix systems copying the entire address space of the parent process | |||||||||||
Modern Unix kernels solve this problem by introducing three different mechanisms: | |||||||||||
Copy On Write | |||||||||||
Lightweight processes | |||||||||||
vfork( ) system call creates a process that shares the memory address space of its parent | |||||||||||
The clone( ), fork( ), and vfork( ) System Calls | |||||||||||
| fork( ) | vfork( ) | |||||||||
Clone flags | |||||||||||
克隆 | sys_clone() | sys_fork( ) | sys_vfork | ||||||||
do_fork( ) | |||||||||||
The value returned by the system call is contained in eax: | |||||||||||
the value is 0 for the child and equal to the PID for the child's parent | |||||||||||
clone(fn, arg, flags, child_stack, tls,ptid, ctid ) | |||||||||||
Clone flags | |||||||||||
/* | |||||||||||
* cloning flags: | |||||||||||
*/ | |||||||||||
#define CSIGNAL | 0x000000ff | /* signal mask to be sent at exit */ | |||||||||
#define CLONE_VM | 0x00000100 | /* set if VM shared between processes */ | |||||||||
#define CLONE_FS | 0x00000200 | /* set if fs info shared between processes */ | |||||||||
#define CLONE_FILES | 0x00000400 | /* set if open files shared between processes */ | |||||||||
#define CLONE_SIGHAND | 0x00000800 | /* set if signal handlers and blocked signals shared */ | |||||||||
#define CLONE_IDLETASK | 0x00001000 | /* set if new pid should be 0 (kernel only)*/ | |||||||||
#define CLONE_PTRACE | 0x00002000 | /* set if we want to let tracing continue on the child too */ | |||||||||
#define CLONE_VFORK | 0x00004000 | /* set if the parent wants the child to wake it up on mm_release */ | |||||||||
#define CLONE_PARENT | 0x00008000 | /* set if we want to have the same parent as the cloner */ | |||||||||
#define CLONE_THREAD | 0x00010000 | /* Same thread group? */ | |||||||||
#define CLONE_NEWNS | 0x00020000 | /* New namespace group? */ | |||||||||
#define CLONE_SYSVSEM | 0x00040000 | /* share system V SEM_UNDO semantics */ | |||||||||
#define CLONE_SETTLS | 0x00080000 | /* create a new TLS for the child */ | |||||||||
#define CLONE_PARENT_SETTID | 0x00100000 | /* set the TID in the parent */ | |||||||||
#define CLONE_CHILD_CLEARTID | 0x00200000 | /* clear the TID in the child */ | |||||||||
#define CLONE_DETACHED | 0x00400000 | /* Not used - CLONE_THREAD implies detached uniquely */ | |||||||||
#define CLONE_UNTRACED | 0x00800000 | /* set if the tracing process can't force CLONE_PTRACE on this clone */ | |||||||||
#define CLONE_CHILD_SETTID | 0x01000000 | /* set the TID in the child */ | |||||||||
#define CLONE_STOPPED | 0x02000000 | /* Start in stopped state */ | |||||||||
do_fork( ) | |||||||||||
1,Allocates a new PID | |||||||||||
2,Checks the ptrace field of the parent (current->ptrace) | |||||||||||
3,Invokes copy_process() | |||||||||||
4,clone flag check | |||||||||||
copy_process( ) | |||||||||||
1,clone_flags check | |||||||||||
2,security_task_create() | |||||||||||
3,dup_task_struct( ) | |||||||||||
4,check current->signal->rlim | |||||||||||
5,Update user_struct | |||||||||||
6,Checks total number of processes of user | |||||||||||
7,Update usage counters | |||||||||||
8,Sets a few crucial fields related to the process state | |||||||||||
9,Stores the PID of the new process in the tsk->pid field | |||||||||||
10,CLONE_PARENT_SETTID flag in the clone_flags parameter is set | |||||||||||
copies the child's PID into the User Mode variable addressed by the parent_tidptr parameter. | |||||||||||
11,Initializes the list_head data structures and the spin locks included in the child's process descriptor | |||||||||||
12,Invokes copy_semundo( ), copy_files( ), copy_fs( ), copy_sighand( ), copy_signal( ), copy_mm( ), and copy_namespace( ) | |||||||||||
13,Invokes copy_thread( ) to initialize the Kernel Mode stack of the child process | |||||||||||
with the values contained in the CPU registers when the clone( ) system call was issued | |||||||||||
14,copies the value of the child_tidptr parameter in the tsk->set_chid_tid or tsk->clear_child_tid field | |||||||||||
15,Turns off the TIF_SYSCALL_TRACE flag in the tHRead_info structure of the child | |||||||||||
16,Initializes the tsk->exit_signal field with the signal number encoded in the low bits of the clone_flags parameter | |||||||||||
17,Invokes sched_fork( ) to complete the initialization of the scheduler data structure of the new process | |||||||||||
18,Sets the cpu field in the thread_info structure of the new process | |||||||||||
19,Initializes the fields that specify the parenthood relationships | |||||||||||
20,If the child does not need to be traced (CLONE_PTRACE flag not set), it sets the tsk->ptrace field to 0 | |||||||||||
21,Executes the SET_LINKS macro to insert the new process descriptor in the process list | |||||||||||
22,If the child must be traced (PT_PTRACED flag in the tsk->ptrace field set), | |||||||||||
it sets tsk->parent to current->parent and inserts the child into the trace list of the debugger | |||||||||||
23,Invokes attach_pid( ) to insert the PID of the new process descriptor in the pidhash[PIDTYPE_PID] hash table | |||||||||||
24,If the child is a thread group leader (flag CLONE_THREAD cleared) | |||||||||||
25,Otherwise, if the child belongs to the thread group of its parent (CLONE_THREAD flag set): | |||||||||||
26,increases the value of the nr_threads variable | |||||||||||
26,Increases the total_forks variable to keep track of the number of forked processes | |||||||||||
28,Terminates by returning the child's process descriptor pointer (tsk). | |||||||||||
Kernel Threads | |||||||||||
kernel threads differ from regular processes in the following ways: | |||||||||||
· Kernel threads run only in Kernel Mode | |||||||||||
· Because kernel threads run only in Kernel Mode, they use only linear addresses greater than PAGE_OFFSET | |||||||||||
Creating a kernel thread | |||||||||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||||||||||
do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, pregs, 0, NULL, NULL); | |||||||||||
The kernel_thread( ) function builds up this stack area so that: | |||||||||||
· The ebx and edx registers will be set by copy_thread() to the values of the parameters fn and arg, respectively | |||||||||||
· The eip register will be set to the address of the following assembly language fragment: | |||||||||||
· movl %edx,%eax | |||||||||||
· pushl %edx | |||||||||||
· call *%ebx | |||||||||||
· pushl %eax | |||||||||||
call do_exit | |||||||||||
Process 0 | |||||||||||
The ancestor of all processes, called process 0, the idle process, or, for historical reasons | |||||||||||
This ancestor process uses the following statically allocated data structures | |||||||||||
(data structures for all other processes are dynamically allocated) | |||||||||||
· A process descriptor stored in the init_task variable, which is initialized by the INIT_TASK macro | |||||||||||
· A thread_info descriptor and a Kernel Mode stack | |||||||||||
stored in the init_thread_union variable and initialized by the INIT_THREAD_INFO macro | |||||||||||
· The following tables, which the process descriptor points to | |||||||||||
o init_mm | |||||||||||
o init_fs | |||||||||||
o init_files | |||||||||||
o init_signals | |||||||||||
o init_sighand | |||||||||||
The tables are initialized, respectively, by the following macros: | |||||||||||
o INIT_MM | |||||||||||
o INIT_FS | |||||||||||
o INIT_FILES | |||||||||||
o INIT_SIGNALS | |||||||||||
o INIT_SIGHAND | |||||||||||
· The master kernel Page Global Directory stored in swapper_pg_dir | |||||||||||
Process 0 is selected by the scheduler only when there are no other processes in the TASK_RUNNING state. | |||||||||||
Process 1 | |||||||||||
The start_kernel( ) function initializes all the data structures needed by the kernel, | |||||||||||
enables interrupts, and creates another kernel thread, named process 1 | |||||||||||
kernel_thread(init, NULL, CLONE_FS|CLONE_SIGHAND); | |||||||||||
. Then init( ) invokes the execve( ) system call to load the executable program init. | |||||||||||
As a result, the init kernel thread becomes a regular process having its own per-process kernel data structure | |||||||||||
The init process stays alive until the system is shut down, | |||||||||||
because it creates and monitors the activity of all processes | |||||||||||
that implement the outer layers of the operating system. | |||||||||||
Other kernel threads | |||||||||||
A few examples of kernel threads (besides process 0 and process 1) are: | |||||||||||
keventd (also called events) | |||||||||||
Executes the functions in the keventd_wq workqueue | |||||||||||
kapmd | |||||||||||
Handles the events related to the Advanced Power Management | |||||||||||
kswapd | |||||||||||
Reclaims memory, as described in the section "Periodic Reclaiming" in Chapter 17 | |||||||||||
pdflush | |||||||||||
Flushes "dirty" buffers to disk to reclaim memory, as described in the section "The pdflush Kernel Threads" in Chapter 15 | |||||||||||
kblockd | |||||||||||
Executes the functions in the kblockd_workqueue workqueue. Essentially, it periodically activates the block device drivers, as described in the section "Activating the Block Device Driver" in Chapter 14. | |||||||||||
ksoftirqd | |||||||||||
Runs the tasklets (see section "Softirqs and Tasklets" in Chapter 4); there is one of these kernel threads for each CPU in the system |
相关文章推荐
- Understanding the linux kernel-ch3-Process descriptor
- Understanding the linux kernel-ch3-Process Switch
- Understanding the linux kernel-ch3-Destroying Processes
- Understanding the linux kernel-ch6-Timing Measurements
- Understanding the linux kernel-ch7-Process Scheduling
- Understanding the linux kernel-ch4-Interrupts and Exceptions
- understanding the linux kernel
- Understanding the linux kernel-ch4-Exception Handling
- Notes on Understanding The Linux Kernel
- 《Understanding the Linux kernel》学习笔记 Chapter 1: Introduction
- Notes on Understanding the Linux Kernel
- 《Understanding the Linux kernel》学习笔记 Chapter 13: I/O Architecture and Device Drivers
- Understanding the linux kernel 3rd edition
- 《Understanding the Linux kernel》学习笔记 Chapter 12: The Virtual Filesystem
- Memory Addressing(Understanding the Linux Kernel)
- Understanding the linux kernel-ch1-overview
- Understanding the linux kernel-ch4-Interrupt and exception
- Understanding the linux kernel-ch4-Interrupt Handling
- Introduction(Understanding the Linux Kernel)
- Understanding the Linux Kernel