Linux设备驱动之第 2 章 内核符号表

2.5. 内核符号表

        insmod使用公共内核符号表来解析模块中未定义的符号。公共内核符号表包含所有的全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必需的。当模块被装入内核后,这个模块导出的任何符号都会变成内核符号表的一部分。通常情况下,模块只需实现自己的功能,而无需导出任何符号。但是,如果其它模块需要从某个模块中获得好处时,也可以导出符号。

        新模块可以使用由自己的模块导出的符号,这样,可以在其它模块上层叠新的模块。模块层叠技术也使用在很多主流的内核源代码中。例如,msdos文件系统依赖于由fat模块导出的符号。模块层叠技术在复杂的项目中非常有用。如果以设备驱动程序的形式实现一个新的软件抽象,则可以为硬件相关的实现提供一个插头。例如,video-for-linux 驱动程序组划分了一个通用模块,它导出的符号可供下层与具体硬件相关的驱动程序使用。根据所安装的硬件的不同,加载通用的video模块以及与具体硬件相关的特定模块。另外,并口支持以及大量可插拔设备的处理(比如USB内核子系统)都使用类似的层叠方法。图2-2给出并口子系统中的层叠方式,箭头显示模块之间和内核编程接口之间的通信情况。


图2-2并口驱动程序模块的层叠

        modprobe是处理层叠模块的一个实用命令。modprobe的功能在很大程度上和insmod类似,但是modprobe除装入指定模块外还同时装入指定模块所依赖的其它模块。因此,一个modprobe命令有时相当于调用几次insmod命令。通过层叠技术,可以将模块划分为多个层,通过简化每个层可缩短开发时间。

        Linux内核头文件提供了一个方法来管理符号(函数、变量)对模块外部的可见性,从而减少可能造成的名字空间的污染,并且适当隐藏信息。如果一个模块需要向其他模块导出符号,应该使用宏。

EXPORT_SYMBOL(name);

EXPORT_SYMBOL_GPL(name);

分析:这两个宏用于将给定的符号(函数、变量)导出到模块外部。EXPORT_SYMBOL_GPL使得要导出的模块只能被GPL许可证下的模块使用。符号必须在模块文件的全局部分导出,这是因为这两个宏将被扩展为一个特殊变量的声明,而该变量必须是全局的。该变量将在模块可执行文件的特殊部分(ELF段)中保存,在装载时,内核通过这个段来寻找模块导出的变量。

猜你喜欢

转载自blog.csdn.net/xiezhi123456/article/details/80917224