????????????
????????????????task_struct??

???????????????????????????????????????????????????????????????PID??????????????????????????????????У???????????????task_struct
???????????饗PCB??
?????????????????????????????????????????
??????????

????fork()
????fork()?????????????????Ρ?????????з????????? pid??????????з???0??
????fork????????????
????#include <stdio.h>
????#include <stdlib.h>
????#include <unistd.h>
????int main(int argc?? char * argv[])
????{
????int pid;
????/* fork another process */
????pid = fork();
????if (pid < 0)
????{
????/* error occurred */
????fprintf(stderr??"Fork Failed!");
????exit(-1);
????}
????else if (pid == 0)
????{
????/* child process */
????printf("This is Child Process! ");
????}
????else
????{ 
????/* parent process  */
????printf("This is Parent Process! ");
????/* parent will wait for the child to complete*/
????wait(NULL);
????printf("Child Complete! ");
????}
????}
???????????
????????????

????fork ???0×80?ж??????????????????????????????????????????????????
????fork.c
????//fork
????#ifdef __ARCH_WANT_SYS_FORK
????SYSCALL_DEFINE0(fork)
????{
????#ifdef CONFIG_MMU
????return do_fork(SIGCHLD?? 0?? 0?? NULL?? NULL);
????#else
????/* can not support in nommu mode */
????return -EINVAL;
????#endif
????}
????#endif
????//vfork
????#ifdef __ARCH_WANT_SYS_VFORK
????SYSCALL_DEFINE0(vfork)
????{
????return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD?? 0??
????0?? NULL?? NULL);
????}
????#endif
????//clone
????#ifdef __ARCH_WANT_SYS_CLONE
????#ifdef CONFIG_CLONE_BACKWARDS
????SYSCALL_DEFINE5(clone?? unsigned long?? clone_flags?? unsigned long?? newsp??
????int __user *?? parent_tidptr??
????int?? tls_val??
????int __user *?? child_tidptr)
????#elif defined(CONFIG_CLONE_BACKWARDS2)
????SYSCALL_DEFINE5(clone?? unsigned long?? newsp?? unsigned long?? clone_flags??
????int __user *?? parent_tidptr??
????int __user *?? child_tidptr??
????int?? tls_val)
????#elif defined(CONFIG_CLONE_BACKWARDS3)
????SYSCALL_DEFINE6(clone?? unsigned long?? clone_flags?? unsigned long?? newsp??
????int?? stack_size??
????int __user *?? parent_tidptr??
????int __user *?? child_tidptr??
????int?? tls_val)
????#else
????SYSCALL_DEFINE5(clone?? unsigned long?? clone_flags?? unsigned long?? newsp??
????int __user *?? parent_tidptr??
????int __user *?? child_tidptr??
????int?? tls_val)
????#endif
????{
????return do_fork(clone_flags?? newsp?? 0?? parent_tidptr?? child_tidptr);
????}
????#endif
?????????????????????????????????????????? fork ???? vfork ??????????????????? do_fork() ???????????????????????????? do_fork()??????????????????????????
????long do_fork(unsigned long clone_flags??
????unsigned long stack_start??
????unsigned long stack_size??
????int __user *parent_tidptr??
????int __user *child_tidptr)
????{
????//?????????????????
????struct task_struct *p;
????//……
????//???????????????copy_process()??????????? task_struct ???
????p = copy_process(clone_flags?? stack_start?? stack_size??
????child_tidptr?? NULL?? trace);
????if (!IS_ERR(p)) {
????struct completion vfork;
????struct pid *pid;
????trace_sched_process_fork(current?? p);
????//????′???????????????е?pid
????pid = get_task_pid(p?? PIDTYPE_PID);
????nr = pid_vnr(pid);
????if (clone_flags & CLONE_PARENT_SETTID)
????put_user(nr?? parent_tidptr);
????//???????? vfork()??????????? vfork ???????????
????if (clone_flags & CLONE_VFORK) {
????p->vfork_done = &vfork;
????init_completion(&vfork);
????get_task_struct(p);
????}
????//?????????????????У??????? CPU????????
????wake_up_new_task(p);
????//fork ???????????????????
????if (unlikely(trace))
????ptrace_event_pid(trace?? pid);
????//????? vfork?????????????????????У????????????
????if (clone_flags & CLONE_VFORK) {
????if (!wait_for_vfork_done(p?? &vfork))
????ptrace_event_pid(PTRACE_EVENT_VFORK_DONE?? pid);
????}
????put_pid(pid);
????} else {
????nr = PTR_ERR(p);
????}
????return nr;
????}
????do_fork ????
???????? copy_process ???????????????????
????????? vfork ??????????????
???????? wake_up_new_task ??????????????????????? CPU
????????? vfork?????????????????? exec ?滻??????????
????copy_process ????
???????copy_process ?????????
????static struct task_struct *copy_process(unsigned long clone_flags??
????unsigned long stack_start??
????unsigned long stack_size??
????int __user *child_tidptr??
????struct pid *pid??
????int trace)
????{
????int retval;
????//?????????????????
????struct task_struct *p;
????//……
????//???????? task_struct
????p = dup_task_struct(current);
????//……
????//???????????? 
????rt_mutex_init_task(p);
????//?????????????????????????????
????if (atomic_read(&p->real_cred->user->processes) >=
????task_rlimit(p?? RLIMIT_NPROC)) {
????if (p->real_cred->user != INIT_USER &&
????!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
????goto bad_fork_free;
????}
????//……
????//????????????? max_threads ??????С????
????if (nr_threads >= max_threads)
????goto bad_fork_cleanup_count;
????//……
????//???????????
????spin_lock_init(&p->alloc_lock);
????//????????????
????init_sigpending(&p->pending);
????//????? CPU ?????
????posix_cpu_timers_init(p);
????//……
????//?????????????????????????????? TASK_RUNNING
????retval = sched_fork(clone_flags?? p);
????//???????н??????????????????????????????????????????
????if (retval)
????goto bad_fork_cleanup_policy;
????retval = perf_event_init_task(p);
????if (retval)
????goto bad_fork_cleanup_policy;
????retval = audit_alloc(p);
????if (retval)
????goto bad_fork_cleanup_perf;
????/* copy all the process information */
????shm_init_task(p);
????retval = copy_semundo(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_audit;
????retval = copy_files(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_semundo;
????retval = copy_fs(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_files;
????retval = copy_sighand(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_fs;
????retval = copy_signal(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_sighand;
????retval = copy_mm(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_signal;
????retval = copy_namespaces(clone_flags?? p);
????if (retval)
????goto bad_fork_cleanup_mm;
????retval = copy_io(clone_flags?? p);
????//??????????????
????retval = copy_thread(clone_flags?? stack_start?? stack_size?? p);
????//??????????μ? pid
????if (pid != &init_struct_pid) {
????retval = -ENOMEM;
????pid = alloc_pid(p->nsproxy->pid_ns_for_children);
????if (!pid)
????goto bad_fork_cleanup_io;
????}
????//????????? pid 
????p->pid = pid_nr(pid);
????//……
????//??????? p
????return p;
???????? dup_task_struct ???????? task_struct
?????????????????????
?????????????????????????CPU ???????
???????? sched_fork ?????????????????????????????? TASK_RUNNING
???????????н?????????????????????????????????????????
???????? copy_thread ??????????????
??????????????????μ? pid
????dup_task_struct ????
????static struct task_struct *dup_task_struct(struct task_struct *orig)
????{
????struct task_struct *tsk;
????struct thread_info *ti;
????int node = tsk_fork_get_node(orig);
????int err;
????//??????? task_struct ???
????tsk = alloc_task_struct_node(node);
????if (!tsk)
????return NULL;
????//??????? thread_info ??????????????????ti ????
????ti = alloc_thread_info_node(tsk?? node);
????if (!ti)
????goto free_tsk;
????//?????????????????
????tsk->stack = ti;
????//……
????return tsk;
????}
????????alloc_task_struct_node??????? task_struct ???
????????alloc_thread_info_node??????? thread_info ????????????????thread_union?????壬????????? ti
????union thread_union {
????struct thread_info thread_info;
????unsigned long stack[THREAD_SIZE/sizeof(long)];
????};
??????????? ti ???????????
???????????dup_task_struct???????????tsk->stack?????????????????