proc 通信

使用 /proc 文件系统进行用户空间应用程序与内核驱动程序的通信,是一种简单而有效的方法。以下是一个完整的示例,展示了如何通过 /proc 文件系统进行通信,包括内核模块代码和用户空间应用程序代码。

内核模块代码

这个内核模块将在 /proc 文件系统中创建一个文件,用户空间程序可以通过读取和写入该文件与内核模块通信。

1. 创建一个名为 myproc.c 的文件,并添加以下代码:

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>

#define PROC_NAME "myprocfile"
#define BUFFER_SIZE 128

static char proc_buffer[BUFFER_SIZE];
static unsigned long buffer_size = 0;

// 读操作的实现
static ssize_t proc_read(struct file *file, char __user *buffer, size_t count, loff_t *pos) {
    ssize_t ret = 0;

    if (*pos > 0 || count < buffer_size) {
        return 0;
    }

    if (copy_to_user(buffer, proc_buffer, buffer_size)) {
        return -EFAULT;
    }

    *pos = buffer_size;
    ret = buffer_size;

    return ret;
}

// 写操作的实现
static ssize_t proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) {
    buffer_size = count;
    if (buffer_size > BUFFER_SIZE) {
        buffer_size = BUFFER_SIZE;
    }

    if (copy_from_user(proc_buffer, buffer, buffer_size)) {
        return -EFAULT;
    }

    return buffer_size;
}

static const struct file_operations proc_fops = {
    .owner = THIS_MODULE,
    .read = proc_read,
    .write = proc_write,
};

// 初始化模块
static int __init proc_init(void) {
    proc_create(PROC_NAME, 0666, NULL, &proc_fops);
    printk(KERN_INFO "/proc/%s created\n", PROC_NAME);
    return 0;
}

// 清理模块
static void __exit proc_exit(void) {
    remove_proc_entry(PROC_NAME, NULL);
    printk(KERN_INFO "/proc/%s removed\n", PROC_NAME);
}

module_init(proc_init);
module_exit(proc_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple /proc file example");
MODULE_VERSION("1.0");

用户空间应用程序代码

2. 创建一个名为 user_app.c 的文件,并添加以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define PROC_FILE "/proc/myprocfile"
#define BUFFER_SIZE 128

int main() {
    int fd;
    char buffer[BUFFER_SIZE];

    // 打开 /proc 文件
    fd = open(PROC_FILE, O_RDWR);
    if (fd < 0) {
        perror("Failed to open /proc file");
        return 1;
    }

    // 写入数据到 /proc 文件
    const char *data = "Hello from user space!";
    if (write(fd, data, strlen(data)) < 0) {
        perror("Failed to write to /proc file");
        close(fd);
        return 1;
    }

    // 读取数据从 /proc 文件
    if (lseek(fd, 0, SEEK_SET) < 0) { // 将文件偏移量设置为文件开头
        perror("Failed to seek /proc file");
        close(fd);
        return 1;
    }

    if (read(fd, buffer, BUFFER_SIZE) < 0) {
        perror("Failed to read from /proc file");
        close(fd);
        return 1;
    }

    printf("Read from /proc file: %s\n", buffer);

    close(fd);
    return 0;
}

编译和使用步骤

1. 编译内核模块

在包含 myproc.c 文件的目录中创建一个名为 Makefile 的文件,并添加以下内容:

obj-m += myproc.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

 

 

参考:

 

posted @ 2024-07-17 11:26  redrobot  阅读(4)  评论(0编辑  收藏  举报