linux进程上下文切换的具体过程,Linux实验三 结合中断上下文切换和进程上下文切换分析Linux内核一般执行过程...

fork系统调?创建?进程,也就?个进程变成了两个进程,两个进程执?相同的代码,只是fork系统调?在?进程和?进程中的返回值不同。

打开linux-5.4.34/arch/x86/entry/syscalls/syscall_64.tbl 文件,56、 57、 58号系统调?__x64_sys_clone、 __x64_sys_fork、__x64_sys_vfork,即如下kernel/fork.c代码。

9d25aef3fc8b83923f376836674be38d.png

进入linux-5.4.34/kernel/fork.c 查看 fork 源代码:

cf6102aed6183c81d4fc621d1be11289.png

cf6102aed6183c81d4fc621d1be11289.png

d24ee66e7693babf0662ef2437237057.png

/** Create a kernel thread.*/pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned longflags)

{return _do_fork(&args);

}

SYSCALL_DEFINE0(fork)

{return _do_fork(&args);

}

SYSCALL_DEFINE0(vfork)

{return _do_fork(&args);

}

SYSCALL_DEFINE5(clone, unsignedlong, clone_flags, unsigned long, newsp,

{return _do_fork(&args)

}

通过上?的代码可以看出fork、vfork和clone这3个系统调?,以及do_fork和kernel_thread内核函数都可以创建?个新进程,?且都是通过_do_fork函数来创建进程的,只不过传递的参数不同。

_do_fork函数主要完成了调?copy_process()复制?进程、获得?wake_up_new_task将?进程加?就绪队列等待调度执?等。

ffe3bdaff113c596b55e993acf2d7bfe.png

//_do_fork关键部分代码

long _do_fork(struct kernel_clone_args *args)

{//复制进程描述符和执?时所需的其他数据结构

p =copy_process(NULL, trace, NUMA_NO_NODE, args);

wake_up_new_task(p);//将?进程添加到就绪队列

return nr;//返回?进程pid(?进程中fork返回值为?进程的pid)

}

copy_process()是创建?个进程的主要的代码。如下是copy_process()函数的关键代码,完整代码?kernel/fork.c

static __latent_entropy struct task_struct *copy_process(struct pid *pid,inttrace,intnode,struct kernel_clone_args *args)

{//复制进程描述符task_struct、创建内核堆栈等

p =dup_task_struct(current, node);/*copy all the process information*/shm_init_task(p);

…//初始化?进程内核栈和thread

retval = copy_thread_tls(clone_flags, args->stack, args->stack_size, p,

args->tls);

…return p;//返回被创建的?进程描述符指针

}

copy_process函数主要完成了:

调?dup_task_struct复制当前进程(?进程)描述符task_struct

信息检查、初始化、把进程状态设置为TASK_RUNNING(此时?进程置为就绪态)、采?写时复制技术逐?复制所有其他进程资源

调?copy_thread_tls初始化?进程内核栈

设置?进程pid等。

接下来具体看dup_task_struct和copy_thread_tls

dup_task_struct作用:

在专业高速缓冲内存上分配task_struct,并完成初始化

在普通内存中分配thread_info及连续的两个页面,完成初始化

将task_struct和thread_info联系起来

主要代码:

static struct task_struct *dup_task_struct(struct task_struct *orig, intnode)

{…//实际完成进程描述符的拷?,具体做法是*tsk = *orig

err =arch_dup_task_struct(tsk, orig);

tsk->stack =stack;

...//实际完成进程描述符的拷?,具体做法是*tsk = *orig

setup_thread_stack(tsk, orig);

clear_user_return_notifier(tsk);

clear_tsk_need_resched(tsk);

set_task_stack_end_magic(tsk);…

}

copy_thread_tls作用:

负责构造fork系统调?在?进程的内核堆栈,也就是fork系统调?在??进程各返回?次,?进程中和其他系统调?的处理过程并??致,?在?进程中的内核函数调?堆栈需要特殊构建,为?进程的运?准备好上下?环境。

主要代码:

int copy_thread_tls(unsigned long clone_flags, unsigned longsp,

unsignedlong arg, struct task_struct *p, unsigned longtls)

{

frame->ret_addr = (unsigned long) ret_from_fork;

p->thread.sp = (unsigned long) fork_frame;*childregs = *current_pt_regs();

childregs->ax = 0;

.../** Set a new TLS for the child thread?*/

if (clone_flags &CLONE_SETTLS) {

err= do_arch_prctl_64(p, ARCH_SET_FS, tls);

do_fork 总结

进程的创建过程?致是?进程通过fork系统调?进?内核_do_fork函数,如下图所示复制进程描述符及相关进程资源(采?写时复制技术)、分配?进程的内核堆栈并对内核堆栈和thread等进程关键上下?进?初始化,最后将?进程放?就绪队列, fork系统调?返回;??进程则在被调度执?时根据设置的内核堆栈和thread等进程关键上下?开始执?。

9f3bca8d1359d9aa7039296c3144fd50.png

2 execve系统调用

execve(执行文件)在父进程中fork一个子进程,在子进程中调用exec函数启动新的程序。exec函数一共有六个,其中execve为内核级系统调用,其他(execl,execle,execlp,execv,execvp)都是调用execve的库函数。

表头文件:

#include

定义函数:

int execve(const char * filename,char * const argv[ ],char * const envp[ ]);

execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用指针数组来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。成功无返回值,失败返回-1。

7a9b04bbe046e29bf14dac99421dd527.png

execve系统调过程:

sys_execve-->do_execve-->do_execveat_common-->__do_execve_file-->search_binary_handler-->load_elf_binary-->start_thread

execve陷入内核,传入命令行参数和shell上下文环境

sys_execve调用do_execve封装命令行参数和shell上下文

调用do_execveat_common,do_execveat_common调用__do_execve_file,打开ELF文件并把信息的装入linux_binprm结构体

__do_execve_file中调用search_binary_handler,寻找解析ELF文件的函数

search_binary_handler找到ELF文件解析函数load_elf_binary,解析ELF文件,把ELF文件装入内存,修改进程的用户态堆栈,修改进程的数据段代码段

load_elf_binary调用start_thread修改进程内核堆栈

返回用户态,此时ip指向ELF文件的main函数地址

三 Linux的一般执行过程

1) 正在运?的?户态进程X。

2) 发?中断(包括异常、系统调?等), CPU完成load cs:rip(entry of a specific ISR),即跳转到中断处理程序??。

3) 中断上下?切换,具体包括如下?点:

