Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux内核字符设备驱动程序将空字符串返回给用户空间_C_Linux Kernel_Kernel_Driver - Fatal编程技术网

C Linux内核字符设备驱动程序将空字符串返回给用户空间

C Linux内核字符设备驱动程序将空字符串返回给用户空间,c,linux-kernel,kernel,driver,C,Linux Kernel,Kernel,Driver,首先,我尝试: static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset) { int error_count = 0; // copy_to_user has the format ( * to, *from, size) and returns 0 on success // error_count = copy_to_user(buffer, messag

首先,我尝试:

static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset) {
    int error_count = 0;
    // copy_to_user has the format ( * to, *from, size) and returns 0 on success
    // error_count = copy_to_user(buffer, message, size_of_message);
    error_count = copy_to_user(buffer, "test", 4);

    if (error_count == 0) { // if true then have success
//      printk(KERN_INFO "MOB: Sent %d characters to the user >> %s\n", size_of_message, message);
        printk(KERN_INFO "MOB: Sent %d characters to the user >> %s\n", 4, "test");
        return (size_of_message = 0); // clear the position to the start and return 0
    }
    else {
        printk(KERN_INFO "MOB: Failed to send %d characters to the user\n", error_count);
        return -EFAULT; // Failed -- return a bad address message (i.e. -14)
    }
}
然后我试着检查:

error_count = copy_to_user(buffer, message, size_of_message);
同样的故事。两者都返回空字符串。没有错误。与dmesg无关

我以root用户身份进行试用,并且该文件具有以下权限:

crw------1root根250,3月30日14:43/dev/kbdozgur

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

#define  DEVICE_NAME "kbdozgur"   
#define  CLASS_NAME  "kbdozgur"  
MODULE_AUTHOR("Mehmet Ozgur Bayhan");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Interrupt buffering skeleton");
MODULE_VERSION("0.2");

#define BUFFER_SIZE 20
static unsigned char bfr[BUFFER_SIZE]; 
static int bufferCounter = 0; 

static int majorNumber; 
static char message[BUFFER_SIZE] = { 0 }; 
static short size_of_message; 
static int numberOpens = 0; 
static struct class* kbdozgurcharClass = NULL; 
static struct device* kbdozgurcharDevice = NULL; 


static int dev_release(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *, size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);

static struct file_operations fops = { .open = dev_open, .read = dev_read, .write = dev_write, .release = dev_release, };

irq_handler_t irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
    static unsigned char scancode;
    //Read keyboard status
    scancode = inb(0x60);

    if (scancode == 0x01) {
        printk(KERN_INFO "MOB: Inputs are > %s\n", bfr);
        bufferCounter = 0;
        memset(&bfr[0], 0, sizeof(bfr));
    }
    else if (scancode == 0x1E) {
        bfr[bufferCounter] = 'a';
        bufferCounter++;
    }
    else if (scancode == 0x1F) {
        bfr[bufferCounter] = 's';
        bufferCounter++;
    }
    else if (scancode == 0x20) {
        bfr[bufferCounter] = 'd';
        bufferCounter++;
    }
    else if (scancode == 0x21) {
        bfr[bufferCounter] = 'f';
        bufferCounter++;
    }
    else if (scancode == 0x22) {
        bfr[bufferCounter] = 'g';
        bufferCounter++;
    }
    else if (scancode == 0x23) {
        bfr[bufferCounter] = 'h';
        bufferCounter++;
    }
    else if (scancode == 0x24) {
        bfr[bufferCounter] = 'j';
        bufferCounter++;
    }
    if (bufferCounter >= BUFFER_SIZE) {
        bufferCounter = 0;
        memset(&bfr[0], 0, sizeof(bfr));
    }

    return (irq_handler_t) IRQ_HANDLED;
}

