Linux设备驱动程序:Symbol";memcpy“;找不到

Linux设备驱动程序:Symbol";memcpy“;找不到,c,linux-kernel,device-driver,memcpy,C,Linux Kernel,Device Driver,Memcpy,我正在尝试编写一个Linux设备驱动程序。在我尝试使用“memcpy”之前,它一直工作得很好。我甚至没有得到编译器错误,当我“制造”它只是警告我: 警告:“memcpy”[/root/homedir/sv/main.ko]未定义 好的,当我尝试通过insmod加载时,我进入控制台: insmod:在模块中插入“/main.ko”时出错:-1个未知符号 关于dmesg: main:未知符号memcpy(错误0) 我包括以下内容: #include <linux/module.h> #i

我正在尝试编写一个Linux设备驱动程序。在我尝试使用“memcpy”之前,它一直工作得很好。我甚至没有得到编译器错误,当我“制造”它只是警告我:

警告:“memcpy”[/root/homedir/sv/main.ko]未定义

好的,当我尝试通过insmod加载时,我进入控制台:

insmod:在模块中插入“/main.ko”时出错:-1个未知符号

关于dmesg:

main:未知符号memcpy(错误0)

我包括以下内容:

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/kernel.h> /* printk() */
#include <linux/slab.h>  /* kmalloc() */
#include <linux/fs.h>  /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/cdev.h>
#include <asm/system.h>  /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */

memcpy是在string.h中定义的,您没有将其包括在内。

让我将此评论作为一个答案发布,因为这里有更多的写作空间

首先,“err0”听起来可疑。(因为0是成功的。)然后,您的Makefile有两行KERNELDIR,后者是?=d,因此它可能无法执行您想要的操作。还有CFLAGS=“-ARCH=um”听起来非常错误-I$PWD是多余的。内核relase检查也不需要。总的来说,它看起来过于复杂。使用更简单的MF:

obj-m := main.o KERNELDIR = /lib/modules/$(shell uname -r)/build all: modules modules modules_install clean: ${MAKE} V=1 ARCH=um -C ${KERNELDIR} M=$$PWD $@; obj-m:=main.o KERNELDIR=/lib/modules/$(shell uname-r)/build 全部:模块 模块安装清洁: ${MAKE}V=1 ARCH=um-C${KERNELDIR}M=$$PWD$@;
memcpy
被定义为特定于arch的(如果
\u拥有\u arch\u memcpy
),或者被定义为lib/string.c中的通用版本。无论哪种情况,它都应该可用。查看/proc/kallsyms,使用objdump检查您的模块,并验证符号版本控制没有弄糟任何事情。

包括正确的
string.h
标题

#include <linux/string.h>
#包括

如果这是一个编译错误,请发布它。

第一点是,这是一个链接错误,而不是编译错误。实际上,这是一个动态链接问题。您的模块编译得很好,尽管有一个警告。只有当您加载它时,它才会失败。所以这与头文件无关。 第二点是memcpy是在内核中定义和广泛使用的,因此没有理由找不到memcpy符号


原因可能只是GCC本身的问题。GCC使用内置函数,其中一些函数可能引用内核中不存在的libgcc。如果是这种情况,可以通过使用编译器选项
-fno builtin

解决此问题,问题可能在于
额外的\u CFLAGS
声明。尝试删除include的额外空间和架构的
-
,即:

我是在用户模式linux下做的

您可以尝试不使用用户模式Linux吗

内核不与libc链接,但UML是一个例外。
这可以解释你的链接错误。

我认为你缺少
#include
。。。显然,除非其中一个linux标头已经包含它:p@Drknezz它没有,那是因为你不能使用它。内核不是托管环境,也没有stdio。代码不包含stdio,所以也没有理由包含它。@Hinton这是链接错误,不是编译错误。“你是如何建立你的模块的?”霍布斯:哦,对不起。我对linux内核驱动程序开发一无所知,只是想到了一个通用的解决方案;)为什么这个问题标注了C++?在内核中,我不能只包含String。h;我用linux/string.h试过了,它可能在内核中使用,但是没有用。。。无论如何,我应该得到一个编译器错误/警告,而不是这个构建系统错误。如果includes有问题,当我尝试这个方法时,我总是得到“所有的事情都没有做/clean/等等”。我的makefile大部分来自LDD3。你确定你的选项卡正确吗?(如果没有,请参阅
.PHONY:all modules clean
)是的,因为它没有包含正确的头,Hinton声称
linux/string.h
给出了一个编译错误,我要求这样做。如果需要任何选项,它们将已经添加到内核生成文件中。说到这里,一些arch makefiles已经添加了
-fno builtin memcpy
。是的,关于UML你肯定是对的,但是:问题今天就解决了(没有我的帮助)。Memcpy似乎很管用。。。我看到的唯一原因是:这是一个大学项目,Lead为我们编译UML。我敢肯定他们几天前把事情搞砸了,现在又把它修好了;谢谢你的回答。我现在唯一能推荐的就是为自己编译UML并正确地执行它。 obj-m := main.o KERNELDIR = /lib/modules/$(shell uname -r)/build all: modules modules modules_install clean: ${MAKE} V=1 ARCH=um -C ${KERNELDIR} M=$$PWD $@;
#include <linux/string.h>
EXTRA_CFLAGS+=-I$(PWD) ARCH=um