swapgs指令保存现场,可以理解CPU通过swapgs指令给当前CPU寄存器状态做了?个快照。

rsp point to kernel stack,加载当前进程内核堆栈栈顶地址到RSP寄存器。快速系统调?是由系统调???处的汇编代码实现?户堆栈和内核堆栈的切换。

save cs:rip/ss:rsp/rflags:将当前CPU关键上下?压?进程X的内核堆栈,快速系统调?是由系统调???处的汇编代码实现的。

此时完成了中断上下?切换,即从进程X的?户态到进程X的内核态。

4) 中断处理过程中或中断返回前调?了schedule函数,其中完成了进程调度算法选择next进程、进程地址空间切换、以及switch_to关键的进程上下?切换等。

5) switch_to调?了__switch_to_asm汇编代码做了关键的进程上下?切换。将当前进程X的内核堆栈切换到进程调度算法选出来的next进程(本例假定为进程Y)的内核堆栈,并完成了进程上下?所需的指令指针寄存器状态切换。之后开始运?进程Y(这?进程Y曾经通过以上步骤被切换出去,因此可以从switch_to下??代码继续执?)。

6) 中断上下?恢复,与(3)中断上下?切换相对应。注意这?是进程Y的中断处理过程中,?(3)中断上下?切换是在进程X的中断处理过程中,因为内核堆栈从进程X切换到进程Y了。

