当前位置: 首页 > news >正文

linux 解压oracle提示write error_Linux驱动程序学习二 (续) scull 源码在内核5.4.0上的编译调试...

LINUX设备驱动程序》第三章提供了源码scull,但是由于我用的是5.4.0内核,书中的是2.6.10内核,内核发生了很大的变化,因此编译scull源码花费了不少时间,下面是编译调试记录。(这个编译调试记录应该是目前网络上适应内核版本最高的,所以也希望给近期加入《LINUX设备驱动程序》学习的小白们一个参考)。

一、main.c

1、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’ [-Werror=implicit-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’ [-Werror=implicit-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 2
   err = !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 2
   err =  !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

得到以下提示:

89039e915c020822cca7d6e9062f9066.png

从提示看到新的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.4'
  CC [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 [-Werror=designated-init]
  .ioctl =    scull_ioctl,

ioctl是未知域,同样检索ioctl

find /lib/modules/5.4.0/build/include/linux  -type f -exec grep "ioctl" {} ; -print

得到(在/lib/modules/5.4.0/build/include/linux/fs.h)

879688c93399f1d9764b649b943a3f4a.png
	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);   // 5.4.0
        int (*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 改为long,struct 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’ [-Werror=implicit-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.h

static inline void sema_init(struct semaphore *sem, int val)

pipe.c

1:init_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’ [-Werror=implicit-function-declaration]
   if (signal_pending(current))

从错误代码查找关键词signal_pending的定义:

查找命令

find /lib/modules/5.4.0/build/include/linux -name '*.h' | xargs grep -w "signal_pending"

得到如下信息:

valian@valian-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.h>

access.c

1、.ioctl 错误,参考上面的改正方法。

2、init_MUTEX

init_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_struct

find /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.h

struct task_struct {
...........
}
/lib/modules/5.4.0/build/include/linux/sched.h

但是查找sched.h中struct task_struct的定义,没有找到“uid,euid”。网络搜寻得知新的struct taskstruct 定义有变化,uid和euid在cred结构体中(在头文件/lib/modules/5.4.0/build/include/linux/cred.h中)。如下图找到uid,euid,其类型为kuid_t

bff7e8404aeb500b92961d38d5cf67c8.png

在</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->uid,current->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上编译通过。

相关文章:

  • SharePoint Services和SharePoint Portal Server的主要功能
  • mysql中的date_MySql Date函数
  • mysql innodb 文件备份_MySQL物理备份
  • SharePoint Portal Server与SharePoint Services的关系
  • mysql 查找中位数_MYSQL 取中位数
  • python中声明变量注意事项_我们如何在Python中声明变量?
  • 配置SharePoint门户网站的基本思路
  • mysql批量更新查询某个字段_Mysql批量更新某个字段
  • mysql数据库的远程访问_Mysql 数据库 远程连接
  • 分形艺术
  • 绘制恒线速度的参数曲线
  • hibernate mysql sequence_hibernate 在mysql数据库上,利用sequence生成主键的另一种解决方法...
  • 抱SQL SERVER大腿之从巨大表中提炼非重复数据
  • 抱SQL SERVER大腿之我爱用视图
  • python初学往哪个方向比较容易_学习Python应该往哪个方向发展?
  • [译] React v16.8: 含有Hooks的版本
  • 2017届校招提前批面试回顾
  • Bytom交易说明(账户管理模式)
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • crontab执行失败的多种原因
  • Cumulo 的 ClojureScript 模块已经成型
  • input的行数自动增减
  • Linux下的乱码问题
  • Linux中的硬链接与软链接
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Python socket服务器端、客户端传送信息
  • vue学习系列(二)vue-cli
  • 扑朔迷离的属性和特性【彻底弄清】
  • 算法-图和图算法
  • 我的业余项目总结
  • 移动端唤起键盘时取消position:fixed定位
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 译自由幺半群
  • ​queue --- 一个同步的队列类​
  • ​比特币大跌的 2 个原因
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #define
  • #pragam once 和 #ifndef 预编译头
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • ${factoryList }后面有空格不影响
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (六)软件测试分工
  • (五)关系数据库标准语言SQL
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .Family_物联网
  • .net core使用ef 6
  • .Net 路由处理厉害了
  • .NET 中 GetProcess 相关方法的性能
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递