首页 > 系统服务 > 详细

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

时间:2020-06-15 14:05:21      阅读:71      评论:0      收藏:0      [点我收藏+]

1.以fork和execve系统调用为例分析中断上下文的切换

 

(1)fork系统调用

使用fork库函数,c代码如下

 技术分享图片

反汇编之后,可以看到汇编代码如下

技术分享图片

 可以看到系统调用号保存在ax中,fork系统调用号为0x38,之后执行syscall指令,进入系统调用入口,entry_SYSCALL_64,用gdb追踪执行过程

技术分享图片

在entry_SYSCALL_64中,保存现场,用swapgs保存快照,调用do_syscall_64

技术分享图片

在do_syscall_64中利用系统调用号在syscall_64.tbl找到对应的系统调用函数,转到具体的内核中的系统调用函数执行,可以看出在这里使用了__x64_sys_clone函数

技术分享图片

在__x64_sys_clone函数中,返回_do_fork()函数,在_do_fork函数中完成子进程的创建

技术分享图片

在_do_fork函数中,使用copy_process函数,进行复制进程描述符和执?时所需的其他数据结构的操作

技术分享图片

在copy_process函数中,使用dup_task_struct进行复制进程描述符task_struct、创建内核堆栈等操作

技术分享图片

在dup_task_struct中,使用arch_dup_task_struct完成进程描述符的拷贝,让tsk指针指向org指针。

技术分享图片

在copy_process函数中,使用copy_thread_tls构造fork系统调?在?进程的内核堆栈

技术分享图片

在_do_fork函数中,使用wake_up_new_task,将?进程添加到就绪队列,子进程之后就可从ret_from_fork开始执行。
技术分享图片

 

(2)execve系统调用

c代码如下, 先fork一个子进程,在子进程中使用execlp,执行可执行程序ls。

技术分享图片

用gdb追踪execve系统调用过程:

系统调用入口为__x64_sys_execve

技术分享图片
执行其中的do_execve
技术分享图片

进入其中的do_execveat_common函数

技术分享图片

 进入其中的__do_execve_fifile函数

技术分享图片

进入其中的exec_binprm()函数

技术分享图片

进入其中的search_binary_handler函数,找到解析当前文件的程序入口

技术分享图片

进入其中的load_elf_binary函数,进行校检文件,加载文件到内存并映射到进程的地址空间

技术分享图片

 进入其中的start_thread函数,配置进程启动上下文环境

技术分享图片

 

2.分析execve系统调用中断上下文的特殊之处

execve执行后,加载新的可执行程序,会把当前进程的可执行程序覆盖,execve系统调用返回时将不会返回到调用execve的地方,而是新的可执行程序main函数的入口。

3.分析fork子进程启动执行时进程上下文的特殊之处

由于fork创建了子进程,而子进程需要进行系统调用返回时,内核函数调用堆栈中没有用于返回的地址和一些必要框架,所以在_do_fork函数中的copy_process函数中,使用copy_thread_tls构造fork系统调?在?进程的内核堆栈,使堆栈包含两部分,struct pt_regs regs和struct inactive_task_frame frame,struct pt_regs regs为一般系统调用时所需的堆栈栈底,struct inactive_task_frame frame包含寄存器信息和返回的地址ret_addr,通过该结构,可以使子进程正常的系统调用返回。

 4.以系统调用作为特殊的中断,结合中断上下文切换和进程上下文切换分析Linux系统的一般执行过程

以64位系统为例,首先一个进程正在执行,此时发生系统调用或异常,产生中断,由cpu跳转到中断处理程序调用入口,在入口内,使用swapgs保存现场,之后加载当前进程内核堆栈栈顶地址到RSP寄存器,将当前CPU关键上下?压?内核堆栈,使进程由用户态切换到内核态,中断处理完成后的调度时机或中断处理过程中进行调度,调用schedule函数,通过进程调度算法选择要被调度的进程,其中的switch_to函数进行进程上下文切换,保存寄存器,将内核堆栈切换为被选中的next进程的内核堆栈,将寄存器切换为next进程,由于next之前使用此方法调度至其他进程,所以直接可以接着执行next进程,next进程中断处理完成后回到next进程用户态,继续运行next进程。

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

原文:https://www.cnblogs.com/lclclclc/p/13039471.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!