Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1706917
  • 博文数量: 98
  • 博客积分: 667
  • 博客等级: 上士
  • 技术积分: 1631
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-27 15:59
个人简介

一沙一世界 一树一菩提

文章分类

全部博文(98)

文章存档

2021年(8)

2020年(16)

2019年(8)

2017年(1)

2016年(11)

2015年(17)

2014年(9)

2013年(4)

2012年(19)

2011年(1)

2009年(4)

分类: LINUX

2012-08-01 16:51:45

昨天,公司同事进来说以前的linux-2.6.9的驱动被我移植到linux-3.0.4上以后。出现异常现象。
具体的驱动是个gpio控制端口驱动,很简单。就是控制几个状态灯的亮灭问题。在老板子环境下没有问题。在新的环境下就出现问题。
详细的问题表现如下:
当前灯处于灭的状态,设置让灯亮,点亮,正常
当前灯处于亮的状态,设置让灯亮,无变化,正常
当前灯处于灭的状态,设置让灯灭,点亮,异常
当前灯处于亮的状态,设置让灯灭,无变化,异常

这个驱动是公司以前不知道谁做的,反正做的不怎么样。我感觉隐患很多。
我记得当时的修改是这样的。从linux-2.6.36把,已经由unlocked_ioctl替代原来的ioctl。其中驱动的变化就是函数参数去掉inode参数,其它应该没有变化。应用应该不用修改就可以。

然后就查看应用代码和对应驱动代码,对灯的控制在应用的ioctl函数里。移植这部分的时候,感觉这部分代码确实不怎么样。开始打算重写驱动。后来发现各个模块之间的耦合性太强,还涉及到应用的修改,由于对应用的逻辑不很了解,又传说这系统用了很长时间,很稳定。所以也就没有考虑重写了。

首先跟踪代码看看吧,在应用添加printf,在驱动添加printk。发现当点灯的时候,ioctl执行顺序正常。
而执行灭灯的代码的时候,应用程序ioctl函数前后的printf也都执行了,但是驱动里的unlocked_ioctl
ha函数没有执行。奇怪啊。然后在unlocked_ioctl函数最前面添加一条printk,同样没有执行。也就是说unlocked_ioctl函数没有执行一句代码。我怀疑unlocked_ioctl函数在调用do_vfs_ioctl函数或者其它地方检查参数,不合格返回或者退出。

想到这里就看看unlocked_ioctl的cmd命令吧。
从文件开头一看,都是这样的定义:
#define DO_SOMETHING 1
又看了看应用传过来的参数,驱动空间直接使用应用空间传来的参数。没有任何关于拷贝或者其它空间保护机制。
不过这种代码还确实安全的跑了好几年。
可能移植到linux-3.0.4上以后,这个cmd不好用了,或者这个cmd作用到其它设备上,为了验证,我先把这个灭灯的cmd随便换一个其它值。make insmod,然后运行app。可以正常开支灯的亮灭。
这个案道理说也是一个解决方法,但是这也太不可靠啦。

为了减少隐患,看了看ioctl-number.txt把
#define DO_SOMETHING 1
改成这样的形式:
#define XXXX_MAGIC 'u'
#define IOCTL_NUMBER 0x50
#define DOSOMETHING_NUMBER(n) (IOCTL_NUMBER+(n))
#define DO_SOMETHING _IO(IOCTL_MAGIC, DOSOMETHING_NUMBER(a), type)
...
再把unlocked_ioctl中需要使用应用传来的参数的地方添加上put_user或者get_user。
然后make,执行,还行,不错。

总结:
1 写ioctl函数,一定要按照linux系统的规定来定义cmd。
2 内核空间和应用空间之间的参数使用也要注意,最好不要直接使用不是自己空间的变量。

阅读(5761) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~