7) 为了对应起?中断上下?恢复的最后?步单独拿出来(6的最后?步即是7) iret - pop cs:rip/ss:rsp/rflags,从Y进程的内核堆栈中弹出(3)中对应的压栈内容。此时完成了中断上下?的切换,即从进程Y的内核态返回到进程Y的?户态。注意快速系统调?返回sysret与iret的处理略有不同。

8) 继续运??户态进程Y。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/474547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python常见错误及基本技巧

1.2 Python Hello World1.2.1 执行 python 三种方式1.2.1.1 文本模式Python 代码 保存在文件 中,解释器对文件逐行解释执行,在终端中输入解释器名,再输入要执行的文件名:# 使用 python 2.x 以文本模式执行 python 程序$ python xx…

flash加xml图片叠加焦点图,左右箭头翻页

flash加xml左右箭头翻页,叠加焦点图,具体效果如下:源码下载: http://files.cnblogs.com/chendaoyin/flash%E5%8A%A0xml%E5%9B%BE%E7%89%87%E5%8F%A0%E5%8A%A0%E5%B7%A6%E5%8F%B3%E5%88%87%E6%8D%A2%E7%84%A6%E7%82%B9%E5%9B%BE.z…

linux 跨服务器备份,用BackupPC架设Linux跨平台备份服务器

随着数据价值逐渐被重视,当提到备份,更多是希望备份充分而非不够,特别在一些情况发生下庆幸为重要数据所备份所付出精力是值得的。通过xmodulo网站介绍一个跨平台的备份服务器软件BackupPC,它可以通过网络为Linux,Wind…

LeetCode 351. 安卓系统手势解锁(回溯)

文章目录1. 题目2. 解题1. 题目 我们都知道安卓有个手势解锁的界面,是一个 3 x 3 的点所绘制出来的网格。 给你两个整数,分别为 ​​m 和 n,其中 1 ≤ m ≤ n ≤ 9, 那么请你统计一下有多少种解锁手势,是至少需要经过…

Linux 文件基本属性以及操作技巧

Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。 在Linux中我们可以使用ll或者ls –l命令…

POJ2503 Babelfish(二分)

题目链接。 分析&#xff1b; 主要是学着用一下bsearch。 #include <stdio.h> #include <stdlib.h> #include <string.h>struct Entry{char english[15], foreign[15]; }entrys[100010];int cmp(const void *a, const void *b){return strcmp((*(struct Entr…

linux命令解释程序实验,实验二 命令解释程序的使用

实验二 命令解释程序的使用一、实验目的掌握UNIX或LINUX环境下命令解释程序的使用能对编写简单的C程序&#xff0c;进行编译运行和调试。二、实验内容输入LINUX相关命令后记录系统输出简单的C程序&#xff0c;进行编译运行和调试三、实验步骤1、命令操作1) 浏览目录和文件的各…

Linux常用的命令及操作技巧

今天我们就来看几个常见的处理目录的命令吧&#xff1a; ls: 列出目录 cd&#xff1a;切换目录 pwd&#xff1a;显示目前的目录 mkdir&#xff1a;创建一个新的目录 rmdir&#xff1a;删除一个空的目录 cp: 复制文件或目录 rm: 移除文件或目录 你可以使用 man [命令] 来查看各个…

LeetCode 1534. 统计好三元组

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 arr &#xff0c;以及 a、b 、c 三个整数。请你统计其中好三元组的数量。 如果三元组 (arr[i], arr[j], arr[k]) 满足下列全部条件&#xff0c;则认为它是一个 好三元组 。 0 < i < j < k < arr.length|arr[i] …

edge linux 下载软件,在Linux上安装edge浏览器

原标题&#xff1a;在Linux上安装edge浏览器时至今日&#xff0c;微软已经成为了世界上最大的开源代码贡献者&#xff0c;这可能出乎很多人的预料。随着微软放弃了经营多年的IE之后&#xff0c;edge成为了windows系统新的浏览器软件。前段时间听说改版后的edge提供了针对Linux的…

Linux系统用户账号的管理技巧

