内核符号表和系统调用

来源:互联网 发布:冷藏车配货软件 编辑:程序博客网 时间:2024/05/17 03:55

转自:http://bbs.ednchina.com/BLOG_ARTICLE_62710.HTM

驱动程序开发过程中涉及kernel symbol table syscall两个概念,不知道大家是如何理解的,在此把我对二者理解罗列如下,给大家参考:


    内核符号表linux内核提供给内核代码的一部分引用,所指的“内核代码”包括内核以及驱动程序等运行在内核内存空间的程序,“引用”包括对变量的引用,对函数的引用等。最常见的内核符号引用如printk打印输出。通常内核符号是由一部分内核代码提供给其他内核代码访问其内部数据的接口。在驱动程序中,如果该驱动程序中有被其他内核代码调用的部分,可以用EXPORT_SYMBOL导出到内核符号表中。


    在多层驱动模型如USBSCSI、文件系统中一般底层的驱动程序要导出其功能调用到内核符号表中,给上层驱动调用。


    系统调用是由基本内核提供的功能调用接口,所指的基本内核是不包括驱动程序,不能被随意精简的核代码。系统调用的接口不仅运行于内核空间的代码可以调用,用户空间的程序同样可以使用系统调用。系统调用的最初目的就是提供给用户程序访问操作系统的接口。最常见的系统调用如open,close,read,write等。


    用户应用程序使用open(“/dev/null”)打开设备时,到底该系统调用完成了什么功能?简单的说,应用程序通知操作系统,需要打开/dev/null设备,成功后操作系统会返回设备句柄。至于操作系统为了完成打开设备操作具体干了写什么,可以参考内核代码中sys_open的实现。


    内核符号表中的东西只能被内核空间程序访问,系统调用无此限制。系统调用是最基本内核提供的代码不能随意添加或减少,而内核符号可以根据需要自行导出。


    还有一点值得注意的是,当在内核代码中如驱动程序,发生了系统调用,系统调用的代码是在该进程的用户空间运行。这样说还是有点模糊,举个例子就清楚了。


进程test,虚拟设备/dev/readfile驱动程序模块readfile.o,文件name.txt这三个对象。


Test.c中:


   Open(“/devreadfile”。。。) /*系统调用open,打开设备/dev/readfile*/


readfile.c的驱动程序中:


   open(“name.txt”。。。)   /*系统调用open,打开文件name.txt */


把前一个open命名位OPEN1,后一个为OPEN2OPEN1系统调用运行于test进程的内存区,readfile.o的模块代码运行于内核空间,当发生系统调用OPEN2时,OPEN2其实也是运行于进程test的内存区。Test内存区是用户空间,这点十分重要。不推荐在驱动代码中使用系统调用,以防止死锁。


 


系统调用不到300个,在/arch/i386/kernel/entry.S文件中定义,去掉前面的sys_