Ядро выдает ошибку при записи в файл символьного устройства в Debian 4.9.82-ti-r102 9.3 - PullRequest
0 голосов
/ 26 февраля 2020

Я успешно создал файл устройства в папке / dev, но запись в этот файл устройства заставляет ядро ​​выдавать следующие сообщения об ошибках.

kernel:[10090.943733] Internal error: : 1b [#3] PREEMPT SMP ARM
kernel:[10091.049020] Process echo (pid: 3728, stack limit = 0xdc40a218)
kernel:[10091.054880] Stack: (0xdc40be60 to 0xdc40c000)
kernel:[10091.059267] be60: c15491c6 00000022 dc5cb14c bf30430c dc40bedc dc40be88 c075312c c074fe5c
kernel:[10091.067488] be80: c0753018 ffffff04 ffff0a00 c140414c c0d407c8 bf30430c c140414c 40cfbcf3
kernel:[10091.075709] bea0: 00852878 ffffff04 ffff0a00 00040952 c01a7404 c140414c 00852878 00852878
Segmentation fault

Я очень хорошо знаю c из Linux Драйверы устройств

Может ли кто-нибудь помочь мне с этим?

Я прилагаю код для этого драйвера устройства символа

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


MODULE_AUTHOR("RUCHA");
MODULE_DESCRIPTION("Character Driver First test");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.0.1");


static int MajorNum;
static struct class* RetValOfClassRegistration = NULL;
static struct device*  RetVal = NULL;
static char message[1024];
static int openDev(struct inode * , struct file *);
static int closeDev(struct inode * , struct file *);
static ssize_t readDev(struct file *, char *, size_t, loff_t *);
static ssize_t writeDev(struct file *, const char *, size_t, loff_t *);

static struct file_operations FileOps = {

    .owner = THIS_MODULE,
    .open = openDev,
    .read = readDev,
    .write = writeDev,
    .release = closeDev,

};

static int registerCharDev(void){

    return register_chrdev(0,"MyDev",&FileOps);
}

static int __init Loaded(void){

    // registering device

    MajorNum = registerCharDev();

    if(MajorNum < 0){
        printk("Can not register device\n");
        return -1;
    }

    printk("Driver Loaded with %d \n",MajorNum);


    // registering device class

    RetValOfClassRegistration = class_create(THIS_MODULE,"MyCharacterDriver");

    if(RetValOfClassRegistration < 0){

        printk("can not register class for driver number : %d\n",MajorNum);
        return 0;
    }


    // register the driver

    RetVal = device_create(RetValOfClassRegistration,NULL,MKDEV(MajorNum,0),NULL,"MyDev");


    return 0;

}


static void __exit Removed(void){
    device_destroy(RetValOfClassRegistration,MKDEV(MajorNum,0));
    class_unregister(RetValOfClassRegistration);
    class_destroy(RetValOfClassRegistration);
    unregister_chrdev(MajorNum,"MyDev");
    printk("Driver Removed\n");
}


module_init(Loaded);
module_exit(Removed);


static int openDev(struct inode *inodep , struct file *filep){

    printk("Device is now open to read write operations\n");
    return 0;
}


static int closeDev(struct inode *inodep , struct file *filep){

    printk("Device Closed\n");
    return 0;
}

static ssize_t readDev(struct file *filep, char *c, size_t v, loff_t *lp){

    printk("Read From the device\n");
    return 0;
}

static ssize_t writeDev(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
    sprintf(message, "%s(%zu letters)", buf, len);
    return 0;
}

, и пользовательский ввод

echo '1'> / dev / MyDev

1 Ответ

0 голосов
/ 28 февраля 2020

Вы не можете получить доступ к указателю пользовательских данных (buf) напрямую. Вам необходимо использовать copy_from_user, чтобы сначала скопировать данные в память ядра. Кроме того, используйте snprintf вместо sprintf, чтобы избежать переполнения буфера.

Кроме того, компилируйте с включенной отладкой , особенно CONFIG_DEBUG_INFO, чтобы получить более полезные сообщения об ошибках в журнале ядра. .

...