首页 文章

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

提问于
浏览
6

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

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

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

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

这是我的make文件:

ccflags-y = -g

obj-m = access_mem.o

all:make -C / lib / modules / $(shell uname -r)/ build M = $(PWD)模块

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

2 回答

  • 1

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

    #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
    

    如果以这种方式开发,那么您的内核模块将来或向后兼容 . Compatibility is only adaptation of API's or function signature etc.. changes for the kernel version by preserving the older API's or function signature etc.. in your kernel module as in the above example, but still you need to build/compile your kernel module against the kernel version on which you are trying to load.

  • 5

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

相关问题