内核空间与用户空间的通信之proc(一)

内核空间与用户空间的通信

在Linux中编程,特别是涉及内核驱动时,应用层程序经常需要和内核层驱动进行数据交换,比如内核检测到某个状态需要通知应用程序,或者应用程序的某个状态发生改变需用通知内核等等。

proc简介
/proc 文件系统是一种虚拟文件系统,它可以实现linux内核空间和用户空间的通信。与普通文件不同,这里的虚拟文件的内容都是动态创建的。
如果只是控制内核中的参数而不是传输较多数据的话,用“/proc”是很合适的。

proc实例实现的功能
读取路由器的工作模式到无线驱动中,根据当前的工作模式,对不同的报文做一些特殊处理。路由器当前的工作模式保存在配置文件中,通过脚本来读取配置文件,并将该值写入对应的proc文件即可。

内核空间程序

// 运行下面用户态的脚本后,路由器的工作模式就被写入msg中,内核空间直接使用msg的值即可
#include <linux/init.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

MODULE_AUTHOR("yahai.zhang");
MODULE_DESCRIPTION("procfs get_operation_mode module.");
MODULE_LICENSE("GPL");

#define PROCNAME "operation_mode"
struct proc_dir_entry *proc_entry = NULL;
char msg[16]={0};
static int operation_file_read(struct file * file, char *data, size_t len, loff_t *off)
{
    if(*off > 0)
        return 0;
    if(copy_to_user(data, msg, strlen(msg)))
        return -EFAULT;
    *off += strlen(msg);
    return strlen(msg);
}

static int operation_file_write(struct file *file, const char *data, size_t len, loff_t *off)
{
    memset(msg, 0, sizeof(char)*16);
    if(copy_from_user(msg, (void*)data, len))
        return -EFAULT;
    return len;
}

static struct file_operations operationmode_ops = {
    .read = operation_file_read,
    .write = operation_file_write,
};

static int __init procMode_init(void)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
    if(proc_entry = create_proc_entry(PROCNAME, 0666, NULL))
        proc_entry->proc_fops = &operationmode_ops;
    else
#else
    if(!(proc_entry = proc_create(PROCNAME, 0666, NULL, &operationmode_ops)))
#endif
        printk("!! FAIL to create %s PROC !!\n", PROCNAME);

    return 0;
}

static void __exit procMode_exit(void)
{
    remove_proc_entry(PROCNAME,NULL);
}

module_init(procMode_init);
module_exit(procMode_exit);

内核空间程序

# shell脚本,读取配置文件中路由器当前工作模式,并写数据到相应的proc文件
set_mode_to_kernel() {
    mode=`uci get system.system.mode`
    if [ "$mode" == "AP" ]; then
        echo -e "ap\c" > /proc/operation_mode
    else
        echo -e "repeater\c" > /proc/operation_mode
    fi
}

另外一种内核与用户空间通信方式方式是使用内核设备的读写或IOCTL来实现,以后再介绍。

猜你喜欢

转载自blog.csdn.net/sky619351517/article/details/80715036