开发者

Linux Device Driver: Symbol "memcpy" not found

I'm trying to write a Linux device driver. I've got it to work really well, until I tried to use "memcpy". I don't even get a compiler error, when I "make" it just warns me:

WARNING: "memcpy" [/root/home开发者_JAVA技巧dir/sv/main.ko] undefined!

OK and when I try to load via insmod, I get on the console:

insmod: error inserting './main.ko': -1 Unknown symbol in module

and on dmesg:

main: Unknown symbol memcpy (err 0)

I include the following:

#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 */

The function using memcpy:

static int dc_copy_to_user(char __user *buf, size_t count, loff_t *f_pos, 
        struct sv_data_dev *dev)
{
    char data[MAX_KEYLEN];
    size_t i = 0;

    /* Copy the bulk as long as there are 10 more bytes to copy */
    while (i < (count + MAX_KEYLEN)) {
        memcpy(data, &dev->data[*f_pos + i], MAX_KEYLEN);
        ec_block(dev->key, data, MAX_KEYLEN);
        if (copy_to_user(&buf[i], data, MAX_KEYLEN)) {
            return -EFAULT;
        }
        i += MAX_KEYLEN;
     }

     return 0;
 }

Could someone help me? I thought the thing was in linux/string.h, but I get the error just the same. I'm using kernel 2.6.37-rc1 (I'm doing in in user-mode-linux, which works only since 2.6.37-rc1). Any help is greatly appreciated.

# Context dependent makefile that can be called directly and will invoke itself
# through the kernel module building system.
KERNELDIR=/usr/src/linux

ifneq ($(KERNELRELEASE),)

EXTRA_CFLAGS+=-I $(PWD) -ARCH=um
obj-m := main.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)

all:
 $(MAKE) V=1 ARCH=um -C $(KERNELDIR) M=$(PWD) modules

clean:
 rm -rf Module.symvers .*.cmd *.ko .*.o *.o *.mod.c .tmp_versions *.order

endif


I'm doing it in user-mode-linux

Could you try without User-mode Linux?

The kernel does not link with the libc but UML is an exception. That could explain your linking error.


memcpy is either defined as arch specific (if __HAVE_ARCH_MEMCPY) or as a generic version in lib/string.c. In either case, it should be available. Look in /proc/kallsyms, check your module with objdump and also verify symbol versioning isn't messing things up.


The first point is that this is a linking error and not a compile error. In fact it is a dynamic link problem. You module compiles fine albeit with a warning. It is only when you load it that this fails. So this has nothing to do with header files. The second point is that memcpy is defined and used extensively in the kernel so the so there is no reason why the memcpy symbol is not being found.

The reason could simply be a problem with GCC itself. GCC uses builtin functions of which some may refer to libgcc which is not present in the kernel. If this is the case, this can be solved by using the compiler option -fno-builtin


memcpy is defined in string.h which you missed to include.


Let me post this comment as an answer, because there's more room to write.

First, "err 0" sound suspicious. (Because 0 is success.) Then, your Makefile has two KERNELDIR lines, the latter of which is ?=d, so it might not do what you want. There is also CFLAGS="-ARCH=um" which sounds so terribly wrong. -I$PWD is redundant. The KERNELRELASE check is not needed either. In total, it looks overly convoluted. Use this much simpler 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 $@;


Include the right string.hheader;

#include <linux/string.h>

If you have a compile error with this, post that instead.


The issue might be with the EXTRA_CFLAGS declaration. Try removing the extra space for the include and the - for the architecture, i.e. :

EXTRA_CFLAGS+=-I$(PWD) ARCH=um
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