kernel 中ioctl应用
2014-10-23 19:18
148 查看
ioctl是操作非文件类型的设备的一个常用方法,同时也是调试过程一个很有用的方式。
这里还是承接wdt的那篇来继续
static long at91_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
int new_value;
switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &at91_wdt_info,
sizeof(at91_wdt_info)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_SETOPTIONS:
if (get_user(new_value, p))
return -EFAULT;
if (new_value & WDIOS_DISABLECARD)
at91_wdt_stop();
if (new_value & WDIOS_ENABLECARD)
at91_wdt_start();
return 0;
case WDIOC_KEEPALIVE:
at91_wdt_reload();
/* pat the watchdog */
return 0;
case WDIOC_SETTIMEOUT:
if (get_user(new_value, p))
return -EFAULT;
if (at91_wdt_settimeout(new_value))
return -EINVAL;
/* Enable new time value */
at91_wdt_start();
/* Return current value */
return put_user(wdt_time, p);
case WDIOC_GETTIMEOUT:
return put_user(wdt_time, p);
default:
return -ENOTTY;
}
}
这里先定义两个一个最底层的被调用接口,在这里面初始化了几个命令,这些命令就可以直接调用你自己的底层函数了
之后面临的就是怎么让这个ioctl被上层可一调用
这里有一个系统设置的结构体
static const struct file_operations at91wdt_fops = {
.owner
= THIS_MODULE,
.llseek
= no_llseek,
.unlocked_ioctl
= at91_wdt_ioctl,
.open = at91_wdt_open,
.release
= at91_wdt_close,
.write
= at91_wdt_write,
};
把ioctl赋给unlocked
再把这个结构体赋给miscdevice结构体 这里就可以看出来他是一个杂项设备 不是block 或者字符设备了
static struct miscdevice at91wdt_miscdev = {
.minor
= WATCHDOG_MINOR,
.name = "watchdog",
.fops = &at91wdt_fops,
};
这里再把它注册给系统就好了
static int __devinit at91wdt_probe(struct platform_device *pdev)
{
int res;
if (at91wdt_miscdev.parent)
return -EBUSY;
at91wdt_miscdev.parent = &pdev->dev;
res = misc_register(&at91wdt_miscdev);
if (res)
return res;
printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
wdt_time, nowayout ? ", nowayout" : "");
return 0;
}
上面就是这个设备备注测时的调用 可以看到开始就把这个ioctl的父结构体赋给系统了
后面系统的上层就可以看到这个函数了 就可以一层层的穿到驱动来了
这里还是承接wdt的那篇来继续
static long at91_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
int new_value;
switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &at91_wdt_info,
sizeof(at91_wdt_info)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_SETOPTIONS:
if (get_user(new_value, p))
return -EFAULT;
if (new_value & WDIOS_DISABLECARD)
at91_wdt_stop();
if (new_value & WDIOS_ENABLECARD)
at91_wdt_start();
return 0;
case WDIOC_KEEPALIVE:
at91_wdt_reload();
/* pat the watchdog */
return 0;
case WDIOC_SETTIMEOUT:
if (get_user(new_value, p))
return -EFAULT;
if (at91_wdt_settimeout(new_value))
return -EINVAL;
/* Enable new time value */
at91_wdt_start();
/* Return current value */
return put_user(wdt_time, p);
case WDIOC_GETTIMEOUT:
return put_user(wdt_time, p);
default:
return -ENOTTY;
}
}
这里先定义两个一个最底层的被调用接口,在这里面初始化了几个命令,这些命令就可以直接调用你自己的底层函数了
之后面临的就是怎么让这个ioctl被上层可一调用
这里有一个系统设置的结构体
static const struct file_operations at91wdt_fops = {
.owner
= THIS_MODULE,
.llseek
= no_llseek,
.unlocked_ioctl
= at91_wdt_ioctl,
.open = at91_wdt_open,
.release
= at91_wdt_close,
.write
= at91_wdt_write,
};
把ioctl赋给unlocked
再把这个结构体赋给miscdevice结构体 这里就可以看出来他是一个杂项设备 不是block 或者字符设备了
static struct miscdevice at91wdt_miscdev = {
.minor
= WATCHDOG_MINOR,
.name = "watchdog",
.fops = &at91wdt_fops,
};
这里再把它注册给系统就好了
static int __devinit at91wdt_probe(struct platform_device *pdev)
{
int res;
if (at91wdt_miscdev.parent)
return -EBUSY;
at91wdt_miscdev.parent = &pdev->dev;
res = misc_register(&at91wdt_miscdev);
if (res)
return res;
printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
wdt_time, nowayout ? ", nowayout" : "");
return 0;
}
上面就是这个设备备注测时的调用 可以看到开始就把这个ioctl的父结构体赋给系统了
后面系统的上层就可以看到这个函数了 就可以一层层的穿到驱动来了
相关文章推荐
- msm8974 camera driver添加新摄像头kernel hal修改
- 怎样保存kernel crash dump 文件
- virtualbox 启动虚拟机报 cannot access kernel driver 错误
- Linux kernel upgrade steps
- OS Kernel生成方式
- SMP多核处理器omap4启动分析 笔记版 转载请注明出处---crosskernel@gmail.com
- ubuntu12.04 下 利用 qemu kgdb 调试kernel
- What is the location of the directory of C header files that match your running kernel?
- 关于Tomcat搭建服务器需要80端口问题的解决方案以及80端口被NT KERNEL & SYSTEM ,pid4占用解决方法
- ubuntu升级内核 virtualbox 出现Kernel driver not installed (rc=-1908)
- Linux Kernel系列三:Kernel编译和链接中的linker script语法详解
- 嵌入式 kernel调试方法小结
- Ubuntu 安装 VMware Tools 报“无法找到kernel header path”的解决方案
- OpenCL 学习step by step (3) 存储kernel文件为二进制
- 高斯(exp)kernel 中缩放参数r的确定 度量矩阵到kernel矩阵的转换
- 新建的一个学习linux kernel github
- Linux kernel <= v3.15-rc4 本地提权 Exploit 已测
- U-Boot 编译(嵌入式U-BOOT,kernel编译)
- linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)