Sto provando a scrivere un driver di periferica Linux. Ho funzionato molto bene, fino a quando ho provato a usare "memcpy". Non ho nemmeno ottenere un errore di compilazione, quando mi "faccio" solo mi avverte:Driver di dispositivo Linux: simbolo "memcpy" non trovato
WARNING: "memcpy" [/root/homedir/sv/main.ko] undefined!
OK e quando provo a caricare tramite insmod, ottengo sulla console:
insmod: error inserting './main.ko': -1 Unknown symbol in module
e dmesg:
main: Unknown symbol memcpy (err 0)
ho sono i seguenti:
#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 */
La funzione usando 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;
}
qualcuno potrebbe aiutarmi? Ho pensato che la cosa fosse in linux/string.h, ma ottengo l'errore lo stesso. Sto usando il kernel 2.6.37-rc1 (sto facendo in user-mode-linux, che funziona solo dal 2.6.37-rc1). Qualsiasi aiuto è molto apprezzato.
# 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
Penso che manchi '#include' ... ovviamente a meno che uno degli header di Linux non lo includa già: p –
Machinarius
@Drknezz non lo fa e questo perché non puoi usarlo. Il kernel non è un ambiente ospitato e non c'è stdio. E il codice non include stdio quindi non c'è anche * motivo * per includerlo. – hobbs
@Hinton è un errore di collegamento, non un errore di compilazione. Come stai costruendo il tuo modulo? – hobbs