我正在向一个Android Gingerbread内核添加一个外部驱动程序模块(类似于Linux)。我以前做过它并且它有效但这次我遇到了问题。我按照O'Reilly“Linux Device Drivers 3rd edition”中的配方进行了操作:
在本地Makefile中,添加以下语句:
obj-m := GobiNet.o GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o
在人类语言中,它意味着从GobiUSBNet.c + QMIDevice.c + QMI.c建立一个GobiNet.ko.
这适用于构建整个内核时调用makefile的情况。我在Ubuntu x86-64bit上交叉编译ARM-EABI系统(Cortex-A8)。
不知何故,构建系统理解我想要的东西,因为它在编译期间说:
/home/sylvain/Projects/android_gingerbread_realv210_ver_1_0/kernel CHK include/linux/version.h CHK include/generated/utsrelease.h make[1]: `include/generated/mach-types.h' is up to date. CALL scripts/checksyscalls.sh CHK include/generated/compile.h LD drivers/cell/OptionGobiNet/built-in.o CC [M] drivers/cell/OptionGobiNet/GobiUSBNet.o CC [M] drivers/cell/OptionGobiNet/QMIDevice.o CC [M] drivers/cell/OptionGobiNet/QMI.o LD [M] drivers/cell/OptionGobiNet/GobiNet.o Kernel: arch/arm/boot/Image is ready SHIPPED arch/arm/boot/compressed/lib1funcs.S AS arch/arm/boot/compressed/lib1funcs.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready Building modules, stage 2. MODPOST 5 modules ERROR: "usbnet_suspend" [drivers/cell/OptionGobiNet/GobiNet.ko] undefined! ERROR: "usbnet_resume" [drivers/cell/OptionGobiNet/GobiNet.ko] undefined! ERROR: "usbnet_disconnect" [drivers/cell/OptionGobiNet/GobiNet.ko] undefined! ERROR: "usbnet_probe" [drivers/cell/OptionGobiNet/GobiNet.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2
它还会生成典型的“GobiNet.mod.c”和“GobiNet.o”,这是在您希望将驱动程序作为模块时生成的,但它没有完成我希望的“GobiNet.ko”。我在主目录中运行了“find -name * .ko”,而“GobiNet.ko”无处可寻。
我还查看了WEB和kernel / documentation / kbuild / * .txt。大约有3种方法可以做到这一点。我选择了上面描述的那个,因为所有的环境变量都是在顶级构建脚本中设置的,我不编译本机,但是我交叉编译。无论如何,生成内核树中的另一个“.ko”,因此构建脚本应该很好地生成“.ko”模块。
知道是什么让这个过程开始但没有完成“.ko”文件?
答案 0 :(得分:5)
我找到了解决方案。我真的误解了错误消息以及“.ko”模块如何与内核交互。外部模块在编译/链接时解析外部(至少一些),而不是在运行时。这就是我得到4“错误”的原因。
那就是说,我的“GobiNet”正在寻找我的内核设置中没有的外部符号。一些快速的greps让我发现它需要“drivers / net / usb / usbnet.c”。这需要在“.config”文件中设置CONFIG_USBNET = y(通过“make xconfig”设置)。希望它可以帮助别人。
编辑:回答关于“快速的几个问题”的问题。我的意思是我搜索包含缺少名称的所有源文件。它会告诉我哪个文件定义了该符号。然后,我可以找到应该将变量设置为“y”以将其包含在编译中。这是一个例子:
grep -r --include="*.c" "usbnet_probe"
您可以在要递归搜索的文件夹(-r选项)中在终端中执行该操作。 grep对于在大量文件中查找文本非常有用。我经常不记得具体但快速的谷歌搜索为您提供了如何执行一些您从未想过可以轻松完成的非常棘手的搜索。
答案 1 :(得分:0)
另一种可能性是该函数已定义但未以某种方式导出(就像您编写自己的新函数但忘记导出或某些合并问题)。然后修复是添加一行像
EXPORT_SYMBOL_GPL(some_new_func);