操作系统调用的实现

一个用户程序直接加载到内存中,内核也是在内存中,为什么在调用内核的时候,不能直接就在内存中直接调用访问呢?
如果可以的话,操作系统中很多重要的东西,都能直接被访问调用了,比如root的密码,那么机器一点都不安全了。
在这里插入图片描述

系统调用就是通过调用进入内核的一种手段。
同样内存中,为什么可以让应用程序访问不到操作系统,是因为处理器的硬件设计,在硬件上,把内存分割成用户态和内核态,内核态可以访问任何数据,用户态不能访问内核的数据。想要使用内核数据,只能通过操作系统提供的调用,进行用户态和内核态的切换。
计算机对内存的使用,都是一段一段的使用,所有的段,都是段寄存器切换使用。每次访问的时候,都会查看下自己的权限,自己的权限从GDT表中查看,就是操作系统中刚刚启动的位置,指令mov的位置,如果你是内核权限为3的用户态,访问硬件为0的内存段,那么是不可访问的。而查看当前的内核权限,是操作系统,权限为0,即可以访问内存中的所有位置。CPL是用户态,DPL是内核权限。
在这里插入图片描述

硬件也提供了主动进入内核的方法,通过中断才能进入。
系统调用就是一段包含int指令的代码,由c语言库函数处理。操作系统中也写入了中断的处理,根据中断获取程序的编号,然后执行相应的代码。
比如一个open read 或者write函数,底层使用了int中断,read对应中操作系统中断的某一处,直接读取了相应的操作,然后切入到内核态,进行相应的操作。中断就是int0X80。
在这里插入图片描述

我们在应用程序中调用一个printf,首先会在c函数库中调用printf的函数,然后会调用库函数的write函数,此时是在用户态,printf 是要在显示器上打印东西,权限不够,需要切换到内核态,write函数会调用int中断,对应操作系统itd中记录的向量表(idt表和gdt表十分的相似),切换到内核态,然后系统调用write函数。
对于open还是write等区分,通过eax进行区分,即通过文件描述符fd区分。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

int0X80的处理
先经常idt表中的记录,进行跳转, 通过内嵌汇编,将DPL设置成为3,此时CPL也是3,就能进来了,进来之后,根据这个表,通过段选择符,此时为8,jum8的时候,CS=CS+IP,CPL变为0,才是真正的进入内核态。在此时,中断处理程序执行system_call。在system_call中,中断处理,查询sys_call_table,通过移动查表,调用了当前要执行的程序,此时内核中才真正的实现这程序的功能。这时候,应用程序就可以访问内核的内存区域。
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值