Linux 第六周实验

时间:2022-11-25 21:52:56

姬梦馨

原创博客

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一.进程控制块PCB——task_struct

    1.操作系统的三大管理功能包括:进程管理、内存管理、 文件系统。

    2.PCB task_struct中包含:进程状态、进程打开的文件、进程优先级信息

    3: 进程的状态不同于操作系统

    一个即在的进程调用fork创建一个新的进程。
进程被高优先级抢占。
do_exit 进程退出。
事件发生或资源可用,可被唤醒进入队列。
TASK_RUNNING具体是就绪还是执行,要看系统当前的资源分配情况

  

4.函数的分析与理解

        struct task_struct {          :运行状态

volatile long state;/* -1 unrunnable, 0 runnable, >0 stopped */void *stack; :内核堆栈;进程运行堆栈.
atomic_t usage;
unsigned int flags;:进程标识符
unsigned int ptrace;
#ifdef CONFIG_SMP :条件编译,多处理器
struct llist_node wake_entry;
int on_cpu;
struct task_struct *last_wakee;
unsigned long wakee_flips;
unsigned long wakee_flip_decay_ts;
int wake_cpu;
#endif
struct list_head tasks;        双向进程链表
#ifdef CONFIG_SMP
struct plist_node pushable_tasks;
struct rb_node pushable_dl_tasks;
#endif
struct mm_struct *mm, *active_mm; 地址空间
#ifdef CONFIG_COMPAT_BRK
unsigned brk_randomized:1;
#endif

  

        struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports         
/* 进程父子关系
* children/sibling forms the list of my natural children
*/
struct list_head children;/* list of my children */
struct list_head sibling;/* linkage in my parent's children list */
struct task_struct *group_leader;/* threadgroup leader */

  

 

/* CPU-specific state of this task */    CPU相关状态,进程切换
struct thread_struct thread
/* filesystem information */ 文件相关,打开描述列表
struct fs_struct *fs;
/* open file information */
struct files_struct *files;
/* namespaces */ 调用
struct nsproxy *nsproxy;
/* signal handlers */ 信号处理
struct signal_struct *signal;
struct sighand_struct *sighand;

二:进程的创建

1. fork

fork系统调用在父进程和子进程各返回一次
子进程中返回的是0,父进程中返回值是子进程的pid。

2. 创建一个新进程在内核中的执行过程

fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。
创建新进程是通过复制当前进程实现的。
do_fork主要是复制了父进程的task_struct,得到子进程.
do_fork()
  • 调用copy_process,将当前进程复制一份出来给子进程,并且为子进程设置相应地上下文信息。
  • 调用wake_up_new_task,将子进程放入调度器的队列中,此时的子进程就可以被调度进程选中运行。
要修改复制过来的进程数据,比如pid、进程链表等。

3. 子进程系统调用处理过程

   fork出来的子进程是从ret_from_fork开始执行的,然后跳转到syscall_exit,从系统调用中返回。

 

三:实践    使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone

1. 启动MenuOS

Linux   第六周实验

2.gdb调试fork命令 : qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

Linux   第六周实验

 

3.编译内核,可以看到fork命令

Linux   第六周实验

 

 

4.设置断点

Linux   第六周实验

 

5.  调试结果

Linux   第六周实验

 

停在了父进程

 

 

总结:

Linux通过复制父进程来创建一个新进程,通过调用do_ fork来实现并为每个新创建的进程动态地分配一个task_ struct结构。

子进程是从ret_ from_ fork开始执行的。