Linux 2.6.36以后file_operations和DECLARE_MUTEX 的变化

“asm/semaphore.h: No such file or directory” 今天编译发现一个error: “asm/semaphore.h: No such file or directory” ,发现2.6.19和2.6.31对这个信号量声明并不相同 [patch] include linux/semaphore.h for kernel 2.6 阅读详情
今天尝试移植了2.6.38的内核到AT91SAM9260上,在编译驱动时发现从2.6.36的内核开始,include/linux/semaphore.h 和 include/linux/fs.h中有了两处变化与驱动相关:

1, 在include/linux/semaphore.h 中

将#define DECLARE_MUTEX(name)   改成了 #define DEFINE_SEMAPHORE(name) 

 

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)

DECLARE_MUTEX(led_sem);

#else

DEFINE_SEMAPHORE(led_sem);

#endif

 

2,usb_buffer_alloc 和 usb_buffer_free 

在linux2.6.34和之前的代码中还可以使用usb_buffer_alloc 和 usb_buffer_free 这两个函数,在2.6.35和之后的内核中
usb_buffer_alloc 和 usb_buffer_free这两个函数已不在使用了,可以用usb_alloc_coherent 和 usb_free_coherent代替。


3, file_operations结构体有了一些变化,它去掉了:

  int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

另外添加了:

    long (*fallocate)(struct file *file, int mode, loff_t offset,loff_t len);


这是2.6.36的内核里的定义include/linux/fs.h:

struct file_operations {

    struct module *owner;

    loff_t (*llseek) (struct file *, loff_t, int);

    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

    int (*readdir) (struct file *, void *, filldir_t);

    unsigned int (*poll) (struct file *, struct poll_table_struct *);

  //从2.6.36开始删除ioctl(), 2.6.35中有

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

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

    int (*mmap) (struct file *, struct vm_area_struct *);

    int (*open) (struct inode *, struct file *);

    int (*flush) (struct file *, fl_owner_t id);

    int (*release) (struct inode *, struct file *);

    int (*fsync) (struct file *, int datasync);

    int (*aio_fsync) (struct kiocb *, int datasync);

    int (*fasync) (int, struct file *, int);

    int (*lock) (struct file *, int, struct file_lock *);

    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

    int (*check_flags)(int);

    int (*flock) (struct file *, int, struct file_lock *);

    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);

    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);

    int (*setlease)(struct file *, long, struct file_lock **);

//    long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);  从2.6.38内核开始添加该项,2.6.37以下无

};


下面是Linux-2.6.35里的file_operations

struct file_operations {

    struct module *owner;

    loff_t (*llseek) (struct file *, loff_t, int);

    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);

    int (*readdir) (struct file *, void *, filldir_t);

    unsigned int (*poll) (struct file *, struct poll_table_struct *);

    int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

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

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

    int (*mmap) (struct file *, struct vm_area_struct *);

    int (*open) (struct inode *, struct file *);

    int (*flush) (struct file *, fl_owner_t id);

    int (*release) (struct inode *, struct file *);

    int (*fsync) (struct file *, struct dentry *, int datasync);

    int (*aio_fsync) (struct kiocb *, int datasync);

    int (*fasync) (int, struct file *, int);

    int (*lock) (struct file *, int, struct file_lock *);

    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

    int (*check_flags)(int);

    int (*flock) (struct file *, int, struct file_lock *);

    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);

    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);

    int (*setlease)(struct file *, long, struct file_lock **);

};


[guowenxue@localhost at91sam9260]$ make

