ldd3的scull字符驱动在kernel3.2下编译出错的解决方法

6410阅读 0评论2014-08-22 Yiran_Linux
分类:嵌入式

转载地址:http://blog.csdn.net/rig622/article/details/7608317
本文稍作修改除去编译时产生的警告信息
由于LDD3的驱动实例都是在linux2.6.10中实现,在后期linux内核版本中有些改动,导致有些实例编译不通过。

环境:ubuntu12.04   内核版本:linux3.2.0  实例:LDD3中驱动实例 SCULL

排除错误

1、scripts/Makefile.build:49: *** CFLAGS was changed in "/usr/src/linux-source-3.2.0/drivers/scull/Makefile". Fix it to use ccflags-y。 停止。

这里提示我们修改Makefile中的CFLAGS,用EXTRA_CFLAGS 代替

2、/usr/src/linux-source-3.2.0/drivers/scull/main.c:17:26: 致命错误: linux/config.h:没有那个文件或目录编译中断。

在2.6.19开始的内核中删除了config.h文件,因此只要在mian.c中注释掉#include即可。

3、/usr/src/linux-source-3.2.0/drivers/scull/main.c:556:2: 错误: 初始值设定项里有未知的字段‘ioctl’

这个错误网上搜索发现2.6.38版本内核 file_operation结构体已经删除了ioctl函数,取代的是:

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

long (*compat_ioctl) (struct file *, unsigned int, unsigned long);

file_operation结构体在 /usr/src/linux-2.6.28.8/include/linux/fs.h定义

解决方案:

在globalmem.c中将globalmem_ioctl函数定义做如下修改即可:

static long globalmem_ioctl( struct file *filp,unsigned int cmd, unsigned long arg)

在file_operation 赋值处修改:

.unlocked_ioctl = globalmem_ioctl
在scull.h中将int scull_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg);
修改为
long scull_ioctl(struct file *filp,unsigned int cmd, unsigned long arg);
同时在main.c中将int scull_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg);
修改为
long scull_ioctl(struct file *filp,unsigned int cmd, unsigned long arg);

4、/usr/src/linux-source-3.2.0/drivers/scull/main.c:655:3: 错误: 隐式声明函数‘init_MUTEX’ [-Werror=implicit-function-declaration]
cc1: some warnings being treated as errors

2.6.25及以后的linux内核版本废除了init_MUTEX函数

新版本使用sema_init函数

平台:X86 32位

内核:2.6.24

定义

点击(此处)折叠或打开

  1. static inline void init_MUTEX (struct semaphore *sem)
  2.     {
  3.             sema_init(sem, 1);
  4.     }

说明Init_MUTEX()函数初始化信号量为互斥量。 互斥量为信号量的特例,它可以防止数据被两个不同系统调用读写。

sema_init (sem, 1) 定义为:
点击(此处)折叠或打开

  1. static inline void sema_init (struct semaphore *sem, int val)
  2. {
  3. /*
  4. * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  5. *
  6. * i'd rather use the more flexible initialization above, but sadly
  7. * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
  8. */
  9.     atomic_set(&sem->count, val);
  10.     sem->sleepers = 0;
  11.     init_waitqueue_head(&sem->wait);
  12. }


sleepers : 指定了允许进入等待进入临界区的进程数,这里初始化为 0 。
init_waitqueue_head() : 初始化一个等待队列头。

这样不难得出,废除init_MUTEX 后,将原来使用init_MUTEX(sem)的地方统统替换为sema_init(sem,1);即可

5、/usr/src/linux-source-3.2.0/drivers/scull/pipe.c:131:7: 错误: ‘TASK_INTERRUPTIBLE’未声明(在此函数内第一次使用)
出现TASK_INTERRUPTIBLE未定义,这个定义现在在linux/sched.h中,将用到该预定义的文件中加入#include 文件;

6、/usr/src/linux-source-3.2.0/drivers/scull/access.c:98:34: 错误: ‘SPIN_LOCK_UNLOCKED’未声明(不在函数内)
将static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;

改为static DEFINE_SPINLOCK(scull_u_lock);

7、/usr/src/linux-source-3.2.0/drivers/scull/access.c:107:29: 错误: 提领指向不完全类型的指针

解决办法是在access.c中就加入两个头文件 #include

8、/usr/src/linux-source-3.2.0/drivers/scull/access.c:109:29: 错误: ‘struct task_struct’没有名为‘uid’的成员

/usr/src/linux-source-3.2.0/drivers/scull/access.c:110:29: 错误: ‘struct task_struct’没有名为‘euid’的成员

current->uid 修改为 current->cred->uid                     current->euid 修改为 current->cred->euid

上一篇:全局变量赋初值和不赋初值保存的地方有什么区别?
下一篇:没有了