用户账号的管理工作主要涉及到用户账号的添加、修改和删除。 添加用户账号就是在系统中创建一个新账号&#xff0c;然后为新账号分配用户号、用户组、主目录和登录Shell等资源。刚添加的账号是被锁定的&#xff0c;无法使用。 1、添加新的用户账号使用useradd命令&#xff0c;其…

LeetCode 1535. 找出数组游戏的赢家

文章目录1. 题目2. 解题1. 题目 给你一个由 不同 整数组成的整数数组 arr 和一个整数 k 。 每回合游戏都在数组的前两个元素&#xff08;即 arr[0] 和 arr[1] &#xff09;之间进行。 比较 arr[0] 与 arr[1] 的大小&#xff0c;较大的整数将会取得这一回合的胜利并保留在位置…

在Linux中查看ftp状态,linux中ftp常见操作启动ftp状态,终止ftp会话

Ftp:查询ftp 状态&#xff1a;Service vsftpd status设置目录权限&#xff1a;chmod 777 -R /home/wwwroot/www.xx.com◆启动ftp会话open命令用于打开一个与远程主机的会话。该命令的一般格式是&#xff1a;◆open 主机名/IP如果在ftp 会话期间要与一个以上的站点连接&#xff…

python变量以及类型(含笔记)

1. 变量及类型 1.1 变量的定义 在程序中&#xff0c;有时我们需要对2个数据进行求和&#xff0c;那么该怎样做呢&#xff1f; 大家类比一下现实生活中&#xff0c;比如去超市买东西&#xff0c;往往咱们需要一个菜篮子&#xff0c;用来进行存储物品&#xff0c;等到所有的物…

POJ-1707 Sum of powers bernoulli方程

题目链接&#xff1a;http://poj.org/problem?id1707 利用bernoulli方程来解决此题。 数学上&#xff0c;伯努利数Bn的第一次发现是与下述数列和的公式有关&#xff1a; 其中n为固定的任意正整数。 这数列和的公式必定是变量为m&#xff0c;次数为n1的多项式&#xff0c;称为伯…

LeetCode 1536. 排布二进制网格的最少交换次数

文章目录1. 题目2. 解题1. 题目 给你一个 n x n 的二进制网格 grid&#xff0c;每一次操作中&#xff0c;你可以选择网格的 相邻两行 进行交换。 一个符合要求的网格需要满足主对角线以上的格子全部都是 0 。 请你返回使网格满足要求的最少操作次数&#xff0c;如果无法使网…

linux软件包管理 pdf,vSphere Storage Appliance 安装和管理 PDF

vSphere Storage Appliance 安装和管理VSA 群集利用多个 ESXi 主机的计算和存储资源&#xff0c;并提供一组可由数据中心中的所有主机访问的数据存储。运行 vSphere Storage Appliance 并加入 VSA 群集的 ESXi 主机是 VSA 群集成员。通过vSphere Storage Appliance &#xff0c…

python标识符、命名规则及关键字(含笔记)

目录 1、标识符和关键字 1.1 标识符概念 1.2 标识符规则 2、命名规则 3、关键字 1、标识符和关键字 1.1 标识符概念 开发人员在程序中自定义的一些符号和名称。标示符是自己定义的,如变量名,函数名等。 1.2 标识符规则 2、命名规则 见名知意。起一个有意义的名字&#…

【IT笔试面试题整理】不用加减乘除做加法

【试题描述】写一个函数&#xff0c;求两个整数的和&#xff0c;要求在函数体内不得使用加减乘除四则运算符合。 基本思路是这样的&#xff1a; int A, B;A&B //看哪几位有进位A^B //不带进位加 考虑二进制加法的过程&#xff0c; 步骤一、A^B&#xff0c;能够得到没有…

LeetCode 1537. 最大得分(切片取出局部最大值)

文章目录1. 题目2. 解题1. 题目 你有两个 有序 且数组内元素互不相同的数组 nums1 和 nums2 。 一条 合法路径 定义如下&#xff1a; 选择数组 nums1 或者 nums2 开始遍历&#xff08;从下标 0 处开始&#xff09;。从左到右遍历当前数组。如果你遇到了 nums1 和 nums2 中都…