Linux内核-系统调用

Linux内核-系统调用


1.与内核通信

#系统调用在用户空间进程和硬件设备之间添加了一个中间层

    作用:1.为用户空间提供了一种硬件的抽象接口

              2.系统调用保证了系统的稳定和安全

              3.出于每一个进程都执行在虚拟系统中的考虑

#系统调用是用户空间訪问内核的唯一手段


2.API、POSIX和C库

#应用程序通过API而不是直接系统调用来编程

#一个API定义了一组应用程序使用的编程接口


3.系统调用

#内核必需提供系统调用所希望完毕的功能。但它全然能够依照自己的方式去实现,仅仅要最后结果正确

#全部的系统调用都要asmlinkage限定词

#为保证32/64位兼容,系统调用在用户空间返回值时int,内核空间为long

    1.系统调用号:

        #在Linux中每一个系统调用被赋予一个系统调用号

        #系统调用号一旦分配不可改变,否则编译好的应用会崩溃

        #Linux上有一个“未实现”的系统调用sys_ni_syscall()。它除了返回-ENOSYS外不做其它不论什么工作

          假设一个系统调用被删除,或变的不可用,这个函数去填补空缺

    2.系统调用的性能

        #Linux系统调用比其它操作系统要快,原因:

            1.Linux非常短的上下文切换时间

            2.系统调用处理程序和每一个系统调用很简洁


4.系统调用处理程序

#通知内核的机制靠软中断实现,通过引发异常来促使系统切换到内核态去运行异常处理程序(系统调用处理程序)

#指定恰当的系统调用:

        在x86上通过eax寄存器将系统调用号传递给内核

        system_call()函数通过将给定的系统调用号与NR_syscalls()作比較来检查其有效性

#參数传递:在x86-32系统上,ebx,ecx,edx,esi,edi依照顺序存放前五个參数

                  给用户空间的返回值通过eax寄存器传递(x86)


5.系统调用的实现

#实现系统调用:

    每一个系统调用都有一个明白的用途

    系统调用的接口力求简洁。參数尽可能少

    设计接口的时候要尽量为将来多做考虑

#參数验证:

    #系统调用必须验证他们全部的參数是否合法有效。最重要的检查时检查用户提供的指针是否有效

    #在接受一个用户空间的指针之前,内核必须保证:

        1.指针指向的内存区域属于用户空间,进程决不能让内核去读取内核空间的数据

        2.指针指向的内存区域在进程的地址空间。进程决不能让内核去读取其它进程的数据

        3.假设是读,内存标记为可读。假设是写,标记为可写;假设标记为可运行。进程决不能绕过内存訪问限制

        

6.系统调用上下文

#绑定一个系统调用的最后步骤:

    1.首先,在系统调用表的最后增加一个表项

    2.系统调用号定义于<asm/unistd.h>中

    3.系统调用必须被编译进内核映像(不能编译为模块)

#建立新的系统调用的利与弊:

    利:#系统调用创建easy且使用方便

          #Linux系统调用高性能

    弊:#须要一个系统调用号,由官方分配

          #系统调用增加稳定内核后被固化,它的接口不同意修改

          #须要将系统调用分别注冊到每一个须要支持的结构体系去

          #在脚本中不easy调用。也不能从文件系统直接訪问系统调用

          #在主内核树之外非常难维护和调用系统调用

          


posted @ 2016-01-26 20:34  lcchuguo  阅读(278)  评论(0编辑  收藏  举报