20135302魏静静——课本5章学习笔记

第五章 系统调用

5.1 与内核通信

  • 中间层

     

    作用三个:1.为用户空间提供一种硬件的抽象接口;2.保证系统稳定和安全;3.除异常和陷入,是内核唯一的合法入口。

5.2 API、POSIX和C库

  • API定义了应用程序使用的编程接口(可实现系统调用)。
  • API、POSIX、C库与系统调用之间关系。

5.3 系统调用——syscall

5.3.1 系统调用号

  • 当用户空间的进程执行一个系统调用,就用系统调用号指明到底执行哪个系统调用。
  • sys_ni_syscall():错误号,负责“填补空缺”,返回-ENOSYS,专门针对无效的系统调用。
  • 存在sys_call_table。

5.3.2 系统调用的性能

  • 简洁高效

5.4 系统调用处理程序

  • 通知内核的机制是软中断实现的:通过引发一个异常来促使系统切换到内核态去指向异常处理程序,而此时的异常处理程序就是系统调用的处理程序。
  • x86系统上的软中断是由int $0x80指令触发128号软中断。

5.4.1 指定恰当的系统调用

  • eax寄存器传递系统调用号给内核。

5.4.2 参数传递

  • x86系统,ebx,ecx,edx,esi,edi按顺序存放前五个参数。
  • 需要6个及以上参数,应用一个单独的寄存器存放指向这些参数在用户空间地址的指针。
  • 返回值存放在eax。

5.5 系统调用的实现

1.实现系统调用

  • 决定它的用途
    不提倡采用多用途的系统调用
  • 确定参数、返回值、错误码
    力求简洁
  • 越通用越好,不做错误假设
  • 时刻注意可移植性和健壮性

    2.参数验证

    必须检查每个参数,保证他们不但合法有效,而且正确。
    最重要——检查用户提供的指针:

    • 指针指向的内存区域必须属于用户空间
    • 指针指向的内存区域在进程的地址空间内
    • 决不能绕过内存访问限制
      内核无论何时都不能轻率地接受来自用户空间的指针。

※1.检查读写
(1)向用户空间写入数据——copy_to_user()
参数:

进程空间中的目的内存地址
内核空间内的源地址
需要拷贝的数据长度

(2)从用户控件读取数据——copy_from_user()
把第二个参数指定的位置上的数据拷贝到第一个参数指定的位置上
第三个参数——拷贝数据长度。

以上两个函数成功返回0,失败返回没能完成拷贝的数据的字节数。
这两个函数都有可能引起阻塞——当包含用户数据的页被换出到硬盘上而不是物理内存上的时候。

※2.检查是否有合法权限
老版本:suser()
新版本:权能机制,capable(),返回非0有权操作,返回0则无权操作。

5.6 系统调用上下文

  • 内核在执行系统调用时处于进程上下文。
    在进程上下文中,内核可以:

    • 休眠
      说明系统调用可以使用内核提供的绝大部分功能
    • 可以被抢占
      要求保证该系统调用是可重入的

    1.绑定一个系统调用的最后步骤

    1,在系统调用表的最后加入一个表项。
    2,对于所支持的各种体系结构,系统调用号都必须定义于<asm/unistd.h>中
    3,系统调用必须被编译进内核映像,不能被编译成模块。——放进kernel/下的一个相关文件中即可,例如sys.c。

    2.从用户空间访问系统调用

    Linux本身提供了一组宏,用于直接对系统调用进行访问。

    _syscalln()     //n的范围从0到6,代表需要传递给系统调用的参数个数。

    例如:

    long open(const char *filename, int flags, int mode)
    =
    #define NR_open 5
    _syscall3(long, open,const char*, filename, int, flags, int, mode)
    应用程序可以直接用open()了。

    对于每个宏来说,都有(2+2xn)个参数:

    1.系统调用的返回值类型
    2.系统调用的名称
    以后按照系统调用参数的顺序排列每个参数的类型和名称。

    _NR_open在<asm/unistd.h>中定义。
    这个宏会被扩展成为内嵌汇编的C函数。

    3.为什么不通过系统调用的方式实现

    好处:

    - 系统调用创建容易并且使用方便
    - linux系统调用的高性能

    问题:

    - 占用系统调用号
    - 固化,不允许改动接口
    - 需要分别注册到每个需要支持的体系结构中
    - 脚本中不易调用,文件系统中也不能直接访问
    - 在主内核树外难以维护使用
    - ……

    替代:

    - 某些接口,例如信号量,用文件描述符表示
    - 把增加的信息作为一个文件放在sysfs的合适位置。
posted @ 2016-03-21 17:01  20135302魏静静  阅读(211)  评论(0编辑  收藏  举报