• linux内核基础(系统调用,简明)


    内核基础(系统调用)

    在说系统调用之前。先来说说内核是怎么和我们交互的。或者说是怎么和我们产生交集的。

    首先,内核是用来控制硬件的仅仅有内核才干直接控制硬件,所以说内核非常重要,假设内核被控制那么电脑的一切都被控制了,所以我们须要把内核保护起来。所以SHELL 就诞生了,我们绝大多数情况下是在和SHELL 交互,应用程序也执行与SHELL之上。当执行一些进程时。进程会切换进程上下文。这时进程从用户态切换到内核态,也就是常说的内核代表进程执行。可是就算如此内核依旧是被保护起来的。我们始终不能和内核直接进行数据的交换,我们差点儿不可能从内核中读取数据。可是内核依旧能明确我们写的函数须要执行的进程,由于我们的函数是调用的C库。而C库中的函数均是系统调用(能够理解位内核的一些功能函数)的封装表现。所以说内核能够理解而且能执行上层的应用程序。

    系统调用号:

    在Linux中每一系统调用都有一个系统调用号,进程是不会提及系统调用名称的。假设一个系统调用被删除,它所占的系统调用号不会被回收,由于假设回收,那么其它曾经调用这个函数的程序就会调用成别的函数,事实上是错误的,它还非常高兴的运行呢。当中一个系统调用sys_ni_syscall( )就是用来填充被删除系统调用的空白的。这个函数仅仅返回-ENOSYS这个值,然后什么都不干。内核记录了系统调用表中的全部已经注冊过的系统调用列表。存储在sys_call_table中,每一种体系结构都明白定义了这个表,里面指定了唯一的系统调用号。


    系统调用的性能:

    Linux系统调用比其它非常多的操作系统运行的要快。Linux非常短的上下文切换时间非常短是一个重要的原因,进出内核都被优化的非常便捷高效,还有一个重要的原因就是每个系统调用本身就已经非常高效便捷了。

    系统调用处理程序:

    就像前边说的那样用户空间是不能运行内核代码的,所以系统调用函数不能直接放在用户空间中运行,所以必需要靠软中断来实现。通过一个异常来促使系统切换到内核态去处理异常处理程序,此时异常处理程序就是系统调用程序。X86有一个叫做sysenter 的指令,这条指令被用来使陷入内核运行系统调用的方式。

    系统调用的使用

    由于全部的系统调用陷入内核的方式都一样,所以不过陷入内核空间是不够的因此必须把系统调用号一并传给内核。X86系统是将系统调用号放入eax寄存器中的。通样系统调用的參数也是先放在寄存器中一并传入的,(那几个寄存器不同系统是不同的)。

    參数验证:

    不论是系统调用还是其它的一般的程序,參数验证一直都是一个重要的话题,參数验证能够将发生错误在产生损失之前。

    尤其是系统调用,假设在内核中发生參数的错误,可能会造成极端的不良影响,所以必须进行严格的參数验证。一般有例如以下几条:

    1.传递的指针指向的区域属于用户空间,进程绝不能哄骗内核去读取内核空间的数据(内核是非常单纯的)

    2.指针指向的内存区域必须在进程的地址空间里,不能哄骗内核去读取其它进程的数据

    3.读或者写或者是读写的权限内存必须分明。进程决不能绕过内存的訪问限制

    内核提供了两种方法来完毕必须的检查和内核空间和用户空间的数据的来回拷贝,copy_to_user()  copy_from_user()

    都须要三个參数。第一个是目的内存地址。第二个是源内存地址。第三个位须要操作的字节数。都是原子操作。


  • 相关阅读:
    169. Majority Element
    283. Move Zeroes
    1331. Rank Transform of an Array
    566. Reshape the Matrix
    985. Sum of Even Numbers After Queries
    1185. Day of the Week
    867. Transpose Matrix
    1217. Play with Chips
    766. Toeplitz Matrix
    1413. Minimum Value to Get Positive Step by Step Sum
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5174995.html
Copyright © 2020-2023  润新知