zoukankan      html  css  js  c++  java
  • 扒开系统调用的三层皮

    张潇月《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

    通过库函数与系统调用沟通。

    用户态和内核态:高的执行级别下,代码可以执行特权指令,访问任意物理地址,这就是内核态。低级别的就是用户态。

    为什么要有权限分级?让操作系统更加稳定,防止程序员的用户态代码使系统崩溃。

    intel x86 CPU上有四种执行指令的级别0-3,Linux只使用两种,0是内核态,3是用户态

    如何区分用户态和内核态?在内核态时我们可以访问cs eip是任意的地址,然而用户态只能访问0x0000000-0xbfffffff的地址空间(地址空间是逻辑地址不是物理地址)

    中断处理是从用户态进入内核态的主要方式!系统调用只是一种特殊的中断。

    寄存器上下文切换:用户态切换到内核态时,必须要要把用户态的寄存器上下文保存起来,同时要把内核态寄存器上下文的值保存在对应地方。如:用户态栈顶地址、当时的状态字、当时的cs:eip的值以及内核态的栈顶地址、当时的状态字等。

    中断发生后第一件事就是保存现场 save_all,中断结束前的最后一件事就是恢复现场 restore_all,最后iret指令与中断信号发生时的CPU的做的动作只好相反。

    中断处理过程

    interrupt (ex:int 0x80)-save cs:eip/ss:eip/eflages(current)to kernel stack,then load cs:eip(entry of a specific ISR)and ss:esp(point to kernel stack)
    int 0x80表示系统调用
    保存了当前的堆栈,栈顶,标志寄存器保存到内核堆栈
    同时加载了当前的系统调用相关联的中断服务历程的入口
    同时把当前的堆栈段和esp也加载到CPU里
    save_all
    -…//内核代码,完成中断服务,发生进程调度
    restore_all
    iret-pop cs:eip/ss:esp/eflags from kernel stack

    系统调用的意义:操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用

    把用户从底层的硬件编程中解放出来

    极大地提高了系统的安全性

    使用户程序具有可移植性

    API和系统调用(应用程序编程接口):API知识一个函数定义,系统调用通过软中断向内核发出一个明确的请求。

    一般每个系统调用对应一个封装例程;不是每一个系统调用对应一个API,大部分封装都返回一个整数。

    系统调用的三层皮:API、对应的中断向量、服务程序

    内核实现了很多不同的系统调用,进程必须指明要哪一种系统调用,因此有了系统调用号这个参数。用eax寄存器传递参数。

    寄存器传递参数具有如下限制:每个参数的长度不能超过寄存器的长度,即32位;在系统调用号之外,参数的个数不能超过六个。

     

    实验:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用。

    首先是c代码

    其次是嵌入式代码

    两种方式的比较

    得到答案都是1000

  • 相关阅读:
    CSS压缩工具(自动合并重复的定义)
    windows创建服务
    ashx是什么文件,如何创建(转载)
    在mojoportal中建立自定义模块
    Mojoportal2339之汇总页面
    在vs2008中设置jquery智能提示 (转载)
    关于mojoportal在局域网或单机使用时注意事项
    html编辑器kindeditor我的使用方法 (转载)
    visual studio 2008 没有设计视图的解决方法(转载)
    模块开发捷径配置参数
  • 原文地址:https://www.cnblogs.com/20135131zxy/p/5297795.html
Copyright © 2011-2022 走看看