购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1 内核模块的文件格式

以内核模块形式存在的驱动程序,比如demodev.ko,其在文件的数据组织形式上是ELF (Executable and Linkable Format)格式,更具体地,内核模块是一种普通的可重定位目标文件。用file命令查看demodev.ko文件,可以得到类似如下的输出:

img

ELF是Linux下非常重要的一种文件格式,常见的可执行程序都是以ELF的形式存在。本书不会详细讨论ELF格式的技术细节,但是为了让读者能更好地理解后续的模块加载、导出符号和模块参数等相关主题,在这里我们结合Linux源代码中定义的ELF相关数据结构(基于32位体系架构),给出ELF格式的一个比较详细的结构图,如图1-1所示(这张图在后续的小节中会被多次引用):

img

图1-1 ELF文件视图格式

图1-1中忽略了驱动程序模块ELF文件中不会用到的Program header table。从图1-1可以看到,静态的ELF文件视图 总体上可分为三大部分:头部的ELF header,中间的Section和尾部的Section header table。

img ELF header部分

大小是52字节,位于文件头部。对于驱动模块文件而言,其中一些比较重要的数据成员如下:

img

表明文件类型,对于驱动模块,这个值是1,也就是说驱动模块是一个可定位的ELF文件(relocatable file)。

img

表明Section header table部分在文件中的偏移量。

img

表明Section header table部分中每一个entry 的大小(以字节计)。

img

表明Section header table中有多少个entry。因此,Section header table的大小便为e_shentsize×e_shnum个字节。

img

与Section header entry中的sh_name一起用来指明对应的section的name。

img Section部分

ELF文件的主体,位于文件视图中间部分的一个连续区域中。但是当模块被内核加载时,会根据各自属性被重新分配到新的内存区域(有些section也可能只是起辅助作用,因而在运行时并不占用实际的内存空间)。

img Section header table部分

该部分位于文件视图的末尾,由若干个(具体个数由ELF header中的e_shnum变量指定)Section header entry组成,每个entry具有同样的数据结构类型。对于设备驱动模块而言,一些比较重要的数据成员如下:

img

这个值用来表示该entry所对应的section在内存中的实际地址。在静态的文件视图中,这个值为0,当模块被内核加载时,加载器会用该section在内存中的实际地址来改写sh_addr(如果section不占用内存空间,该值为0)。

img

表明对应的section在文件视图中的偏移量。

img

表明对应的section在文件视图中的大小(以字节计)。类型为SHT_NOBITS的section例外,这种section在文件视图中不占有空间。

img

主要用于由固定数量entry组成的表所构成的section,如符号表,此种情况下用来表示表中entry的大小。

以上简单介绍了内核模块所属ELF文件的一些主要数据成员,显然设备驱动程序并不会使用到这些数据,它们是给内核模块加载器在加载模块时使用的,这里只是为了给后续的模块加载过程的讨论做一个简单的技术铺垫(如果读者对ELF文件的技术细节感兴趣,这里推荐一个非常实用的在Linux环境下读取ELF文件信息的工具——readelf)。接下来在进行模块加载这个沉重的话题讨论前,先来看一个有趣的东西:模块是如何向外界导出符号信息的。 DIZ3uP0A2j43yrmz0jPSxM8B+4/OCFyz7veuubRAK3XbZMf7Ko34PupfKt90c/A4

点击中间区域
呼出菜单
上一章
目录
下一章
×