2010-12-31 31 views
6

Linuxデバイスドライバを作成しようとしています。私は "memcpy"を使用しようとするまで、本当にうまく動作するようにしています。私はそれだけで私を警告し、「作る」とき私も、コンパイラエラーを取得しない:Linuxデバイスドライバ:シンボル "memcpy"が見つかりません

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以降にしか動かないユーザモード-linuxでやっています)。どんな助けでも大歓迎です。

+1

私はあなたが欠けていると思います。#include '...明らかに、Linuxヘッダの1つにすでに含まれている場合を除きます:p – Machinarius

+4

@Drknezzそれは使用できないためです。カーネルはホストされた環境ではなく、stdioもありません。コードにはstdioが含まれていないので、それを含める理由もありません。 – hobbs

+0

@Hintonそれはリンクエラーです。コンパイルエラーではありません。どのようにモジュールを構築していますか?ああ、申し訳ありませんが、 – hobbs

答えて

2

私は、ユーザーモードのLinuxでそれをやっている

あなたはユーザーなしで試みることができる:含めるための余分なスペースとアーキテクチャの-すなわちを削除してください-mode Linux?

カーネルはlibcにリンクしませんが、UMLは例外です。 リンクエラーを説明する可能性があります。

+0

はい、あなたはUMLについて間違いありませんでしたが、問題は今日解決しました(私の助けなし)。 Memcpyはうまくいくようです...私がこれを見る唯一の理由は、これは大学のプロジェクトであり、LeadはUMLをコンパイルします。彼らは何日か前に何かを混乱させて今それを修正したと確信しています。答えに感謝します。私が今お勧めできるのは、あなた自身でUMLをコンパイルし、正しく実行することです。 – Hinton

0

memcpyが含まれていなかったstring.hで定義されています。

+1

カーネルでは、単にstring.hを含めることはできません。私はlinux/string.hでカーネルで使われるかもしれませんが、うまくいきませんでしたが...何かが間違っていた場合、コンパイルエラー/警告が表示されるはずです。 – Hinton

0

このコメントを回答として投稿してください。書く余地があります。

まず、「err 0」は不審な音です。 (0は成功であるからです。)そして、あなたのMakefileに2つのKERNELDIR行があります。後者は?= dなので、あなたが望むことはできません。また、CFLAGS = " - ARCH = um"という非常に間違った音がします。 -I $ PWDは冗長です。 KERNELRELASEチェックも必要ありません。合計で、それは過度に複雑に見えます。このはるかに簡単な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 [email protected]; 
+0

私がこれを試してみると、私はいつも「すべて/きれいにするなど何もしない」私はmakefileをLDD3からほとんど持っています。 – Hinton

+0

タブが正しいですか? (そうでない場合は '.PHONY:すべてのモジュールがきれい'を参照) – user502515

1

memcpyはアーチ特定(__HAVE_ARCH_MEMCPY場合)またはのlib/string.cにおけるジェネリック版などのように定義されますか。いずれの場合も、それは利用可能でなければならない。 /proc/kallsymsを参照して、モジュールをobjdumpでチェックして、シンボルのバージョン管理が物事を乱していないことを確認します。

0

右を含むstring.hヘッダー;

#include <linux/string.h> 

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

+1

エラーはコンパイラエラーではなく、リンカエラーです。 – doron

+0

はい、正しいヘッダーを含んでいないので、Hintonは 'linux/string.h'はコンパイルエラーを返し、私はそれを求めています。 – ismail

1

最初の点は、これはリンクエラーであり、コンパイルエラーではないことです。実際、それはダイナミックリンクの問題です。モジュールは警告を出してコンパイルします。これがロードされたときにのみ失敗します。だから、これはヘッダファイルとは関係ありません。 2番目の点は、memcpyがカーネル内で広範囲に定義され使用されているため、memcpyシンボルが見つからない理由はありません。

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

+0

オプションが必要な場合は、すでにカーネルのmakeファイルに追加されています。これについて言えば、いくつかのアーチ型makefileは時には '-fno-builtin-memcpy'を追加します。 – user502515

0

この問題は、EXTRA_CFLAGS宣言である可能性があります。

EXTRA_CFLAGS+=-I$(PWD) ARCH=um 
関連する問題