cat:書き込みエラー:無効な引数

cat:書き込みエラー:無効な引数

カスタム文字デバイスへの書き込みの使用

猫123> / dev / chardev

与えられた

cat:書き込みエラー:無効な引数

権限を666に変更し、sudoも試してみました。結果はまだ同じです。また、同様の方法でエコーを試しました。

私はArchiLinux 4.8を使用しています。

編集:ドライバコード

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>


//Prototypes
static int __init init(void);
static void __exit cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);

#define SUCCESS 0
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices*/
#define BUF_LEN 80 /* Max length of the message from the device */

static int Major; //Major number of the devices
static int Device_Open = 0;

static char msg[BUF_LEN]; //Message given when asked
static char *msg_Ptr;

static struct file_operations fops = {
    .read = device_read,
    .write = device_write,
    .open = device_open,
    .release = device_release
};

static int __init init(){
    Major = register_chrdev(0,DEVICE_NAME,&fops);
    if(Major < 0){
        printk(KERN_ALERT "Failure in registering the device. %d\n", Major);
        return Major;
  }
    printk(KERN_INFO "%s registered with major %d \n",DEVICE_NAME,Major);
    printk(KERN_INFO "create a device with 'mknod /dev/%s c %d 0'\n",DEVICE_NAME,Major);
    printk(KERN_INFO "Try to cat and echo the file and shit man.\n");
    return SUCCESS;
}

static void __exit cleanup(){
    unregister_chrdev(Major, DEVICE_NAME);
    printk(KERN_ALERT "Unregistered the device %s i guess? \n"DEVICE_NAME);
}   

static int device_open(struct inode *inode,struct file *file){
    static int counter = 0;
    if(Device_Open)
        return -EBUSY;

    Device_Open++;
    sprintf(msg, "I already told you %d times Hello world!\n", counter++);
    msg_Ptr = msg;
    try_module_get(THIS_MODULE);
    return SUCCESS;
}

static int device_release(struct inode *inode,struct file *file){
    Device_Open--;
    module_put(THIS_MODULE);
    return 0;
}

static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset){
    int bytes_read = 0;
    if(*msg_Ptr == 0)
        return 0;
    while(length && *msg_Ptr){
        put_user(*(msg_Ptr++),buffer++);
        length--;   
        bytes_read++;
    }
    return bytes_read;
}

static ssize_t device_write(struct file *filp,const char *buff, size_t len, loff_t *off){
    printk(KERN_ALERT "You cannot write to this device.\n");
    return -EINVAL;
}

module_init(init);
module_exit(cleanup);

ここでは、device_write関数を使用してfops構造の.writeに割り当てたことがわかります。それでは、writeコマンドを受け入れ、ログにそのステートメントを印刷する必要はありませんか?

答え1

カーネルでは、各ドライバはファイルに対して開く、閉じる、読み取り、書き込み、ナビゲーション、ioctlなど、さまざまな操作を実行できる一連のメソッドを提供します。これらのメソッドはstruct file_operations。デバイスの場合、これらのメソッドは特定のデバイス(つまり、ブロック/文字、メジャー番号、マイナー番号の特定の組み合わせ)を登録するドライバによって提供されます。

ドライバはこれらのメソッドの一部のみを実装でき、デフォルト値は提供されます。デフォルト値は通常、何もせず、成功(メソッドに対して何もしないことが合理的な場合)またはEINVAL(合理的なデフォルト値がなく、欠落しているメソッドがその機能がサポートされていないことを意味する場合)を返します。

「書き込みエラー:無効な引数」は、writeドライバのメソッドがEINVALを返したことを意味します。最も可能性の高い説明は、ドライバーにwrite方法がないことです。ドライバが特定のタスクをサポートしていないのは非常に一般的です。たとえば、一部のドライバはioctlのみをサポートし、読み取り/書き込みはサポートしておらず、一部のドライバは本質的に一方向(入力デバイスなど)であり、読み取りのみをサポートし、書き込みはサポートしておらず、その逆も同様です。

「無効なパラメータ」は権限には関係なく、むしろデバイスが実行できる操作に関連しています。書き込み権限はありませんが、ドライバと会話する権限がある場合、権限エラーが発生します。それはあなたがドライバーにまったく概念のない仕事をするように頼むことです。

関連情報