linux进程切换

  1. 内核堆栈:每个进程在内核模式下运行时都有自己的内核堆栈。这个堆栈保存了进程在内核模式下的运行状态,包括函数调用时传递的参数、局部变量和返回地址等。

  2. 用户态与内核态:进程通常在用户态下运行,当执行系统调用或响应中断时进入内核态。在内核态,进程对硬件资源有更高级别的控制。

  3. 返回地址:当系统调用或中断发生时,CPU从用户态切换到内核态并保存返回用户态的地址。当内核完成处理后,通过这个地址返回用户态继续执行原进程。

进程切换的实质操作发生在内核堆栈上。当操作系统决定将CPU从当前进程切换到另一个进程时,它会保存当前进程的内核堆栈信息(即执行“保存上下文”),然后加载新的进程的内核堆栈信息(即执行“恢复上下文”)到CPU。

关键步骤是修改内核堆栈上的返回地址

  • 对于当前正在运行的进程,其在内核堆栈上的信息会被保存,包括即将返回到用户态执行的地址。
  • 当要切换到新的进程时,操作系统会更改内核堆栈上的数据为新进程的堆栈信息,并设置新的返回地址为新进程的用户态地址。

当操作系统做好这些更改后,它将“返回”到新进程的用户态,从新进程保存的那个点继续执行。从用户的角度看,CPU似乎从一个进程“跳”到了另一个。实际上,这个“跳”是通过保存和恢复不同进程的上下文、修改内核堆栈上的数据完成的。这样,一个进程切换到另一个进程的过程就完成了,CPU现在执行新的进程代码。

内核态:

在内核态可以理解为不分进程,进入内核态就不分了。只在内核态返回到用户进程才有意义。

  1. 进程上下文: 在用户态,操作系统为每个运行的程序提供了一个独立的进程上下文,包括虚拟内存空间、文件句柄、安全权限等。每个进程都拥有自己独立的用户态环境,操作系统通过进程间切换(Context Switch)来管理多任务。

  2. 内核态简化: 在内核态,虽然当前可能是响应某个进程的系统调用进入的,但是由于所有进程共享相同的内核空间和内核资源,所以在一些操作中不需要考虑是哪个用户进程在请求服务。

  3. 共享内核资源: 内核态代码直接运行在处理器的最高权限级别,访问的是全局的、不属于特定进程的资源。比如内核的调度器、内存管理单元、I/O处理系统等,都是服务于所有进程的共享资源。

  4. 安全隔离与共享: 即使在内核态有时也需要知道当前操作是由哪个进程触发的(例如管理进程的内核栈、确保访问权限等),但许多低级别的内核操作本身是与发起请求的特定进程无关的,比如硬件中断处理、定时器调度、底层网络数据包处理等。

linux内核如何加载多种不同的可执行文件?

  1. shell 环境下调用execve同时载入命令行参数和环境变量
  2. 库函数触发系统调用陷入内核态
  3. system call 调用sys_execuve -> do_execve -> do_execve_common -> exec_binprm-> load_elf_binary

在系统初始化阶段调用了core_initcall(init_elf_binfmt); 

init_elf_binfmt 中将 elf_format全局变量注册在内核的fmt链表中,所以在 exec_binprm 中会在fmt链表中找到对应模块来解析ELF文件的头部信息。

调用 elf_format变量中的 load_elf_binary 方法,load_elf_binary 中最后调用start_thread 设置新的ip值,等该进程返回用户态时,就转而执行新的代码。

两种加载的方法:

静态库:直接执行可执行程序的入口

动态库:由ld来动态链接这个程序,再把控制权移交给可执行程序的入口

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值