static int init_mod(void) {
    int result;

    /*
     *****************************
     * Create Character device
     *****************************
     */

    // Try to dynamically allocate a major number for the device
    majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
    if (majorNumber < 0) {
        printk(KERN_ALERT "MOB: kbdozgurcharClass failed to register a major number\n");
        return majorNumber;
    }
    printk(KERN_INFO "MOB: registered correctly with major number %d\n", majorNumber);
    // Register the device class
    kbdozgurcharClass = class_create(THIS_MODULE, CLASS_NAME);
    if (IS_ERR(kbdozgurcharClass)) { // Check for error and clean up if there is
        unregister_chrdev(majorNumber, DEVICE_NAME);
        printk(KERN_ALERT "MOB: Failed to register device class\n");
        return PTR_ERR(kbdozgurcharClass); // Correct way to return an error on a pointer
    }
    printk(KERN_INFO "MOB: device class registered correctly\n");

    // Register the device driver
    kbdozgurcharDevice = device_create(kbdozgurcharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
    if (IS_ERR(kbdozgurcharDevice)) { // Clean up if there is an error
        class_destroy(kbdozgurcharClass); // Repeated code but the alternative is goto statements
        unregister_chrdev(majorNumber, DEVICE_NAME);
        printk(KERN_ALERT "MOB: Failed to create the device\n");
        return PTR_ERR(kbdozgurcharDevice);
    }
    printk(KERN_INFO "MOB: device class created correctly\n"); // Made it! device was initialized
    /*
     *****************************
     * Bind interrupt
     *****************************
     */

    result = request_irq(1, (irq_handler_t) irq_handler, IRQF_SHARED, "kbdozgur", (void *) (irq_handler));
    if (result) printk(KERN_INFO "MOB: can't get shared interrupt for keyboard\n");

    printk(KERN_INFO "MOB: kbdozgur loaded.\n");
    return result;

}

static void exit_mod(void) {
    /*
     * ****************************
     * Destroy Character Device
     * ****************************
     */
    device_unregister(kbdozgurcharDevice);
    device_destroy(kbdozgurcharClass, MKDEV(majorNumber, 0)); // remove the device
    class_unregister(kbdozgurcharClass); // unregister the device class
    class_destroy(kbdozgurcharClass); // remove the device class
    unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number
    printk(KERN_INFO "MOB: Goodbye from the LKM!\n");

    /*
     * ****************************
     * Free IRQ bind
     * ****************************
     */
    free_irq(1, (void *) (irq_handler));
    printk(KERN_INFO "MOB: kbdozgur unloaded.\n");
}

static int dev_open(struct inode *inodep, struct file *filep) {
    numberOpens++;
    printk(KERN_INFO "MOB: Device has been opened %d time(s)\n", numberOpens);
    return 0;
}


static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset) {
    int error_count = 0;
    // copy_to_user has the format ( * to, *from, size) and returns 0 on success
//  error_count = copy_to_user(buffer, message, size_of_message);
    error_count = copy_to_user(buffer, "test", 4);

    if (error_count == 0) { // if true then have success
//      printk(KERN_INFO "MOB: Sent %d characters to the user >> %s\n", size_of_message, message);
        printk(KERN_INFO "MOB: Sent %d characters to the user >> %s\n", 4, "test");
        return (size_of_message = 0); // clear the position to the start and return 0
    }
    else {
        printk(KERN_INFO "MOB: Failed to send %d characters to the user\n", error_count);
        return -EFAULT; // Failed -- return a bad address message (i.e. -14)
    }
}


static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset) {
    sprintf(message, "%s(%d letters)", buffer, len); // appending received string with its length
    size_of_message = strlen(message); // store the length of the stored message
    printk(KERN_INFO "MOB: Received %d characters from the user\n", len);
    return len;
}

static int dev_release(struct inode *inodep, struct file *filep) {
    printk(KERN_INFO "MOB: Device successfully closed\n");
    return 0;
}
module_init(init_mod);
module_exit(exit_mod);

那么我哪里做错了?

读取的
应该返回读取的字节数。在您的情况下,返回0

size\u消息=0

您应该执行以下操作

error_count = copy_to_user(buffer, "test", 4);

为什么从
dev_read
返回0?您不应该将超过
len
字节的内容复制到用户缓冲区。是的,我现在得到了:)谢谢。谢谢您的解决方案。它可以工作,但现在我遇到了另一个问题:“sprintf(message,“%s(%d个字母)”,buffer,len);“part:)Try
snprintf(message,sizeof(message),“%*s(%d个字母)”,len,buffer,len)。还有一点更正=>下面的代码导致无限循环,我不知道为什么,但我通过删除“retval=-EFAULT;”并始终返回“size\u request”来解决它
size_t  size_requested;
...
if (len >= size_of_message) {
   size_requested  = size_of_message;
} else {
   size_requested = len;
}
if (copy_to_user (buf, message, size_requested)) {
    retval = -EFAULT;
    return retval
}
return size_requested;