企业网站托管公司,网站建设费用价格明细表,学做网站初入门教程,灰色词快速排名方法《LINUX设备驱动程序》第三章提供了源码scull,但是由于我用的是5.4.0内核,书中的是2.6.10内核,内核发生了很大的变化,因此编译scull源码花费了不少时间,下面是编译调试记录。#xff08;这个编译调试记录应该是目前网络上适应内核版本最高的#xff0c;所以也希望给近期加入《…《LINUX设备驱动程序》第三章提供了源码scull,但是由于我用的是5.4.0内核,书中的是2.6.10内核,内核发生了很大的变化,因此编译scull源码花费了不少时间,下面是编译调试记录。这个编译调试记录应该是目前网络上适应内核版本最高的所以也希望给近期加入《LINUX设备驱动程序》学习的小白们一个参考)。一、main.c1、make出现以下两个错误:/home/valian/scull/main.c:17:26: fatal error: linux/config.h: 没有那个文件或目录
/home/valian/scull/main.c:32:46: fatal error: asm/system.h: 没有那个文件或目录直接在main.c中删除这两个头文件.在新的内核里弃用了这两个.2、copy_to_user copy_from_user/home/valian/scull/main.c:324:6: error: implicit declaration of function ‘copy_to_user’ [-Werrorimplicit-function-declaration]if (copy_to_user(buf, dptr-data[s_pos] q_pos, count)) {^
/home/valian/scull/main.c: In function ‘scull_write’:
/home/valian/scull/main.c:373:6: error: implicit declaration of function ‘copy_from_user’ [-Werrorimplicit-function-declaration]if (copy_from_user(dptr-data[s_pos]q_pos, buf, count)) {新内核修改了这两个函数名称更改如下copy_to_user()改为raw_copy_to_user();
copy_from_user()改为raw_copy_from_user();
3、access_ok /home/valian/scull/main.c:414:68: error: macro access_ok passed 3 arguments, but takes just 2err !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));^
/home/valian/scull/main.c:414:10: error: ‘access_ok’ undeclared (first use in this function)err !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));^
/home/valian/scull/main.c:414:10: note: each undeclared identifier is reported only once for each function it appears in
/home/valian/scull/main.c:416:68: error: macro access_ok passed 3 arguments, but takes just 2err !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));从错误提示看大概是新内核的access_ok的参数为2个但是原来内核为3个。通过以下指令在源码中查找access的出出处find /lib/modules/5.4.0/build/include/linux -type f -exec grep access_ok {} ; -print得到以下提示从提示看到新的access_ok的参数为(ptr,len),于是修改代码如下err !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
err !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
改为err !access_ok((void __user *)arg, _IOC_SIZE(cmd));4 、.ioctl 可参考CSDN-专业IT技术社区-登录make -C /lib/modules/5.4.0/build M/home/valian/scull LDDINC/home/valian/scull/../include modules
make[1]: Entering directory /usr/src/linux-5.4CC [M] /home/valian/scull/main.o
/home/valian/scull/main.c:558:2: error: unknown field ‘ioctl’ specified in initializer.ioctl scull_ioctl,^
/home/valian/scull/main.c:558:14: error: positional initialization of field in ‘struct’ declared with ‘designated_init’ attribute [-Werrordesignated-init].ioctl scull_ioctl,ioctl是未知域同样检索ioctlfind /lib/modules/5.4.0/build/include/linux -type f -exec grep ioctl {} ; -print得到在/lib/modules/5.4.0/build/include/linux/fs.h long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); // 5.4.0int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long); // 2.6.10 网络上查找对比发现.ioctl变为.unlocked_ioctl函数指针的原型也变了少了struct inode * 这个指针参数而且函数类型也由int变为long。修改如下;.ioctl scull_ioctl改为 .unlocked_ioctl scull_ioctl;函数scull_ioctl改为(main.c 和scull.h)long scull_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); // int 改为longstruct inode* 删除 5、init_MUTEX/home/valian/scull/main.c: In function ‘scull_init_module’:
/home/valian/scull/main.c:653:3: error: implicit declaration of function ‘init_MUTEX’ [-Werrorimplicit-function-declaration]init_MUTEX(scull_devices[i].sem); 通过以下命令find /lib/modules/5.4.0/build/include/linux -type f -exec grep init_MUTEX {} ; -print 查找结果没有找到应该是这个函数名称被弃用。在网络中找到解决方法init_MUTEX(sem)被sema_init(sem,1)替换了。init_MUTEX(scull_devices[i].sem); 改为sema_init((scull_devices[i].sem),1);sema_init的定义可参考/lib/modules/5.4.0/build/include/linux/semaphore.hstatic inline void sema_init(struct semaphore *sem, int val)pipe.c1init_MUTEX同main.c,init_MUTEX改为sema_init;//init_MUTEX(scull_p_devices[i].sem);
sema_init((scull_p_devices[i].sem),1);2、signal_pending/home/valian/scull/pipe.c: In function ‘scull_getwritespace’:
/home/valian/scull/pipe.c:172:7: error: implicit declaration of function ‘signal_pending’ [-Werrorimplicit-function-declaration]if (signal_pending(current))从错误代码查找关键词signal_pending的定义查找命令find /lib/modules/5.4.0/build/include/linux -name *.h | xargs grep -w signal_pending得到如下信息valianvalian-TM1703:~/scull$ find /lib/modules/5.4.0/build/include/linux -name *.h | xargs grep -w signal_pending
/lib/modules/5.4.0/build/include/linux/sched/signal.h:static inline int signal_pending(struct task_struct *p)从signal_pending定义看函数参数没有改变但是没有包含/linux/sched/signal.h头文件。加上头文件#include linux/sched/signal.haccess.c1、.ioctl 错误参考上面的改正方法。2、init_MUTEXinit_MUTEX((lptr-device.sem));改为sema_init((lptr-device.sem),1);3、SPIN_LOCK_UNLOCKED/home/valian/scull/access.c:98:34: error: ‘SPIN_LOCK_UNLOCKED’ undeclared here (not in a function)static spinlock_t scull_u_lock SPIN_LOCK_UNLOCKED;
从提示看没有定义。查找关键词find /lib/modules/5.4.0/build/include/linux -type f -exec grep SPIN_LOCK_UNLOCKED {} ; -print 得到以下信息#define DEFINE_SPINLOCK(x) spinlock_t x __SPIN_LOCK_UNLOCKED(x)
/lib/modules/5.4.0/build/include/linux/spinlock_types.h根据以上信息与源码中“static spinlock_t scull_u_lock SPIN_LOCK_UNLOCKED;”对比发现宏定义 DEFINESPINLOCK(x) 代替了源码中spinlock_t scull_u_lock SPIN_LOCK_UNLOCKED。因此按以下修改即可。//static spinlock_t scull_u_lock SPIN_LOCK_UNLOCKED;
//static spinlock_t scull_c_lock SPIN_LOCK_UNLOCKED;
//static spinlock_t scull_w_lock SPIN_LOCK_UNLOCKED;static DEFINE_SPINLOCK(scull_u_lock) ;static DEFINE_SPINLOCK(scull_c_lock) ;static DEFINE_SPINLOCK(scull_w_lock) ;4、uid euid/home/valian/scull/access.c:108:29: error: ‘struct task_struct’ has no member named ‘uid’(scull_u_owner ! current-uid) /* allow user */^
/home/valian/scull/access.c:109:29: error: ‘struct task_struct’ has no member named ‘euid’(scull_u_owner ! current-euid) /* allow whoever did su */查找关键词struct task_structfind /lib/modules/5.4.0/build/include/linux -type f -exec grep struct task_struct {} ; -print众多信息中找到定义在/lib/modules/5.4.0/build/include/linux/sched.hstruct task_struct {
...........
}
/lib/modules/5.4.0/build/include/linux/sched.h但是查找sched.h中struct task_struct的定义没有找到“uideuid”。网络搜寻得知新的struct taskstruct 定义有变化uid和euid在cred结构体中(在头文件/lib/modules/5.4.0/build/include/linux/cred.h中)。如下图找到uideuid其类型为kuid_t。 在/lib/modules/5.4.0/build/include/linux/uidgid.h中查到kuid_t为结构体类型定义如下:typedef struct {uid_t val;
} kuid_t; access.c中scull_u_owner的类型为static uid_t scull_u_owner。因此需要修改代码如下: current-uid改为current-cred-uidcurrent-euid改为current-cred-euid //scull_w_owner current-uid ||
//scull_w_owner current-euid ||
改为
scull_w_owner current-cred-uid.val ||
scull_w_owner current-cred-euid.val ||// (scull_u_owner ! current-uid) /* allow user */
// (scull_u_owner ! current-euid) /* allow whoever did su */
改为(scull_u_owner ! current-cred-uid.val) /* allow user */(scull_u_owner ! current-cred-euid.val) /* allow whoever did su */
过程中出现以下错误可参考[PATCH 0/5] PMFS: Rebase to Linux 3.9 /home/valian/SLAM/linux/scull/access.c:115:19: error: invalid operands to binary ! (have ‘uid_t {aka unsigned int}’ and ‘kuid_t {aka const struct anonymous}’)(scull_u_owner ! current-cred-uid) /* allow user */^
/home/valian/SLAM/linux/scull/access.c:116:19: error: invalid operands to binary ! (have ‘uid_t {aka unsigned int}’ and ‘kuid_t {aka const struct anonymous}’)(scull_u_owner ! current-cred-euid) /* allow whoever did su */ 5、struct signal_struct/home/valian/SLAM/linux/scull/access.c:283:22: error: dereferencing pointer to incomplete type ‘struct signal_struct’if (!current-signal-tty) { 错误提示可能是没有声明对应结构体定义的头文件。查找struct signal_struct的定义:find /lib/modules/5.4.0/build/include/linux -type f -exec grep struct signal_struct {} ; -print得到以下结果,在/lib/modules/5.4.0/build/include/linux/sched/signal.h。struct signal_struct {
static inline void signal_set_stop_flags(struct signal_struct *sig,
static inline int signal_group_exit(const struct signal_struct *sig)
/lib/modules/5.4.0/build/include/linux/sched/signal.h在assess.c中加上头文件;#include linux/sched/signal.h至此scull源码在内核linux5.4.0上编译通过。