1.应用层出发
调用open函数 --->>> 在进程里调用的
在创建进程的时候,内核会为该进程创建一个结构体来描述当前进程的所有信息
struct task_struct{
pid_t pid;
pid_t tgid;
...
/* open file information */
struct files_struct *files;
};
struct files_struct {
struct file * fd_array[NR_OPEN_DEFAULT];
}
创建文件的时候,内核会为该文件创建一个结构体来描述创建的文件信息
struct inode{
uid_t i_uid;
gid_t i_gid;
dev_t i_rdev; //设备号
union {
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
};
...
}
在进程中调用open函数,经过系统调用,陷入内核态,内核代替应用层进程执行,为打开的
这个文件创建一个结构体,来描述该打开的文件的所有信息。
struct file{
const struct file_operations *f_op;
unsigned int f_flags; //模式
};
应用层打开设备文件cdev_demo0、cdev_demo1、cdev_demo2在驱动代码中如何区分?
根据驱动中的open接口形参中的inode结构体指针里面的i_rdev来区分
MINOR(i_rdev)
int demo_open(struct inode *inode, struct file *filp)
{
printk("---devfile_minor:%d---\n",MINOR(inode->i_rdev));
printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__);
return 0;
}
//open系统调用过程
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
--->>> do_sys_open(dfd, filename, flags, mode);
--->>>do_filp_open(dfd, tmp, &op, lookup);
--->>>path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
--->>>do_last(nd, &path, op, pathname);
--->>>filp = nameidata_to_filp(nd);
--->>>__dentry_open(nd->path.dentry, nd->path.mnt, filp,
NULL, cred);
--->>>if (!open && f->f_op)
open = f->f_op->open;
if (open) {
error = open(inode, f);