用户态和内核态是如何切换的?
所有的用户进程都是运行在用户态的,但是我们上面也说了,用户程序的访问能力有限,一些比较重要的比如从硬盘读取数据,从键盘获取数据的操作则是内核态才能做的事情,而这些数据却又对用户程序来说非常重要。所以就涉及到两种模式下的转换,即用户态 -> 内核态 -> 用户态,而唯一能够做这些操作的只有 系统调用
,而能够执行系统调用的就只有 操作系统
。
一般用户态 -> 内核态的转换我们都称之为 trap 进内核,也被称之为 陷阱指令(trap instruction)
。
他们的工作流程如下:
- 首先用户程序会调用
glibc
库,glibc 是一个标准库,同时也是一套核心库,库中定义了很多关键 API。 - glibc 库知道针对不同体系结构调用
系统调用
的正确方法,它会根据体系结构应用程序的二进制接口设置用户进程传递的参数,来准备系统调用。 - 然后,glibc 库调用
软件中断指令(SWI)
,这个指令通过更新CPSR
寄存器将模式改为超级用户模式,然后跳转到地址0x08
处。 - 到目前为止,整个过程仍处于用户态下,在执行 SWI 指令后,允许进程执行内核代码,MMU 现在允许内核虚拟内存访问
- 从地址 0x08 开始,进程执行加载并跳转到中断处理程序,这个程序就是 ARM 中的
vector_swi()
。 - 在 vector_swi() 处,从 SWI 指令中提取系统调用号 SCNO,然后使用 SCNO 作为系统调用表
sys_call_table
的索引,调转到系统调用函数。 - 执行系统调用完成后,将还原用户模式寄存器,然后再以用户模式执行。
评论(6)
https://blog.csdn.net/m0_56130834/article/details/124524698参考
处理器从用户态切换到内核态的方法有三种:系统调用、异常和外部中断。
系统调用,是操作系统的最小功能单位,是操作系统提供的用户接口,系统调用本身是一种软中断。
异常,也叫做内中断,是由错误引起的,如文件损坏、缺页故障等。
外部中断,是通过两根信号线来通知处理器外设的状态变化,是硬中断。
这个异常和外部中断是不是本质上也是系统调用
图片是不是失效啦
已经处理了,gitee挂了,,gitee也是牛逼,啥也不说,直接就加上防盗链了
地总牛皮~