Linux 应用层open调用驱动层open过程
内核版本:3.0.8
open、close、read、write、ioctl等等都是类似。
==========================================================================================
驱动层:
struct file_operations fops =
{
.open = xxx_open,
.release = xxx_close,
.read = xxx_read,
.write = xxx_write,
...
};
struct cdev {
struct module *owner;
const struct file_operations *ops; //文件操作对象
struct list_head list;
dev_t dev; //设备号
...
};
// 申请设备号,创建文件操作结构体 struct file_operations fops
static inline int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops);
// 创建字符设备对象结构体 struct cdev,将 fops 赋值给 cdev
struct cdev *cdev;
cdev->ops = fops;
// 将设备号赋值给 cdev, 将 cdev 注册到链表cdev_map
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
p->dev = dev;
kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
// cdev 结构体中包含 file_operations 和 设备号 dev_t。
// 创建字符设备类
struct class *__class_create(struct module *owner, const char *name, struct lock_class_key *key);
// 在类中创建一个设备, /dev 目录下会生成一个文件,名称为 led
// 系统自动为此文件分配 inode 节点(linux系统是通过 inode 节点来查找文件),节点中包含此字符设备的设备号 dev_t
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata,"led");
// 每一个文件都有一个inode
struct inode {
umode_t i_mode;//就是权限
uid_t i_uid; //用户
gid_t i_gid; //用户组
dev_t i_rdev; //设备号
loff_t i_size; //大小
... ...
}
==========================================================================================
应用层:
// 打开驱动中创建的设备,open 会调用VFS层中的 sys_open();
int open("/dev/led", int flags, mode_t mode);
// 调用 sys_open() 的过程,详见 http://blog.csdn.net/hxmhyp/article/details/22699669 ,感谢这位朋友细心讲解
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode);
==========================================================================================
VFS层:
// open会调用内核中的 sys_open(),这个函数是经过变换得来的,参数与open完全吻合
// 参数1:函数名,
// 参数2:文件名类型
// 参数3:文件名
// 参数4:打开标志类型
// 参数5:打开文件标志
// 参数6:文件权限类型
// 参数7:文件权限
int sys_open(open, const char __user *, filename, int, flags, int, mode)
// 每个文件都对应一个 struct file 结构体,打开一个文件,系统都会将 struct file 添加到 struct fdtable 的数组中
struct fdtable {
unsigned int max_fds;
struct file __rcu **fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
struct rcu_head rcu;
struct fdtable *next;
};
// 返回的文件描述符就是此文件的 struct file 在数组中的下标,从3开始(stdin-0 stdout-1 stderr-2)
struct file {
struct path f_path; // 文件路径
const struct file_operations *f_op; // 文件操作对象
unsigned int f_flags; //文件标志
fmode_t f_mode; // 文件权限
loff_t f_pos; // 文件当前偏移量
void *private_data; // 私有数据
... ...
}
// 通过 struct file 中的文件路径 f_path 得到文件的 inode 节点
long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
static inline void fsnotify_open(struct file *file)
struct path *path = &file->f_path;
struct inode *inode = path->dentry->d_inode;
// 通过 inode 节点获取文件设备号
// 遍历 cdev 链表,获取设备号,与此文件的设备号相同表示匹配成功
// 将匹配成功的 cdev 结构体中的 file_operations 赋值给此文件的 struct file,从而关联到驱动层中的 xxx_open
==========================================================================================
// 应用层 ---> 驱动层
// open ---> xxx_open
// close ---> xxx_open
// read ---> xxx_open
// write ---> xxx_open
ps:以上的缩进都表示包含于上一个函数中之内。
Linux 应用层open调用驱动层open过程的更多相关文章
- DeviceIoControl 应用层如何和驱动层通信?
调用的方法之一的DeviceIoControl 驱动层提供设备名 例如filedisk 在驱动层 首先先是注册列表 用winObj查看 filedisk的驱动对象 但是 这八个对象时怎么生成的呢? 我 ...
- android和linux开发环境建立(驱动层)
流程:安装ubutu14.04操作系统==>安装各种库和应用程序并配置环境变量 1,install ubuntu14.04 为了完全释放PC机的资源,我们安装在主机上,就不用虚拟机来玩了.下面是 ...
- Linux的应用层到底层驱动的调用过程
应用层如何内核.md 1.从应用层打通内核:驱动 首先来说是设备号的引入,我们通过 cat/proc/kallsyms |grep mydevice 可以查看设备号,当然我们也是可以自己创建设备号,这 ...
- Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析)
本文将介绍网络连接建立的过程.收发包流程,以及当中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 1.应用层 对于使用socket进行网络连接的server端程序.我们会先调用socket函 ...
- Minifilter微过滤框架:框架介绍以及驱动层和应用层的通讯
minifilter是sfilter后微软推出的过滤驱动框架.相比于sfilter,他更容易使用,需要程序员做的编码更简洁. 系统为minifilter专门制作了一个过滤管理器,这个管理器本身其实是一 ...
- 2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- Linux 驱动层实现阻塞和非阻塞
linux应用层的函数默认是阻塞型的,但是要想真正实现阻塞,还需要驱动的支持才行. 例:open().scanf().fgets().read().accept() 等 1.默认情形,驱动层不实现阻塞 ...
- 应用层open(read、write、close)怎样调用驱动open(read、write、close)函数的?
应用层open(read.write.close)怎样调用驱动open(read.write.close)函数的? 华清远见2014-09-29 北京海淀区 张俊浩 三大数据结构关系图
- 迅为4412开发板Linux驱动教程——编写简单应用调用驱动
Linux驱动教程:http://pan.baidu.com/s/1c0hljUS 编写简单应用调用驱动--头文件 • 打印头文件 – include <stdio.h>调用打印函数pri ...
随机推荐
- dubbo用户指南-总结
dubbo用户指南-总结 入门 背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用 ...
- 关于iOS开发的学习
关于iOS开发的学习,打个比方就像把汽车分解: 最底层的原料有塑料,钢铁 再用这些底层的东西造出来发动机,座椅 最后再加上写螺丝,胶水等,把汽车就拼起来了 iOS基本都是英文的资料, ...
- NextPermutation,寻找下一个全排列
问题描述:给定一个数组是一个全排列,寻找下一个全排列.例如123->132, 321->123, 115->151. 算法分析:从后往前寻找顺序,找到后从往前寻找第一个大于当前元素, ...
- codevs 1017 乘积最大 dp
1017 乘积最大 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚 ...
- NumPy字节交换
NumPy - 字节交换 我们已经知道,存储在计算机内存中的数据取决于 CPU 使用的架构. 它可以是小端(最小有效位存储在最小地址中)或大端(最小有效字节存储在最大地址中). numpy.ndarr ...
- C-RAN
无线接入网(RAN)是移动运营商赖以生存的重要资产.传统的无线接入网具有以下特点: 1. 每一个基站连接若干个固定数量的扇区天线,并覆盖小片区域,每个基站只能处理本小区收发信号: 2. 系统的容量是干 ...
- CMD下利用subst命令将一个文件夹镜像成本地的一个虚拟磁盘
我们都知道net use可以建立网络驱动器映射,这里不说了. 我今天刚看到这命令的,叫镜像虚拟磁盘subst命令,这个命令可以简化好多操作,比如一个常用的文件放在一个路径很深的文件夹中,每次我们想要操 ...
- 51nod 1270 dp
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1270 简单的线性dp,最近狂刷水题真的是...药丸 差值最大得话要么是峰 ...
- elasticsearch负载均衡节点——客户端节点 node.master: false node.data: false 其他配置和master 数据节点一样
elasticSearch的配置文件中有2个参数:node.master和node.data.这两个参 数搭配使用时,能够帮助提供服务器性能. 数据节点node.master: false node. ...
- language model ——tensorflow 之RNN
代码结构 tf的代码看多了之后就知道其实官方代码的这个结构并不好: graph的构建和训练部分放在了一个文件中,至少也应该分开成model.py和train.py两个文件,model.py中只有一个P ...