2010-12-31 38 views
6

Tôi đang cố gắng viết trình điều khiển thiết bị Linux. Tôi đã có nó để làm việc thực sự tốt, cho đến khi tôi đã cố gắng sử dụng "memcpy". Tôi thậm chí không nhận được một lỗi biên dịch, khi tôi "làm cho" nó chỉ cảnh báo tôi:Trình điều khiển thiết bị Linux: Biểu tượng "memcpy" không được tìm thấy

WARNING: "memcpy" [/root/homedir/sv/main.ko] undefined!

OK và khi tôi cố gắng để tải qua insmod, tôi nhận được trên giao diện điều khiển:

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

và trên dmesg:

main: Unknown symbol memcpy (err 0)

tôi bao gồm:

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

Chức năng sử dụng 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; 
} 

một người nào đó có thể giúp tôi? Tôi nghĩ rằng điều này là trong linux/string.h, nhưng tôi nhận được lỗi chỉ giống nhau. Tôi đang sử dụng kernel 2.6.37-rc1 (tôi đang làm trong user-mode-linux, nó chỉ hoạt động từ 2.6.37-rc1). Bất kỳ trợ giúp nào cũng được đánh giá rất cao.

# 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 
+1

Tôi nghĩ rằng bạn đang thiếu '#include ' ... rõ ràng trừ khi một trong các tiêu đề linux đã bao gồm nó: p – Machinarius

+4

@Drknezz nó không và đó là bởi vì bạn không thể sử dụng nó. Hạt nhân không phải là môi trường được lưu trữ và không có stdio. Và mã không bao gồm stdio vì vậy cũng không có * lý do * để bao gồm nó. – hobbs

+0

@Hinton là lỗi liên kết chứ không phải lỗi biên dịch. Bạn đang xây dựng mô-đun của mình như thế nào? – hobbs

Trả lời

2

tôi đang làm nó trong sử dụng chế độ-linux

Bạn có thể thử mà không cần tài khoản -mode Linux?

Hạt nhân không liên kết với libc nhưng UML là ngoại lệ. Điều đó có thể giải thích lỗi liên kết của bạn.

+0

Có, bạn chắc chắn đúng về UML, nhưng: Vấn đề đã giải quyết được ngay hôm nay (không có sự giúp đỡ của tôi). Memcpy dường như làm việc ... Lý do duy nhất tôi thấy cho điều này là: Đây là một dự án đại học, và Lead biên dịch UML cho chúng tôi. Tôi khá chắc chắn rằng họ đã làm hỏng một vài thứ trước đây và sửa nó ngay bây giờ; cảm ơn cho câu trả lời. Điều duy nhất tôi có thể đề nghị bây giờ là biên dịch UML cho chính bạn và thực hiện nó đúng cách. – Hinton

0

memcpy được định nghĩa bằng chuỗi.h mà bạn đã bỏ lỡ.

+1

Trong hạt nhân, tôi không thể chỉ bao gồm string.h; Tôi đã thử nó với linux/string.h mà có thể được sử dụng trong hạt nhân, nhưng điều đó đã không làm việc ... Tôi nên có một lỗi biên dịch/cảnh báo anyway thay vì lỗi hệ thống xây dựng này nếu một cái gì đó đã sai với bao gồm – Hinton

0

Hãy để tôi đăng nhận xét này làm câu trả lời vì có nhiều chỗ để viết hơn.

Đầu tiên, âm thanh "err 0" đáng ngờ. (Vì 0 là thành công.) Sau đó, Makefile của bạn có hai dòng KERNELDIR, dòng sau là? = D, vì vậy nó có thể không làm những gì bạn muốn. Ngoài ra còn có CFLAGS = "- ARCH = um" nghe rất tệ. -I $ PWD là dư thừa. Cũng không cần kiểm tra KERNELRELASE. Tổng cộng, nó trông quá phức tạp. Sử dụng điều này MF đơn giản hơn nhiều:

 
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 [email protected]; 
+0

Khi tôi thử điều này, tôi luôn luôn nhận được "không có gì để được thực hiện cho tất cả/sạch/etc." Tôi đã có makefile của tôi chủ yếu là từ LDD3. – Hinton

+0

Bạn có chắc chắn có các tab đúng không? (Nếu không, hãy xem '.PHONY: tất cả các module clean') – user502515

1

memcpy hoặc được định nghĩa là vòm cụ thể (nếu __HAVE_ARCH_MEMCPY) hoặc như là một phiên bản generic trong lib/string.c. Trong cả hai trường hợp, nó sẽ có sẵn. Hãy xem trong /proc/kallsyms, kiểm tra mô-đun của bạn với objdump và cũng xác minh phiên bản biểu tượng không gây rối mọi thứ.

0

Bao gồm tiêu đề string.h phù hợp;

#include <linux/string.h> 

Nếu bạn gặp lỗi biên dịch, hãy đăng thay thế.

+1

Lỗi này không phải là lỗi trình biên dịch, đó là lỗi liên kết. – doron

+0

Có bởi vì nó không bao gồm tiêu đề phải, Hinton tuyên bố 'linux/string.h' đưa ra một lỗi biên dịch và tôi yêu cầu điều đó. – ismail

1

Điểm đầu tiên là đây là lỗi liên kết chứ không phải lỗi biên dịch. Trong thực tế, nó là một vấn đề liên kết động. Bạn mô-đun biên dịch tốt mặc dù với một cảnh báo. Đó là chỉ khi bạn tải nó rằng điều này không thành công. Vì vậy, điều này không có gì để làm với các tập tin tiêu đề. Điểm thứ hai là memcpy được định nghĩa và sử dụng rộng rãi trong hạt nhân nên không có lý do tại sao biểu tượng memcpy không được tìm thấy.

Lý do đơn giản có thể là vấn đề với chính GCC. GCC sử dụng các hàm dựng sẵn trong đó một số có thể tham chiếu đến libgcc không có trong hạt nhân.Nếu trường hợp này xảy ra, điều này có thể được giải quyết bằng cách sử dụng tùy chọn trình biên dịch -fno-builtin

+0

Nếu có bất kỳ tùy chọn nào cần thiết, chúng sẽ được thêm vào trong makefiles của hạt nhân. Nhắc mới nhớ, một số makefiles đã được thêm vào '-fno-buildin-memcpy'. – user502515

0

Sự cố có thể xảy ra với tuyên bố EXTRA_CFLAGS. Hãy thử loại bỏ các không gian thêm cho bao gồm và - cho kiến ​​trúc, tức:

EXTRA_CFLAGS+=-I$(PWD) ARCH=um 
Các vấn đề liên quan