linux编程写一个用户程序及字符设备驱动?

驱动程序可以使用ioctl执行硬件控制。

,,,:可选参数:插入*argp,具体内容依赖于cmd

inode与filp两个指针对应于应用程序传递的文件描述符fd,这和传递open方法的参数一样。

cmd 由用户空间直接不经修改的传递给驱动程序

size:表示所涉及的用户数据大小,通常为13位或是14位,具体可通过宏_IOC_SIZEBITS找到针对特定体系结构的具体数值。内核不会检查这个位字段,对该字段的检查可以帮助我们检测用户空间的错误。

在使用ioctl命令编号时,一定要避免与预定义命令重复,否则,命令冲突,设备不会响应

下列ioctl命令对任何文件(包括设备特定文件)都是预定义的:

如何使用ioctl的附加参数:arg

1:arg是个整数,那简单,直接用

2:arg是个指针,麻烦点,需检测后才能用

分析:使用指针,首先得保证指针指向的地址合法。因此,在使用这个指针之前,我们应该使用

addr: 一个用户空间的地址

如果在该地址处既要读取,又要写入,则应该用:VERIFY_WRITE,因为它是VERIFY_READ的超集

注意:首先, access_ok不做校验内存存取的完整工作; 它只检查内存引用是否在这个进程有合理权限的内存范围中,且确保这个地址不指向内核空间内存。其次,大部分驱动代码不需要真正调用 access_ok,而直接使用put_user(datum, ptr)和get_user(local, ptr),它们带有校验的功能,确保进程能够写入给定的内存地址,成功时返回 0, 并且在错误时返回 -EFAULT.。

/*抽取类型和编号位字段,并拒绝错误的命令号:在调用access_ok之前返回ENOTTY(不恰当的ioctl)*/

/*方向是一个位掩码,而VERIFY_WRITE用于R/W*传输。“类型”是针对用户空间而言,而access_ok面向内核,因此,读取和写入,恰好相反*/

使用时,速度快,不做类型检查,使用时可以给ptr传递任意类型的指针参数,只要是个用户空间的地址就行,传递的数据大小依赖于ptr参数的类型。

一般用法:实现一个读取方法时,可以调用__put_user来节省几个时钟周期,或者在复制多项数据之前调用一次access_ok,像上面代码一样。

接收的数据被保存在局部变量local中,返回值说明其是否正确。同样,__get_user应该在操作地址被access_ok后使用。

来由:驱动程序必须进行附加的检查以确认用户是否有权进行请求的操作

权能作用:基于权能的系统抛弃了那种要么全有,要么全无的特权分配方式,而是把特权操作划分成了独立的组。

在执行一项特权之前,应先检查其是否具有这个权利

CAP_NET_ADMIN /*进行网络管理任务的能力, 包括那些能够影响网络接口的任务*/

我要回帖

更多关于 linux字符设备和块设备 的文章

 

随机推荐