首页 > 解决方案 > 为什么这个内核模块不处理打开和读取系统调用?

问题描述

我正在使用 Ubuntu 20.04(Linux 内核 5.4.0-37 通用)学习 Linux 内核模块。以下是实际代码的代码。

我希望跟随模块在get_random_bytes(&c, 1)处理系统调用时将 0-255 ( ) 之间的单字节随机数传递给用户空间缓冲区,->read()然后向 dmesg 打印一条消息。

但不幸的是,目前它不起作用。似乎没有添加句柄->read()->open()系统调用。

为什么它不处理->read()->open()系统调用?

用户空间应用代码(打开和读取设备文件)app.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

int main() {
    char c[8];
    memset(c, '\0', 8);
    int fd = open("/dev/devsaikoro0", O_RDONLY);
    read(fd, &c, 1);
    //printf("Hello\n");
    printf("%s\n", c);
}

内核模块代码:

#include <linux/init.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/random.h>

MODULE_LICENSE("Dual BSD/GPL");

static int devsaikoro_num = 3;
static int devsaikoro_major = 0;
static int devsaikoro_minor = 0;
static struct cdev devsaikoro_cdev;
static struct class *devsaikoro_class = NULL;
static dev_t saikoro_dev;

ssize_t read_num(struct file * filp, char __user *buf, size_t count, loff_t *f_pos)
{
    int retval;
    char c;
    get_random_bytes(&c, 1);
    if (copy_to_user(buf, &c, 1)) {
        printk("devsaikoro read failed\n");
        retval = -EFAULT;
        return retval;
    } else {
        printk("devsaikoro read succeeded\n");
        return 1;
    }
}
struct file_operations fops = {
    .read = read_num,
};

int saikoro_open(struct inode *inode, struct file *file) {

    printk("devsaikoro open\n");
    file->f_op = &fops;
    return 0;
}

struct file_operations fops2 = {
    .open = saikoro_open,
};

static int devsaikoro_init(void)
{
    dev_t dev = MKDEV(devsaikoro_major, 0);
    int alloc_ret = 0;
    int major;
    int cdev_err = 0;
    struct device *class_dev = NULL;

    alloc_ret = alloc_chrdev_region(&dev, 0, devsaikoro_num, "devsaikoro");
    if (alloc_ret) {
        goto error;
    }
    devsaikoro_major = major = MAJOR(dev);

    cdev_init(&devsaikoro_cdev, &fops2);
    devsaikoro_cdev.owner = THIS_MODULE;
    cdev_err = cdev_add(&devsaikoro_cdev, MKDEV(devsaikoro_major, 0), devsaikoro_num);
    if (cdev_err)
        goto error;

    devsaikoro_class = class_create(THIS_MODULE, "devsaikoro");
    if (IS_ERR(devsaikoro_class))
        goto error;
    saikoro_dev = MKDEV(devsaikoro_major, devsaikoro_minor);
    class_dev = device_create(devsaikoro_class, NULL, saikoro_dev, NULL, "devsaikoro%d", devsaikoro_minor);
    printk(KERN_ALERT "devsaikoro_driver (major %d) installed\n", major);
    return 0;


error:
    if (cdev_err == 0) {
        cdev_del(&devsaikoro_cdev);
    }
    if (alloc_ret == 0) {
        unregister_chrdev_region(dev, devsaikoro_num);
    }
    return -1;
}

static void devsaikoro_exit(void)
{
    dev_t dev = MKDEV(devsaikoro_major, 0);

    device_destroy(devsaikoro_class, saikoro_dev);
    class_destroy(devsaikoro_class);

    cdev_del(&devsaikoro_cdev);

    unregister_chrdev_region(dev, devsaikoro_num);

    printk(KERN_ALERT  "devsaikoro driver removed\n");
}

module_init(devsaikoro_init);
module_exit(devsaikoro_exit);

标签: linuxubuntulinux-kernellinux-device-driverkernel-module

解决方案


推荐阅读