系统调用态的切换过程

kernel 是什么?

  1. 当计算机接上电源的那一刻,会启动一个 kernel 程序,加载到内存当中,这是整套系统第一个加载到内存当中的程序,也就是说 kernel接管了硬件的调用,kernel 它将最底层封装后,内核会向外暴露一些调用,又叫系统调用(system call)。
    当其他程序要调用资源的时候,是直接面向于kernel的。例如访问硬盘。
  2. kernel还起到一个非常关键的安全性保证,不让其他程序乱动硬件和访问其他程序的内存,因此kernelcpu存在着两种交互模式。
    kernel加载到内存前与cpu的交互是实模式,加载完毕以后,转换为保护模式
    实模式下kernel访问cpu请求,获取到的都是真实的物理地址。
    保护模式kernel本身的内存地址虚拟化隔离开,还可以将其他程序分配到一个虚拟地址。
  3. kernel中有个调度程序,会将其他的活动进程扔到一个队列里面。内核里面还有一个中断向量表,是一个hashmapkey为中断号,值为回调函数。
    在程序没启动前,程序只是一个文件,当程序启动时,内核会读取文件将其读取到内存当中。

时分系统与中断

单核cpu利用时间片来保证每个程序同时运行。也叫时分系统。

时间片如何产生的?

晶振(硬件):直流电输入,输入过程是没有间歇的,它的输出是按照一定频率分段的(交流电的输入是有间隔的)。它的输出会连接到cpu上,因为有间隔的输出,每当cpu收到一个电流信号,则会发生一个中断行为。
当中断行为产生,cpu会把当前执行的程序在cpu上的寄存器中缓存的数据写回到内存(先找到中断向量表,再通过kernel),保留上下文现场。再把另外一个(Kernel的队列按顺序取出看优先级)需要加载的程序的内存再放回到寄存器中。之后,再执行用户的程序代码,开始进入了用户态。如此循环。

晶振

键盘会产生中断告诉cpu该执行此程序了,因为外设设备可以自己产生间断的电压告诉cpu发生中断。

当执行到 system.out.println("hello world")

在这个过程中,我们首先会进入到系统调用入口程序,然后会往cpu寄存器(eax)送写了一个write函数,参数('hello world')也会放到一个寄存器(ebx),紧接着当cpu看到write后,就会开始找内核kernel,因为它不知道write函数是在内核的哪个地址上,然后cpu会埋下一个cpu的指令 int 0x80,int是指令不是变量类型,为中断的前三个字母的首字母interrupt,当读到int指令后,就会读到0x80,0x80是16进制的128,128存在中断向量表当中,找到对应的回调函数,即切换程序指令,这个回调函数的大致内容是不要执行当前程序了,开始保护当前程序的上下文现场,放入到寄存器,然后进入阻塞状态,到内核,把刚才寄存器里放的write在kernel重新注册的地址,找到这个函数运行执行,这个时候就是由用户态的程序跑到内核态。
结论,cpu最终会从内核中读取指令。程序给cpu指令,产生中断,cpu再通过内核执行函数。这个叫做系统调用态的切换过程。

函数调用:不需要产生中断,同一个程序发生两个指令,不需要切换时间片,就在同一个进程所有的内存中
系统调用成本比较高,需要产生中断。io牵扯到硬件,必然会发生中断,会有内核态切换的过程。
内核要保护进程内存,多个程序需要以中断的方式使用内核。

中断,陷阱,异常的该方面知识的扩展

https://www.cnblogs.com/broglie/p/5463359.html
https://blog.csdn.net/yikaozhudapao/article/details/89279304
https://www.cnblogs.com/yudao/p/4386775.html?utm_source=tuicool&utm_medium=referral

你可能感兴趣的:(系统调用态的切换过程)