Linux内核模块(* .ko)内核之间的兼容性

时间:2013-08-07 14:54:41

标签: kernel-module

我有一个简单的内核对象,我为内核内存进行探测而构建。

如果我在我的64位Ubuntu(3.2)机器上构建它,它在该机器上工作正常。但它不会在我的64位Ubuntu(3.9)机器上进行insmod。反之亦然。如果我尝试在内核上运行它而不是我构建它的那个,它会给我一个“-1无效的模块格式”错误。

我认为insmod将动态链接到导出的符号表,导出的符号表在内核修订版之间不会发生变化。 (它会附加。)

有人能告诉我如何构建与未来(或过去)Linux内核兼容的内核模块(.ko),而不必在该内核上重建吗?

这是我的make文件:

ccflags-y = -g

obj-m + = access_mem.o

所有:     make -C / lib / modules / $(shell uname -r)/ build M = $(PWD)modules

清洁:     make -C / lib / modules / $(shell uname -r)/ build M = $(PWD)clean

2 个答案:

答案 0 :(得分:5)

Joe,Ubuntu(3.2)可能使用内核版本x.y.z但Ubuntu(3.9)可能使用内核版本x.y.z1。如果内核版本不同,则必须针对该特定内核版本构建/编译驱动程序。如果内核版本相同,则无需构建驱动程序。重要的一点是,每个驱动程序模块都已经编译或构建,与version.ko模块链接(实际上嵌入了驱动程序模块构建的内核版本的信息),而加载内核模块则检查此信息和内核版本,如果不同然后抛出“ - 1无效的模块格式”或者如果匹配则成功加载内核模块。要开发未来或向后兼容的内核模块,您需要知道哪个内核版本的API或函数签名已更改为ex: ioctl签名从内核版本2.3.36开始更改,因此您的代码应该如下

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
static long minor_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
#else
static int minor_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,  
                                                               unsigned long arg)
#endif 

如果以这种方式开发,那么您的内核模块将来或向后兼容。 兼容性仅适用于API或函数签名等。通过在内核模块中保留较旧的API或函数签名等来更改内核版本,如上例所示,但仍需要构建/编译针对您尝试加载的内核版本的内核模块。

答案 1 :(得分:1)

我不是这方面的专家,但我很确定你必须针对每个内核版本构建驱动程序。至于内核版本之间保持相同的符号,我很确定在阅读https://www.kernel.org/doc/Documentation/stable_api_nonsense.txt之后这是不正确的。