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
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix