Не удается прочитать с устройства, созданного драйвером устройства

#c #linux #linux-kernel #linux-device-driver #kernel-module

Вопрос:

В своем проекте я решил попробовать создать устройство, которое может имитировать броски костей. Для этого я написал следующий модуль ядра.

 //dicedriver.c
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/device.h>

static dev_t fdevice;
static struct cdev my_cdev;
static struct class *deviceclass;

static int val;
unsigned char get_random_byte(int max) {
         unsigned char c;
         get_random_bytes(amp;c, 1);
         return c%max;
}

static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){
    val = get_random_byte(6) 1;
    int len = sizeof(val);
    if(count < len){
        return -EINVAL;
    }
    if(*ppos != 0){
        return 0;
    }
    if(copy_to_user(buf, amp;val, len)!=0){
        printk(KERN_ALERT "ERROR while copying to buffer");
        return -EINVAL;
    }
    *ppos = len;
    return len;
}

static ssize_t my_write(struct file *file, const char *buf, size_t count, loff_t *ppos){
    return 0;
}

int my_open(struct inode *inode, struct file *filep){
    return 0;
}

int my_release(struct inode *inode, struct file *filep){
    return 0;
}


static struct file_operations dice_fops = {
    .owner = THIS_MODULE,
    .read = my_read,
    .release = my_release,
    .write = my_write,
    .open = my_open,
};

static int __init my_init(void){
    int ret;
    struct device *dev_ret;

    ret = alloc_chrdev_region(amp;fdevice, 0, 1, "dice_device");
    if(ret<0)
        printk(KERN_ALERT "dice_device init error 1");
    deviceclass = class_create(THIS_MODULE, "chardrv");
    if(IS_ERR(deviceclass)){
        printk(KERN_ALERT "dice_device init error 2");
        unregister_chrdev_region(fdevice, 1);
        return PTR_ERR(deviceclass);
    }
    dev_ret = device_create(deviceclass, NULL, fdevice, NULL, "dice_device");
    if(IS_ERR(dev_ret)){
        printk(KERN_ALERT "dice_device init error 3");
        class_destroy(deviceclass);
        unregister_chrdev_region(fdevice, 1);
        return PTR_ERR(dev_ret);
    }
    cdev_init(amp;my_cdev, amp;dice_fops);
    ret = cdev_add(amp;my_cdev, fdevice, 1);
    if(ret<0){
        printk(KERN_ALERT "dice_device init error 4");
        device_destroy(deviceclass, fdevice);
        class_destroy(deviceclass);
        unregister_chrdev_region(fdevice, 1);
        return ret;
    }
    printk(KERN_DEBUG "dice_device created sucessfully");
    return 0;
}

static void __exit my_exit(void){
    device_destroy(deviceclass, fdevice);
    class_destroy(deviceclass);
    unregister_chrdev_region(fdevice, 1);
    printk(KERN_DEBUG "dice device removed successfully");
}

module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("NWLYNX");
MODULE_DESCRIPTION("DICE HELLO WORLD");
MODULE_VERSION("DEV");
 

Для тестирования того же самого, что я планирую сделать сначала, просто напечатав десять из этих случайных чисел, я создал еще один файл тестирования.

 ///testing.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(){
    int fd = 0, ret = 0;
    int i=0;
    char buf[20]="";
    fd = open("/dev/dice_device", O_RDONLY);
    printf("fd :%dn",fd);
    for(i=0;i<10;i  ){
        ret = read(fd,buf,10);
        printf("buf:%s,len:%dn",buf,ret);
    }
    close(fd);
    return 0;
}
 

Проверив journalctl и попытавшись отладить мой dicedriver, я обнаружил , что он может успешно создать случайное число и сохранить его val , но не может скопировать его buf .
Любые намеки или предложения по этому поводу были бы полезны.

Комментарии:

1. Вы возвращаете значение int, но пытаетесь напечатать строку.

2. Ну ладно, спасибо @stark, твой комментарий помог мне