make[1]: Entering directory `/usr/.devices_group/guowenxue/l350-dev06/src/kernel/linux-2.6.38'

  CC [M]  /usr/.devices_group/guowenxue/embedded_project/drivers/at91sam9260/dev_skeleton.o

/usr/.devices_group/guowenxue/embedded_project/drivers/at91sam9260/dev_skeleton.c:93: error: unknown field 'ioctl' specified in initializer

/usr/.devices_group/guowenxue/embedded_project/drivers/at91sam9260/dev_skeleton.c:93: warning: initialization from incompatible pointer type

make[2]: *** [/usr/.devices_group/guowenxue/embedded_project/drivers/at91sam9260/dev_skeleton.o] Error 1

make[1]: *** [_module_/usr/.devices_group/guowenxue/embedded_project/drivers/at91sam9260] Error 2

make[1]: Leaving directory `/usr/.devices_group/guowenxue/l350-dev06/src/kernel/linux-2.6.38'

make: *** [modules] Error 2


参考别的字符设备的驱动drivers/char/ppdev.c:

static const struct file_operations pp_fops = {

    .owner      = THIS_MODULE,

    .llseek     = no_llseek,

    .read       = pp_read,

    .write      = pp_write,

    .poll       = pp_poll,

    .unlocked_ioctl = pp_ioctl,

    .open       = pp_open,

    .release    = pp_release,

};

这里ioctl()已使用unlocked_ioctl代替。


但这里不是一个简单的替换,要注意unlocked_ioctl和ioctl的函数原型并不一致。

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

               ioctl: int(*ioctl) (struct inode *,struct file *, unsigned int, unsigned long);

    The 'inode' value that was passed to 'ioctl' function is available for use with the 'unlocked_ioctl' function by way of filp->d_entry->d_inode:

    long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long arg);
    ...
    struct inode *inode = filp->f_path.dentry->d_inode

There is a nice explanation of this at http://lwn.net/Articles/119652/


如:

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

{

    int  index = iminor(file->f_path.dentry->d_inode); /* Which Channel*/

   .....

}

--------------------------------------

在file_operations 结构体中,会看到许多函数指针所指向的函数都必须传进struct file 结构体指针struct file * 作为参数。struct file 结构体定义在<linux/fs.h> 中,完整如下:

引用

struct file {
       
        union {
               struct list_head        fu_list;
               struct rcu_head        fu_rcuhead;
        } f_u;
        struct path             f_path;
#define f_dentry        f_path.dentry
#define f_vfsmnt        f_path.mnt
        const struct file_operations    *f_op;
        spinlock_t             f_lock;
        atomic_long_t           f_count;
        unsigned int           f_flags;
        fmode_t                f_mode;
        loff_t                 f_pos;
        struct fown_struct      f_owner;
        const struct cred       *f_cred;
        struct file_ra_state    f_ra;

        u64                    f_version;
#ifdef CONFIG_SECURITY
        void                   *f_security;
#endif
       
        void                   *private_data;

#ifdef CONFIG_EPOLL
       
        struct list_head        f_ep_links;
#endif
        struct address_space    *f_mapping;
#ifdef CONFIG_DEBUG_WRITECOUNT
        unsigned long f_mnt_write_state;
#endif
};


在设备驱动中,struct file 结构体也是一个非常重要的数据结构。注意的是,这里的file 和应用程序中的FILE 流指针没有什么关系,FILE 定义在C 库中,它永远不会出现在内核代码中。

file structure 结构代表一个打开的文件(open file).(打开的文件并没有确切的指定到哪个设备驱动,实际上每个打开的文件都与内核空间中的struct file 结构相关联)。

file structure 结构在调用open 打开一个文件时由内核创建,并会被传递给任一个对这个打开文件进行操作的函数;当所有事情都做完后,会调用close() 关闭掉文件,此时内核释放这个数据结构。

一般地,在内核源码中,struct file 结构体的指针往往写成filp 。

struct file 中的几个重要成员:

mode_t f_mode;
文件模式根据FMMODE_READ 和FMODE_WRITE 位来识别文件是否可读或可写,或是可读可写。在read() 和write() 系统调用中,没有必要对此权限进行检查,因为内核已经在你的系统调用之前已经做了检查。如果文件没有相应的读或写权限,那么如果尝试读写都将被拒绝,驱动程序甚至对此情况毫无知觉。

