兴趣是最好的学习契机!
全部博文(127)
分类: LINUX
2014-06-27 14:53:11
解决办法:在access.c中添加 #include
今天试着编译LDD3例子源代码中的scull模块,出现了问题
参照下面的文章解决了问题:http://blog.163.com/chenfang7977@yeah/blog/static/1282741962010219327201/
内核版本:2.6.27
1、提示scripts/Makefile.build:46:*** CFLAGS was changed in "/home/chenfang/scull/Makefile",Fix it use EXTRA_CFLAGS.Stop.:
由于LDD3使用的是2.6.10内核,很多东西已经发生了变化,这里提示我们修改Makefile中的CFLAGS,用EXTRA_CFLAGS代替,照它说的做就可以。
2、提示找不到文件linux/config.h:
在2.6.19开始的内核中删除了config.h文件,因此只要在mian.c中注释掉#include
3、提示access.c中存在:dereferencing pointer to incomplete type 错误:
在 源码中发现只能是current存在错误,current应该是一个task_struct类型的全局变量,查找task_struct存在于 linux/sched.h中,因此在access.c中加入#include
顺便看下current这个全局变量是在哪里定义的:
在source ininsight中查找得到的current类似于以下的定义:
static inline struct task_struct *get_current(void) __attribute_const__;
static inline struct task_struct *get_current(void)
{
return current_thread_info()->task;
}
#define current (get_current())
可 见,current其实是一个“伪全局变量”,是函数get_current()的宏定义。当access.c中使用current->uid时, 就调用了get_current()函数,从而返回task_struct结构的task,因此current->uid就相当于 task->uid。
make成功后,在scull目录下生成了scull.ko文件,命令:chomd +x scull_load scull_unload 使这两个脚本变为可执行。
./scull_load 挂载scull.ko模块
./scull_unload 卸载
scull_load脚本是对insmod的调用,该脚本在调用insmod之后读取/proc/devices以获得新分配的主设备号,然后创建对应的设备文件。
$DEVICE.ko以下是我的实践收获:
另外,scull例子源码目录中还提供了一个脚本scull.init可以完成,scull_load 和scull_unload 的工作。
直接运行这个脚本sudo ./scull.init start会提示失败:
Loading scull (loading file ./scull.o)insmod: error inserting './scull.o': -1 Invalid module format
FAILED!
.
回到scull.init中把 $DEVICE.o改成$DEVICE.ko即可。
ps;前面定义了DEVECE=scull
error :implicit declaration of function 'init_MUTEX'
后来一查,在新版本的linux内核中,init_mutex已经被废除了。
查了一下早期版本的定义。
平台:X86 32位
内核:2.6.24
定义:
static inline void init_MUTEX (struct semaphore *sem)
{
sema_init(sem, 1);
}
说明:Init_MUTEX()函数初始化信号量为互斥量。 互斥量为信号量的特例,它可以防止数据被两个不同系统调用读写。
static inline void sema_init (struct semaphore *sem, int val)
{
/*
* *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
*
* i'd rather use the more flexible initialization above, but sadly
* GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
*/
atomic_set(&sem->count, val);
sem->sleepers = 0;
init_waitqueue_head(&sem->wait);
}
sleepers : 指定了允许进入等待进入临界区的进程数,这里初始化为 0 。
init_waitqueue_head() : 初始化一个等待队列头。
根据代码判断,只要在init_mutex的地方直接使用sema_init来替换,试了一些,果然可以成功make。
代码大概是这样的init_MUTEX(&wl->sem); 手动修改为 sema_init(&wl->sem,1); 然后再进行编译就可以。
1、提示scripts/Makefile.build:46:*** CFLAGS was changed in "/home/chenfang/scull/Makefile",Fix it use EXTRA_CFLAGS.Stop.:
由于LDD3使用的是2.6.10内核,很多东西已经发生了变化,这里提示我们修改Makefile中的CFLAGS,用EXTRA_CFLAGS代替,照它说的做就可以。
2、提示找不到文件linux/config.h:
在2.6.19开始的内核中删除了config.h文件,因此只要在mian.c中注释掉#include
3、提示access.c中存在:dereferencing pointer to incomplete type 错误:
在 源码中发现只能是current存在错误,current应该是一个task_struct类型的全局变量,查找task_struct存在于 linux/sched.h中,因此在access.c中加入#include
顺便看下current这个全局变量是在哪里定义的:
在source ininsight中查找得到的current类似于以下的定义:
static inline struct task_struct *get_current(void) __attribute_const__;
static inline struct task_struct *get_current(void)
{
return current_thread_info()->task;
}
#define current (get_current())
可 见,current其实是一个“伪全局变量”,是函数get_current()的宏定义。当access.c中使用current->uid时, 就调用了get_current()函数,从而返回task_struct结构的task,因此current->uid就相当于 task->uid。
之前在里编译scull时有错误,还好有网友提供了解决办法,即删除config.h文件和增加#include 两个头文件:capability.h和sched.h
最近将升级到9.10版本后,重新生成了2.6.31版本的内核树,没想到编译scull模块时出现新的
/home/dengwei/eclipse_workspace/scull/access.c:108: error: ‘struct task_struct’ has no member named ‘uid’
/home/dengwei/eclipse_workspace/scull/access.c:109: error: ‘struct task_struct’ has no member named ‘euid’
/home/dengwei/eclipse_workspace/scull/access.c:116: error: ‘struct task_struct’ has no member named ‘uid’
/home/dengwei/eclipse_workspace/scull/access.c: In function ‘scull_w_available’:
/home/dengwei/eclipse_workspace/scull/access.c:167: error: ‘struct task_struct’ has no member named ‘uid’
/home/dengwei/eclipse_workspace/scull/access.c:168: error: ‘struct task_struct’ has no member named ‘euid’
/home/dengwei/eclipse_workspace/scull/access.c: In function ‘scull_w_open’:
/home/dengwei/eclipse_workspace/scull/access.c:186: error: ‘struct task_struct’ has no member named ‘uid’
原因:
struct task_struct定义在include/linux/sched.h中,原来task_struct结构体定义有所改动,将uid和euid等挪到 cred中,见include/linux/sched.h和include/linux/cred.h。
解决方法:
只需要将报error的代码做如下修改
current->uid 修改为 current->cred->uid
current->euid 修改为 current->cred->euid
make success
结果:
root@dw:/home/dengwei/eclipse_workspace/scull# ls
access.c main.o Module.symvers scull.init scull.mod.o
access.o Makefile pipe.c scull.ko scull.o
_desktop.ini Module.markers pipe.o scull_load scull_unload
main.c modules.order scull.h scull.mod.c
root@dw:/home/dengwei/eclipse_workspace/scull# insmod scull.ko
按照上面提示,就可以顺利编译成ko文件,其中include/linux在我的Linux中绝对路径名是
/usr/src/linux-headers-2.6.32-21/include/linux
****************************************************************************
****************************************************************************
xx@xx-ubuntu:~/driver_dev/scull$ sudo ./scull_load
awk: 0: unexpected character '\'
awk: line 1: syntax error at or near ==
mknod: missing operand after `0'
Try `mknod --help' for more information.
mknod: missing operand after `1'
Try `mknod --help' for more information.
mknod: missing operand after `2'
Try `mknod --help' for more information.
mknod: missing operand after `3'
Try `mknod --help' for more information.
chgrp: cannot access `/dev/scull[0-3]': No such file or directory
chmod: cannot access `/dev/scull[0-3]': No such file or directory
mknod: missing operand after `4'
Try `mknod --help' for more information.
mknod: missing operand after `5'
Try `mknod --help' for more information.
mknod: missing operand after `6'
Try `mknod --help' for more information.
mknod: missing operand after `7'
Try `mknod --help' for more information.
chgrp: cannot access `/dev/scullpipe[0-3]': No such file or directory
chmod: cannot access `/dev/scullpipe[0-3]': No such file or directory
mknod: missing operand after `8'
Try `mknod --help' for more information.
chgrp: cannot access `/dev/scullsingle': No such file or directory
chmod: cannot access `/dev/scullsingle': No such file or directory
mknod: missing operand after `9'
Try `mknod --help' for more information.
chgrp: cannot access `/dev/sculluid': No such file or directory
chmod: cannot access `/dev/sculluid': No such file or directory
mknod: missing operand after `10'
Try `mknod --help' for more information.
chgrp: cannot access `/dev/scullwuid': No such file or directory
chmod: cannot access `/dev/scullwuid': No such file or directory
mknod: missing operand after `11'
Try `mknod --help' for more information.
chgrp: cannot access `/dev/scullpriv': No such file or directory
chmod: cannot access `/dev/scullpriv': No such file or direct
解决了。
1.要apt-get install gawk.ubuntu里面的awk行为有点诡异
2.把major=$(awk "\\$2==\"$module\" {print \\$1}" /proc/devices)
改为
major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)