第六周分析Linux内核创建一个新进程的过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六周分析Linux内核创建一个新进程的过程相关的知识,希望对你有一定的参考价值。

潘恒 原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

task_struct结构:

struct task_struct { 
 volatile long state;进程状态
 void *stack; 堆栈

 pid_t pid; 进程标识符
 unsigned int rt_priority;实时优先级
 unsigned int policy;调度策略
 struct files_struct *files;系统打开文件
 ...
}

内核处理函数sys_clone:
    系统调用通过do_fork实现进程的创建:
return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);

linux系统是通过复制父进程的信息来创建子进程,在do_fork函数中,真正实现复制的是copy_process函数:


p = copy_process(clone_flags, stack_start, stack_size,child_tidptr, NULL, trace);

p = dup_task_struct(current);创建内核栈
retval = security_task_create(clone_flags);
retval = sched_fork(clone_flags, p);和调度相关的设置,cpu将调度这个task
retval = copy_thread(clone_flags, stack_start, stack_size, p); 复制父进程堆栈的内容到子进程的堆栈中去.这其中,copy_thread函数中的语句p->thread.ip = (unsigned long) ret_from_fork决定了新进程的第一条指令地址.

创建栈函数dup_task_struct:
tsk = alloc_task_struct_node(node);开辟内存空间
ti = alloc_thread_info_node(tsk, node);ti指向thread_info的首地址,同时也是系统为新进程分配的两个连续页面的首地址。
err = arch_dup_task_struct(tsk, orig);复制父进程的task_struct信息到新的task_struct里
tsk->stack = ti;task对应栈
setup_thread_stack(tsk, orig);初始化thread info结构
set_task_stack_end_magic(tsk);栈结束的地址设置数据为栈结束标示


新进程从哪里开始执行:

在之前的分析中,谈到copy_process中的copy_thread()函数,正是这个函数决定了子进程从系统调用中返回后的执行.ret_from_fork决定了新进程的第一条指令地址。p->thread.ip = (unsigned long) ret_from_fork;将子进程的ip设置为ret_from_fork的首地址,子进程从ret_from_fork开始执行

执行起点与内核堆栈如何保持一致

1. 在ret_from_fork之前,也就是在copy_thread()函数中*childregs = *current_pt_regs();该句将父进程的regs参数赋值到子进程的内核堆栈,

2. *childregs的类型为pt_regs,里面存放了SAVE ALL中压入栈的参数

3. 故在之后的RESTORE ALL中能顺利执行下去.

 

实验:分析Linux内核创建一个新进程的过程

技术分享

 

技术分享

 

技术分享

 

总结:

1.Linux通过复制父进程来创建一个新进程,通过调用do_fork来实现。

2.Linux为每个新创建的进程动态地分配一个task_struct结构。

3.为了把内核中的所有进程组织起来,Linux提供了几种组织方式,其中哈希表和双向循环链表方式是针对系统中的所有进程(包括内核线程),而运行队列和等待队列是把处于同一状态的进程组织起来。

4.fork()函数被调用一次,但返回两次。

以上是关于第六周分析Linux内核创建一个新进程的过程的主要内容,如果未能解决你的问题,请参考以下文章

第六周分析Linux内核创建一个新进程的过程

Linux内核及分析 第六周 分析Linux内核创建一个新进程的过程

Linux内核设计第六周学习总结 分析Linux内核创建一个新进程的过程

《Linux内核分析》第六周学习总结

《Linux内核分析》第六周学习小结

linux内核分析 第六周读书笔记