loff_t f_pos;
此变量表示当前的文件读写位置。loff_t 在所有的平台上都是64 位的变量( long long 型, gcc 专用术语)。驱动程序如果想知道当前在文件中所处位置,那么可以通过读取此变量得知,但是一般地不应直接对此进行更改。通过llseek() 方法可以改变文件位置。

unsigned int f_flags;
这是表示如O_RDONLY, O_NONBLOCK与O_SYNC 这样的标志。一个驱动程序应该检查O_NONBLOCK 标志,以查看是否有非阻塞操作的请求。其它的标志用得比较少。需要注意的是,检查read/write 权限应该是通过检查f_mode 得到而不是f_flags 。所有的标志定义在头文件linux/fcntl.h 中可以看到。

struct file_operations*f_op;
内核安排这个指针作为它的open 实现的一部分,当需要分派什么操作时,会读取它。filp->f_op 因为不会被内核保存起来以在其后之用,所以我们可以改变我们对相关文件的操作,在对文件使用新的操作方法时,我们就会转移到相应调用上。

void *private_data;
在对驱动调用open 方法之前,open() 系统调用会这个指针设置为NULL 。用户可以自由使用这个域,或者对其忽略。可以使用这个域之想分配的数据空间,但必须记得在内核销毁file structure 之前在release 方法里释放掉原来分配的内存。private_data 对于系统调用之间信息的保存会显得非常有用。

struct dentry*f_dentry;
目录入口(dentry) 结构与文件相关。一般的,除了在以filp->f_dentry->d_inode 来访问inode 结构时,我们不太关心dentry 这个结构。

 

====

http://hi.baidu.com/kkernel/item/ea0ae8f4abb46929743c4c96

arm_linux-2.6.21_s3c2440.rar_ARM Linux S3C2440_CAH_SCSI ATN_arm- linux-2.6.21 内核 基于arm_s3c2440 立即下载

相关推荐

postgresql 数据库 timescaledb 函数time_bucket_gapfill()报错解决及更换 license

最近在工作中使用postgresql 和 timescaledb 的time_bucket_gapfill()函数 报错,让更换license,在网上找了一大圈,没有找到,最后解决了这个问题,这篇文章记录我的解决办法查看timescaledb.license参数命令:show timescaledb.license;修改命令: 结果不行,报错如下:lter system set timescaledb.license=‘timescale’;那只能换包了如果出现上面那种情况,那我们只能先从官网上下载带 '

yang_z_1的博客 3249

at91sam9260官方BSP下载地址

http://www.at91.com/windows4sam/bin/view/Windows4SAM/WindowsEmbeddedCEBSP Windows4SAM » WebHome » WindowsEmbeddedCEBSP Windows Embedded CE BSP  Introduction

gooogleman#foxmail.com 5169

B站李沐讲论文笔记AlexNet

B站李沐讲论文笔记AlexNet

夏知识不进脑子薇的博客 789

Linux 2.6.36以后file_operations和DECLARE_MUTEX 和kmem_cache_create的变化

<br />今天尝试在2.6.39内核上编译一个驱动, 在编译驱动时发现从2.6.36的内核开始,include/linux/semaphore.h 和 include/linux/fs.h中有了两处变化与驱动相关:<br /> <br />1, 在include/linux/semaphore.h 中<br />在编译阶段初始化的变化:<br />将#define DECLARE_MUTEX(name)   改成了 #define DEFINE_SEMAPHORE(name) <br /> <br />#

yhguo2008的专栏 2271

浏览器主页被360篡改?教你彻底解决并预防再次发生

