Linux用户态和内核态通信

来源:互联网 发布:超轻粘土批发淘宝 编辑:程序博客网 时间:2024/05/16 04:22

linux环境下用户态和内核态通信机制主要有:ioctl、procFS和netlink,下面分别对各种实现进行简要分析。

1、ioctl

在内核态创建设备文件,并提供read、write和ioctl等操作接口,

1)内核态部分

#define DEV_NAME "usr"static struct cdev usr_cdev;static dev_t usr_dev_num;static struct class *usr_class;static struct device *usr_dev;enum E_DEV_CMD{    ADD_USER= 0x2201,    DEL_USER= 0x2202};static int usr_dev_open(struct inode *node, struct file * fd){return RET_OK;}static int usr_dev_close(struct inode *node, struct file * fd){return RET_OK;}static long usr_dev_ioctl(struct file *fd, unsigned int cmd, unsigned long arg){int ret = 0;switch (cmd){case ADD_USER:{usr_info_t user_info;usr_info_t __user *UserSpaceInfo =  (usr_info_t __user *) arg;if (UserSpaceInfo == NULL){ret = -EINVAL;break;}if (copy_from_user(&user_info, UserSpaceInfo, sizeof(usr_info_t))){ret = -EFAULT;break;}ret = usr_add(&user_info);break;}case DEL_USER:{usr_info_t user_info;usr_info_t __user *UserSpaceInfo =  (usr_info_t __user *) arg;if (UserSpaceInfo == NULL){ret = -EINVAL;break;}if (copy_from_user(&user_info, UserSpaceInfo, sizeof(usr_info_t))){ret = -EFAULT;break;}usr_del(&user_info);break;}default:{printk(KERN_ERR " cmd %d not support \n", cmd);return -EINVAL;}}return ret;}static const struct file_operations usr_dev_fops ={.owner      = THIS_MODULE,.open       = usr_dev_open,.release    = usr_dev_close,.unlocked_ioctl = usr_dev_ioctl,};static int usr_dev_init(void){int ret = 0;usr_class = class_create(THIS_MODULE, "usr");if(IS_ERR(usr_class)){return -1;}ret = alloc_chrdev_region(&usr_dev_num, 0, 1, DEV_NAME);if (ret){goto err;}cdev_init(&usr_cdev, &usr_dev_fops);ret = cdev_add(&usr_cdev, usr_dev_num, 1);if (ret){unregister_chrdev_region(usr_dev_num, 1);goto err;}usr_dev = device_create(usr_class, NULL, usr_dev_num, NULL, "usr");if(IS_ERR(usr_dev)){unregister_chrdev_region(usr_dev_num, 1);ret = -1;goto err;}return ret;err:class_destroy(usr_class);return ret;}



2)用户态部分

fd = open(DEV_NAME, O_RDONLY | O_NDELAY);if (fd < 0){return -1;}ret = ioctl(fd, cmd, &input);if(0 != ret){   printf("Failed to exe usr cmd, string=[%s], ret=[%d] \n", argv[1], ret);}close(fd);


2、procFS

1)内核态部分

#define PROCNAME "usr"static int usr_show(struct seq_file *m, void *p){seq_printf(m, "Global usr num = [%d]\n", g_usr_info->elem);seq_putc(m, '\n');return 0;}static int special_open(struct inode *inode, struct file *file){return single_open(file, usr_show, NULL);}static ssize_t usr_write(struct file *file, const char *data, size_t len, loff_t *ppos){char *buf = NULL;uint32_t mark = 0;buf = kmalloc(len,  GFP_KERNEL);if(!buf)return -EFAULT;if(copy_from_user(buf, data, len)){goto out;}sscanf(buf, "%d", &mark);printk("The mark input is [%u]\n", mark);kfree(buf);buf = NULL;return len;}static struct file_operations usr_route_ops ={.open = special_open,.read = seq_read,.write = usr_write,.llseek = seq_lseek,.release = single_release,};static int __init usr_init(void){if(!proc_create(PROCNAME, S_IRUSR | S_IWUSR, NULL, &usr_route_ops)){printk(KERN_ERR "Failed to create /proc/usr .\n");}}static void __exit usr_exit(void){remove_proc_entry(PROCNAME, NULL);}module_init(usr_init);module_exit(usr_exit);

2)用户态部分

可以直接读写proc对应的文件,如:

read : cat /proc/usrwrite: echo 1024 >/proc/usr


3、netlink

0 0