今天对程序进行编译,结果出现
make -C /lib/modules/3.3.2-6.fc16.x86_64/build M=/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull LDDINC=/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/../include modules
make[1]: Entering directory `/usr/src/kernels/3.3.2-6.fc16.x86_64'
scripts/Makefile.build:49: *** CFLAGS was changed in "/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/Makefile". Fix it to use ccflags-y. Stop.
make[1]: *** [_module_/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull] Error 2
make[1]: Leaving directory `/usr/src/kernels/3.3.2-6.fc16.x86_64'
make: *** [modules] Error 2
vim /usr/src/kernels/3.3.2-6.fc16.x86_64/scripts/Makefile.build
第49行内容
# If the save-* variables changed error out
47 ifeq ($(KBUILD_NOPEDANTIC),)
48 ifneq ("$(save-cflags)","$(CFLAGS)")
49 $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
50 endif
51 endif
没有定义KBUILD_NOPEDANTIC,且修改了CFLAGS,导致编译不能继续。我想这里是开发者为了防止修改CFLAG进行的保护措施,解决办法可以在编译前定义KBUILD_NOPEDANTIC,export KBUILD_NOPEDANTIC=1或者修改Makefile中的CFLAGS为ccflags-y
继续编译,#include 出现include的linux下没有config.h这个文件
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/main.c:17:26: fatal error: linux/config.h: No such file or directory
把这个文件加上去就好了。现在较新的内核已经弃用了config.h。
sudo vim /usr/src/kernels/3.3.2-6.fc16.x86_64/include/linux/config.h
#ifndef _LINUX_CONFIG_H
#define _LINUX_CONFIG_H
#endif
OK!这个问题解决了。
接下来有出问题了
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/main.c:556:2: error: unknown field 'ioctl' specified in initializer
ioctl是未知域,查看file_operations结构体,在build/inlcude/linux/fs.h中的1603行定义,前面有两句话
/* These macros are for out of kernel modules to test that
* the kernel supports the unlocked_ioctl and compat_ioctl
* fields in struct file_operations. */
根据开发者的意见,ioctl使用了大内核锁,这个是不安全的,新的kerne将l不再支持ioctl方法,而应该使用 unlocked_ioctl或者compat_ioctl。修改main.c中556行的.ioctl为unlocked_ioctl,这个错误不会出现了。同时,这个函数指针的原型也改变了!
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
与原来的ioctl函数原型相比少传递了struct inode *inode 这个变量,因此我们的实现scull_ioctl需要变为
main.c
394 int scull_ioctl(struct file *filp,
395 unsigned int cmd, unsigned long arg)
scull.h
131 int scull_ioctl(struct file *filp,
132 unsigned int cmd, unsigned long arg);
接着,出现另外一个问题:
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/main.c:652:3: error: implicit declaration of function 'init_MUTEX
与前一个错误来源一样,init_MUTEX(&sem)在新内核里也被弃用了。用sema_init(&sem,1)进行替换可解决此问题。
好了,main.c的问题解决了,pipe.c编译的时候出现了一大堆问题了。
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:130:3: error: dereferencing pointer to incomplete type
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:131:7: error: 'TASK_INTERRUPTIBLE' undeclared (first use in this function)
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:131:7: note: each undeclared identifier is reported only once for each function it appears in
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:131:3: error: implicit declaration of function 'signal_pending' [-Werror=implicit-function-declaration]
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:131:3: error: implicit declaration of function 'schedule' [-Werror=implicit-function-declaration]
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:153:2: error: dereferencing pointer to incomplete type
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c: In function 'scull_getwritespace':
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:167:3: error: dereferencing pointer to incomplete type
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:168:38: error: 'TASK_INTERRUPTIBLE' undeclared (first use in this function)
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c: In function 'scull_p_write':
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:219:2: error: 'TASK_INTERRUPTIBLE' undeclared (first use in this function)
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:223:34: error: 'SIGIO' undeclared (first use in this function)
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:223:41: error: 'POLL_IN' undeclared (first use in this function)
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:224:2: error: dereferencing pointer to incomplete type
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c: At top level:
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:319:2: warning: initialization from incompatible pointer type [enabled by default]
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/pipe.c:319:2: warning: (near initialization for 'scull_pipe_fops.unlocked_ioctl') [enabled by default]
cc1: some warnings being treated as errors
太吓人了,不过仔细看这些错误,大部分都是类型未定义,怎么办?我们可以用命令在 /lib/modules/$(uname -r)/build/include/linux 文件夹下搜搜
find ./ -type f -exec grep "TASK_INTERRUPTIBLE" {} \; -print
结果显示
#define TASK_INTERRUPTIBLE 1
#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
#define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \
if (!(state & (TASK_INTERRUPTIBLE | TASK_WAKEKILL)))
return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p);
./sched.h
原来改到了在sched.h中定义了。把这个头文件加到pipe.c中
#include
再编译,发现access.c也出现跟pipe.c一样的问题,再把sched.h添加进去。
还是出现问题:
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/access.c:99:34: error: 'SPIN_LOCK_UNLOCKED' undeclared here (not in a function)
原因,SPIN_LOCK_UNLOCKED在新内核中被弃用,用新内核编译的人伤不起阿!解决办法,添加头文件
#include
修改定义
static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;
为
static DEFINE_SPINLOCK(scull_u_lock);
问题:
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/access.c:107:29: error: 'struct task_struct' has no member named 'uid'
/home/jqzeng/workSpace/ldd3/ldd3-samples-1.0.0/scull/access.c:108:29: error: 'struct task_struct' has no member named 'euid'
原因:新的struct task_struct 定义有变化,uid和euid在cred结构体中。
解决办法:加头文件cred.h,将 current->uid改为current->cred->uid,current->euid改为current->cred->euid
#include
108 if (scull_u_count &&
109 (scull_u_owner != current->cred->uid) && /* allow user */
110 (scull_u_owner != current->cred->euid) && /* allow whoever did su */
...
117 scull_u_owner = current->cred->uid; /* grab it */
好了。接下来access.c还会出现一大帮的问题,不过都是前面出现的,只要按照前面的方法修改,最终就可以通过编译!