字符设备文件的打开操作

sys_openf
do_sys_open
fd = get_unused_fd_flags(flags);//获得文件描述符fb;
struct file *f = do_filp_open(dfd, tmp, &op, lookup);//通过tmp==filename(/dev/filename)查找与之对应的设备文件的inode,在linux文件系统中,每个文件都有一个inode与之对应。
path_openat
filp = get_empty_filp();//调用这个函数为每个打开的文件分配一个新的struct file 类型的内存空间(对象指针简写为filp);内核用struct file对象来描述进程打开的每一个文件的视图,即使打开同一个文件,内核也会为之生成一个新的struct file的对象,用来表示当前操作的文件 的相关信息。他有private_data 和 f_op成员。进程为文件操作维护一个描述符表(current->files->fdt[fd]---->filp);
filp = do_last(nd, &path, op, pathname);
filp = nameidata_to_filp(nd);//调用关键的函数来幅值filp对象与具体的cdev对象;
filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,NULL, cred);
open = f->f_op->open;
error = open(inode, f);//在生成设备节点init_special_inode中inode->i_fop = &def_chr_fops所以调用的是const struct file_operations def_chr_fops = { .open = chrdev_open;
chrdev_open
kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);//通过inode->i_rdev设备号在cdev_map的cdev链表中来找到具体设备的kobj对象;
new = container_of(kobj, struct cdev, kobj);//通过kobj来找到cdev *new具体的设备对象。
filp->f_op = fops_get(p->ops);//filp对象赋值fop操作方法;
ret = filp->f_op->open(inode, filp);//调用驱动中的open方法;
通过如上分析可以知道设备号的重要性,通过设备号才能查找到cdev_map里的字符设备对象,从而在成功查找到字符设备对象后将inode的i_cdev成员指向该设备对象,这样下次对再对该字符设备节点进行打开操作时就可以直接通过i_cdev得到设备对象,无需去map_cdev里查找。
内核在每一次打开一个设备文件的时候都会产生一个整形的文件描述符fd和一个新的struct file对象filp来跟踪对该文件的操作,在打开设备文件时内核会将fd和filp关联起来。同时会将cdev中的ops赋值给filp->f_op最后sys_open系统调用将设备文件描述符fd返回到用户空间。这样子在用户空间对后续文件操作read,write和ioctrl等的函数调用,将会通过该fd来获得文件所对应的filp,根据filp中的f_op就可以调用到该文件对应的设备驱动上实现的函数。
mknod c /dev/filename 256 2 创建的设备文件inode里的i_rdev保存了设备号。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值