zoukankan      html  css  js  c++  java
  • Linux内核读书笔记第二周

    1. 什么是系统调用
      简单来说,系统调用就是用户程序和硬件设备之间的桥梁。用户程序在需要的时候,通过系统调用来使用硬件设备。
      系统调用的存在,有以下重要的意义:
      1)用户程序通过系统调用来使用硬件,而不用关心具体的硬件设备,这样大大简化了用户程序的开发。
          比如:用户程序通过write()系统调用就可以将数据写入文件,而不必关心文件是在磁盘上还是软盘上,或者其他存储上。
      2)系统调用使得用户程序有更好的可移植性。
          只要操作系统提供的系统调用接口相同,用户程序就可在不用修改的情况下,从一个系统迁移到另一个操作系统。
      3)系统调用使得内核能更好的管理用户程序,增强了系统的稳定性。
          因为系统调用是内核实现的,内核通过系统调用来控制开放什么功能及什么权限给用户程序。
          这样可以避免用户程序不正确的使用硬件设备,从而破坏了其他程序。
      4)系统调用有效的分离了用户程序和内核的开发。
          用户程序只需关心系统调用API,通过这些API来开发自己的应用,不用关心API的具体实现。
          内核则只要关心系统调用API的实现,而不必管它们是被如何调用的。
      2.为了和用户空间上运行的进程进行交互,内核提供了一组借口。透过该接口,应用程序可以访问硬件设备和其他操作系统资源。这组接口在应用程序和内核之间扮演着使者的角色。同时,这组接口也保证了系统稳定可靠,避免应用程序肆意妄行,惹出麻烦。Linux系统的系统调用作为C库的一部分提供,其调用过程中的实例如下图所示:

    3.Linux上的系统调用实现原理
    要想实现系统调用,主要实现以下几个方面:
    1)通知内核调用一个哪个系统调用
    每个系统调用都有一个系统调用号,系统调用发生时,内核就是根据传入的系统调用号来知道是哪个系统调用的。
    在x86架构中,用户空间将系统调用号是放在eax中的,系统调用处理程序通过eax取得系统调用号。
    eax寄存器:将系统调用号传递给内核system_call():与NR_syscall比较,检查有效性
    call *sys_call_table(,%rax,8):执行相应的系统调用
    2)用户程序把系统调用的参数传递给内核
    系统调用的参数也是通过寄存器传给内核的,在x86系统上,系统调用的前5个参数放在ebx,ecx,edx,esi和edi中,如果参数多的话,还需要用个单独的寄存器存放指向所有参数在用户空间地址的指针。
    一般的系统调用都是通过C库(最常用的是glibc库)来访问的,Linux内核提供一个从用户程序直接访问系统调用的方法。
    3)用户程序获取内核返回的系统调用返回值
    获取系统调用的返回值也是通过寄存器,在x86系统上,返回值放在eax中。
    4.系统调用上下文
         内核在执行系统调用的时候处于进程上下文。current指针指向当前任务,即引发系统调用的那个进程。在进程上下文中,内核可以休眠并且可以被抢占。这表明即使是在内核空间中,当前进程也可以被其他进程抢占。因为新的进程可以执行相同的系统调用,所以必须保证系统调用是可重入的。当系统调用返回时,控制权仍然在system_call()中,它最终会负责切换到用户空间并让用户继续执行下去。

    总结:这周通过网易云课堂和自己读书学习,对系统调用有了比较系统的认识,自己对系统调用过程大致认识如下:应用程序在用户态调用API函数,该函数将对应的系统调用号及参数保存,触发软中断,然后陷入内核态,system_call根据系统调用号调用对应的内核函数,内核函数执行完毕后将结果存放的eax中并返回给程序,程序返回的用户态。经过最近几周的学习对Linux系统也逐渐理解,对这种学习方式也有很大的兴趣,希望今后能更好的学习。

  • 相关阅读:
    Google's Innovation Factory (and how testing adapts)
    虎年拜年帖
    [ZZ]让测试也敏捷起来
    Selenimu做爬虫续
    OKR的解说
    春秋航空的机上店铺
    免费TK域名试用
    快速排序_C语言实现
    第一篇博客
    C、C++代码格式优化软件献给编程爱好者
  • 原文地址:https://www.cnblogs.com/20135316wjq/p/5311649.html
Copyright © 2011-2022 走看看