7

Linux デバイス ドライバーを作成しようとしています。「memcpy」を使用しようとするまでは、非常にうまく機能していました。「make」すると、警告が表示されるだけで、コンパイラエラーは発生しません。

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

OK、insmod 経由でロードしようとすると、コンソールが表示されます。

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

そしてdmesgで:

main: Unknown symbol memcpy (err 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 を使用する関数:

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;
 }

誰かが私を助けることができますか?linux/string.h にあると思っていましたが、同じエラーが発生します。私はカーネル 2.6.37-rc1 を使用しています (2.6.37-rc1 以降でのみ動作する user-mode-linux で実行しています)。どんな助けでも大歓迎です。

# 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
4

7 に答える 7

2

私は user-mode-linux でそれをやっています

ユーザーモード Linux なしで試してみませんか?

カーネルは libc とリンクしていませんが、UML は例外です。それはあなたのリンクエラーを説明するかもしれません.

于 2011-01-04T20:51:05.570 に答える
1

最初のポイントは、これはリンク エラーであり、コンパイル エラーではないということです。実際、これは動的リンクの問題です。あなたのモジュールは、警告はありますが正常にコンパイルされます。これが失敗するのは、ロードするときだけです。したがって、これはヘッダー ファイルとは関係ありません。2 番目のポイントは、memcpy が定義され、カーネルで広く使用されているため、memcpy シンボルが見つからない理由がないということです。

その理由は、単に GCC 自体の問題である可能性があります。GCC は、カーネルに存在しない libgcc を参照する組み込み関数を使用します。このような場合は、コンパイラ オプションを使用することで解決できます。-fno-builtin

于 2010-12-31T15:52:13.530 に答える
1

memcpylib/string.cでarch 固有 (if __HAVE_ARCH_MEMCPY) または汎用バージョンとして定義されています。どちらの場合でも、利用可能である必要があります。/proc/kallsymsを見て、モジュールをobjdumpでチェックし、シンボルのバージョン管理が混乱していないことも確認してください。

于 2010-12-31T15:29:39.160 に答える
0

正しいstring.hヘッダーを含めます。

#include <linux/string.h>

これでコンパイルエラーが発生した場合は、代わりに投稿してください。

于 2010-12-31T15:41:05.010 に答える
0

書く余地があるので、このコメントを回答として投稿させてください。

まず、「err 0」は怪しいと思われます。(0 が成功するためです。)次に、Makefile には 2 つの KERNELDIR 行があり、後者は ?=d であるため、意図したとおりに動作しない可能性があります。CFLAGS="-ARCH=um" もあり、ひどく間違っているように聞こえます。-I$PWD は冗長です。KERNELRELASE チェックも必要ありません。全体として、過度に複雑に見えます。このはるかに単純な MF を使用します。

obj-m := main.o

KERNELDIR = /lib/modules/$(シェル uname -r)/build

すべて: モジュール

モジュール modules_install クリーン:
        ${MAKE} V=1 ARCH=um -C ${KERNELDIR} M=$$PWD $@;
于 2010-12-31T15:07:25.393 に答える
0

memcpy は、含めるのを逃した string.h で定義されています。

于 2010-12-31T14:44:35.640 に答える
0

EXTRA_CFLAGS問題は宣言にある可能性があります。-インクルードとアーキテクチャの余分なスペースを削除してみてください。

EXTRA_CFLAGS+=-I$(PWD) ARCH=um
于 2011-01-04T19:46:44.367 に答える