通过本文介绍的快捷方式修复、注册表清理、启动项管理三步法,可解决99%的浏览器主页篡改问题。权限最小化原则:非管理员账户日常使用,关键系统目录设置写保护定期安全审计:每月检查启动项/计划任务/浏览器扩展备份还原机制:创建系统还原点,重要操作前做好快照安全意识培养:不安装来源不明的软件,谨慎处理软件安装向导中的附加选项浏览器安全是系统防护的重要环节,建议结合EDR(终端检测与响应)方案构建立体防护体系。对于普通用户,保持系统更新、使用官方渠道下载软件、定期清理系统垃圾,即可有效预防绝大多数安全威胁。

nntxthml的博客 1万+

GIS小白也能看懂的实战:5步教你将ArcGIS里的等高线和水系完美导入CAD做规划图

本文详细介绍了如何将ArcGIS中的等高线和水系数据高效导入CAD,制作专业规划底图的5个关键步骤。从数据准备、ArcGIS处理到CAD优化,涵盖坐标系设置、数据裁剪、格式转换等实用技巧,特别适合设计规划领域的新手快速掌握GIS与CAD协同工作流程。

weixin_27966471的博客 425

DECLARE_MUTEX宏定义

Linux可以使用互斥信号量来表示互斥锁,那就是通过宏DECLARE_MUTEX来定义一个互斥信号量,因为DECLARE_MUTEX这个宏, Marcin Slusarz在08年提交的了一个patch,邮件地址为:https://lkml.org/lkml/2008/10/26/74,Marcin Slusarz认为DECLARE_MUTEX宏会误导开发者,所以建议将DECLARE_MUTEX修改...

wx601056818的博客 1107

使用VNC可视化Docker容器

Docker容器可视化

Robert_Q的博客 1万+

Linux内核当中的互斥锁

Linux可以使用互斥信号量来表示互斥锁,那就是通过宏DECLARE_MUTEX来定义一个互斥信号量,因为DECLARE_MUTEX这个宏,Marcin Slusarz在08年提交的了一个patch,邮件地址为:https://lkml.org/lkml/2008/10/26/74,Marcin Slusarz认为DECLARE_MUTEX宏会误导开发者,所以建议将DECLARE_MUTEX修改成

Tracy Mcgrady的专栏 1万+

栅格数据做相关性分析前的预处理(批量定义投影、栅格投影、重采样)

最近在做两个栅格数据的相关性分析,这个最主要的是两个栅格数的行列号是一致的(也就是说坐标系、分辨率一致),那么标准的栅格数据的分辨率是以米的形式存在的,但是有一些栅格数据是以度为单位存在的,所以在做分析前,一定要先把其转换为米,否则在重采样的时候就会出错。(相关文章——栅格数据以度为单位变为以米为单位的简单做法)当然,在变其分辨率的单位前,一定要将其坐标系转换为一致。所以就有以下的步骤(如何将两个栅格数据的坐标系、分辨率的单位和分辨率一致) 1.首先,要看两个栅格数据的坐标系是否一致,如果不一致,要先统一到

qq_41828818的博客 8350

Python爬虫实战:高德地图POI信息爬取(餐馆/加油站等),附选址分析技巧

高德API配置AMAP_KEY = "你的高德API Key" # 替换成自己的Key# 爬取参数CITY = "成都" # 城市DISTRICTS = ["锦江区"] # 区域,可添加多个(比如["锦江区", "武侯区"])KEYWORDS_LIST = ["川菜馆", "加油站"] # 要爬取的POI类型TYPES = {"川菜馆": "050101", # 餐饮服务→中餐→川菜馆(高德POI分类编码)"加油站": "110100" # 交通设施→加油站。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2467

hi3516v300gpio驱动编译遇到的问题2

1. /home/share/HI3516CV300/Hi3516CV300_SDK_V1.0.1.1/package/drv/extdrv/gpio/hi_gpio.c:50:24: fatal error: asm/system.h:没有那个文件或目录  #include                         ^ compilation terminated. make[2

MAKE_TROUBLE的专栏 850

