linux核内外通信——ioctl

来源:互联网 发布:java 使用ant design 编辑:程序博客网 时间:2024/05/17 07:27
    ioctl可以通过对内核设备的控制达到核内外通信的目的,即在用户态控制内核动作。从ioctl这个名称上看,本意是针对I/O设备进行的控制操作,但实际并不限制是真正的I/O设备,可以是任何一个内核设备即可。
    使用ioctl通信一般是通过字符设备实现(当然也可以用其他的设备)。首先要向内核注册一个字符设备,设置字符设备属性:
STATIC struct miscdevice test_char_dev=
{
    .name  = “test_dev”,
    .fops  = &test_char_dev_fops 
};
STATIC const struct file_operations test_char_dev_fops =
{
    .open = test_ctl_open,
    .release = test_ctl_release,
    .ioctl = test_ctl_ioctl,
    .owner = THIS_MODULE

};

像内核注册一个字符设备:

misc_register(&test_char_dev);

这样就向内核注册了一个字符设备,字符设备名是"test_dev",注册完成后会在/dev/目录下有个test_dev,这就是我们的字符设备。在用户态操作的时候先open这个文件。打开这个文件后的文件操作指针是test_char_dev_fops ,所以如果我们有ioctl相关的操作,会调用到test_ctl_ioctl这个接口,不同cmd的相关处理都在这个接口完成。

ioctl函数的基本使用格式为:
int ioctl(int fd, int cmd, void *data)
第一个参数是文件描述符,打开字符设备返回的描述符;

第二个参数cmd是操作命令,操作命令由自己定义,在内核中针对不用的命令做出不同的动作,以用户态实现内核设备的控制。cmd虽然是一个整数,但是有一定的参数格式的;
cmd命令参数是个32位整数,分为四部分:
dir(2b)  size(14b)  type(8b) nr(8b)

内核定义了一些宏对cmd进行操作,这里不展开讲解,详细请看(http://blog.csdn.net/jasonsungblog/article/details/8682009);

第三个参数是数据起始位置指针,由于内核内存空间和用户内存空间不同,要将内核数据拷贝到用户空间,要使用专用拷贝函数copy_to_user();要将用户空间数据拷贝到内核,要使用copy_from_user()。

0 0