计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,为了更好的管理这些资源进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用。
        系统调用是属于操作系统内核的一部分的,必须以某种方式提供给进程让它们去调用。CPU有着不同的运行级别,在这里操作系统也有着运行级别:用户态和内核态。
        通俗的来讲进程处于内核态时就是“boss”,这时他可以随心所欲的使用和“霸占”各种资源。
        相对来讲用户态就是“下属”,处于该级别的进程的操作限制多优先级明显低。

        Linux下常见系统调用

         fork       open        read        write        close等


       

        标准I/O库

        fopen     fread       fwrite       fclose       ffflush等


标准IO库中预定义了三个流

stdin 标准输入

stdout 标准输出

stderr 标准错误

它们引用的文件和STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO指向的文件相同

       标准IO库通过调用read/write系统调用来实现真正的IO。


Linux下系统调用的实现

        Linux下的系统调用是通过0x80实现的,但是我们知道操作系统会有多个系统调用(Linux下有319个系统调用),而对于同一个中断号是如何处理多个不同的系统调用的?最简单的方式是对于不同的系统调用采用不同的中断号,但是中断号明显是一种稀缺资源,Linux显然不会这么做;还有一个问题就是系统调用是需要提供参数,并且具有返回值的,这些参数又是怎么传递的?也就是说,对于系统调用我们要搞清楚两点:

        1. 系统调用的函数名称转换。

        2. 系统调用的参数传递。

        首先看第一个问题。实际上,Linux中处理系统调用的方式与中断类似。每个系统调用都有相应的系统调用号作为唯一的标识,内核维护一张系统调用表,表中的元素是系统调用函数的起始地址,而系统调用号就是系统调用在调用表的偏移量。在进行系统调用是只要指定对应的系统调用号,就可以明确的要调用哪个系统调用,这就完成了系统调用的函数名称的转换。

1 了解linux下的系统调用



    2  了解linux下的系统调用
       
       

              假如Linux中open的调用号是5


               Linux中是通过寄存器%eax传递系统调用号,所以具体调用open的过程是:将5存入%eax中,然后进行系统调用sys_open

               完成操作。

               

              对于参数传递,Linux是通过寄存器完成的。

              Linux最多允许向系统调用传递6个参数,分别依次由%ebx,%ecx,%edx,%esi,%edi和%ebp这个6个寄存器完成。

               

               如上图2所示,Linux中,在用户态和内核态运行的进程使用的栈(空间)是不同的,分别叫做用户空间和内核空间,两者各自负责相应特权级别状态下 的函数调用。当进行系统调用时,进程不仅要从用户态切换到内核态,同时也要完成空间切换,这样处于内核态的系统调用才能在内核空间上完成调用。系统调用返回时,还要切换回用户空间,继续完成用户态下的函数调用。


           系统调用很耗时耗资源原因在于俩点:

          

          第一,系统调用通过中断实现,需要完成栈切换

          第二,使用寄存器传参,这需要额外的保存和恢复的过程。

          

               

      

相关文章:

  • 2021-07-29
  • 2021-12-21
  • 2021-12-13
  • 2021-06-28
  • 2021-09-21
  • 2022-12-23
  • 2021-07-30
猜你喜欢
  • 2022-12-23
  • 2021-04-07
  • 2021-08-26
  • 2022-01-17
  • 2021-08-04
  • 2021-10-31
  • 2022-01-23
相关资源
相似解决方案