科研神器: 用Gemini 3

Edge藏了个科研开挂神器!免TZ/免谷歌账号用Gemini 3,1分钟上手(附保姆级教程) 做科研查文献、理数据总卡壳?想蹭Gemini 3的AI能力,却被“谷歌账号+TZ+节点筛选”三连劝退? 现在不用折腾了!Edge浏览器里装个插件,直接把Gemini 3揣进口袋——**免翻墙、免谷歌账号、国内直接用**,分分钟让你的科研效率翻三倍,导师都得问你“偷偷开了啥挂”!

ZhangJiqun&191cm&85kg 1159

字符设备2.6.34源码移植5.0.0遇到的问题

<asm/system.h> //3.3.0版本以前 <asm/switch_to.h>//3.30版本以后 可用在同目录下创建version.h文件自动判断,在程序中添加version.h头文件即可。 #include <linux/version.h> #if LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0) #include <asm/seitch_to.h> #else #inclde &lt

u011053941的博客 169

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Linux 2.6.36以后file_operations…

今天尝试在2.6.39内核上编译一个驱动, 在编译驱动时发现从2.6.36的内核开始,include/linux/semaphore.h 和 include/linux/fs.h中有了两处变化与驱动相关:   1, 在include/linux/semaphore.h 中 在编译阶段初始化的变化: 将#define DECLARE_MUTEX(name)   改成了 #define DEFINE_

shangyaowei的专栏 372

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

由于linux内核变化导致的若干头文件出错问题

注:我也觉得,linux的好处是开源,坏处恰好也就是开源。 转:http://blog.csdn.net/jw212/article/details/6702152 原标题“asm/semaphore.h: No such file or directory” 今天编译发现一个error: “asm/semaphore.h: No such file or

CD_keanu的专栏 1194

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

内核中DEFINE_MUTEX DECLARE_MUTEX DEFINE_SEMAPHORE的区别

内核中DEFINE_MUTEX DECLARE_MUTEX DEFINE_SEMAPHORE的区别   DEFINE_MUTEX 以上是互斥锁包含在include/linux/mutex.h中;以下是信号量include/linux/semaphore.h,发生变化的是在semaphore.h从以下的Git的Log中就可以看出来。而mutex.h中始终都是DEFINE_MUTEX没有变的,所

Android/Linux的专栏 6845

编写一个内核模块

编写MakefileMakefile中的内容详情请参考。

zyqash的博客 1484

互斥锁linux内核优化,linux内核信号量和互斥锁使用

信号量概念Linux 内核的信号量在概念和原理上与用户态的 System V 的 IPC 机制信号量是一样的,但是它绝不可能在内核之外使用,因此它与 System V 的 IPC 机制信号量毫不相干。信号量在创建时需要设置一个初始值,表示同时可以有几个任务可以访问该信号量保护的共享资源,初始值为 1 就变成互斥锁(Mutex),即同时只能有一个任务可以访问信号量保护的共享资源。一个任务要想访问共享...

weixin_39534395的博客 385

linux内核信号量和互斥锁使用

信号量概念 Linux 内核的信号量在概念和原理上与用户态的 System V 的 IPC 机制信号量是一样的,但是它绝不可能在内核之外使用,因此它与 System V 的 IPC 机制信号量毫不相干。 信号量在创建时需要设置一个初始值,表示同时可以有几个任务可以访问该信号量保护的共享资源,初始值为 1 就变成互斥锁(Mutex),即同时只能有一个任务可以访问信号量保护的共享资源。 一个任务要想访问共享资源,首先必须得到信号量,获取信号量的操作将把信号量的值减 1,若当前信号量的值为负数,表明无法获得信号量

仗劍走天涯 2384
上一篇: Linux驱动修炼之道-内存映射
下一篇: linux中mmap系统调用原理分析与实现
Alan0521
博客等级 码龄19年 77粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值