当前位置: 技术问答>linux和unix
请高手指教一下进程打开的File对象相关的几个问题
来源: 互联网 发布时间:2016-04-09
本文导语: 网上搜了几天没有结果,看了些相关的书也没整明白,还望高人相助。具体的问题如下: 1.进程打开的每一个文件都对应一个File对象,该对象中有一个成员struct file_operations *f_op,该结构里的函数指针所指向的函...
网上搜了几天没有结果,看了些相关的书也没整明白,还望高人相助。具体的问题如下:
1.进程打开的每一个文件都对应一个File对象,该对象中有一个成员struct file_operations *f_op,该结构里的函数指针所指向的函数是具体的文件系统(打开的是普通文件)或驱动程序(打开的是设备文件)里实现的函数吗?当用户进程调用read等系统调用时,实际执行的应该是f_op结构中的函数吧?也就是说当对该文件进行进行操作时都是通过File对象来进行的,对吗?
2.File对象中的f_op指针的赋值问题,看到一篇文章说的是File中的f_op从该文件的inode结构i_fop得来,而该文件的inode结构中的i_fop是在open文件时从磁盘读入inode结点内容,判断是普通文件,目录或设备后采取不同方式进行赋值的,对于设备而言要用到inode->dev中的操作表。我想知道的是对File中的f_op赋值的流程是不是只有上面一种,一般情况下有没有其他的获得该f_op的方法,比如在chrdevs表中也注册了设备驱动的操作函数,会不会从那里获得f_op?还有inode中的i_fop都是要在open文件时才初始化吗?
3.register_chrdev和device_register,driver_register都啥关系呀,呵呵,大概说两句就行,剩下的自己看。
哎,一头雾水啊。
1.进程打开的每一个文件都对应一个File对象,该对象中有一个成员struct file_operations *f_op,该结构里的函数指针所指向的函数是具体的文件系统(打开的是普通文件)或驱动程序(打开的是设备文件)里实现的函数吗?当用户进程调用read等系统调用时,实际执行的应该是f_op结构中的函数吧?也就是说当对该文件进行进行操作时都是通过File对象来进行的,对吗?
2.File对象中的f_op指针的赋值问题,看到一篇文章说的是File中的f_op从该文件的inode结构i_fop得来,而该文件的inode结构中的i_fop是在open文件时从磁盘读入inode结点内容,判断是普通文件,目录或设备后采取不同方式进行赋值的,对于设备而言要用到inode->dev中的操作表。我想知道的是对File中的f_op赋值的流程是不是只有上面一种,一般情况下有没有其他的获得该f_op的方法,比如在chrdevs表中也注册了设备驱动的操作函数,会不会从那里获得f_op?还有inode中的i_fop都是要在open文件时才初始化吗?
3.register_chrdev和device_register,driver_register都啥关系呀,呵呵,大概说两句就行,剩下的自己看。
哎,一头雾水啊。
|
进程打开的每一个文件内核都会创建一个File结构体对象,打开时会返回一个文件描述符,就是fd=open("/dev/tty",....)中的fd,这个fd就是内核维护的File对象组的索引。通过fd可以找到File对象,进而由File对象中的struct file_operations *f_op指针找到你关于这个文件的驱动,进而在你文件操作时调用对应的驱动,如read(fd,buffer,size,...)则调用file_operations 中的read函数。第一个你说的是对的。
第二个,你的inode的创建是指定了设备号的,这个设备号是你在注册驱动时获得的,他可以对应上你的驱动,也就是说你的inode里边包含了你的驱动信息,所以打开节点时就获得了驱动信息,并保存到了File结构体对象中,在你操作该文件时(比如read、write)时只用调用标准的接口,把一个文件描述符fd传递为函数参数就可以了。这个过程时linux文件系统规定的标准操作过程。
第三个,device_register,driver_register时2.6内核提供一种新的驱动编写模型,他引入了bus、device等新的驱动开发架构,可以使繁多的设备有更好的抽象层,进而方便驱动编写,具体可以看看ldd3的相关章节。
第二个,你的inode的创建是指定了设备号的,这个设备号是你在注册驱动时获得的,他可以对应上你的驱动,也就是说你的inode里边包含了你的驱动信息,所以打开节点时就获得了驱动信息,并保存到了File结构体对象中,在你操作该文件时(比如read、write)时只用调用标准的接口,把一个文件描述符fd传递为函数参数就可以了。这个过程时linux文件系统规定的标准操作过程。
第三个,device_register,driver_register时2.6内核提供一种新的驱动编写模型,他引入了bus、device等新的驱动开发架构,可以使繁多的设备有更好的抽象层,进而方便驱动编写,具体可以看看ldd3的相关章节。
|
第2点:Let's suppose that a process executes an open( ) system call on a device file (either of type block or character). Essentially, the corresponding service routine resolves the pathname to the device file and sets up the corresponding inode object, dentry object, and file object.
The inode object is initialized by reading the corresponding inode on disk through a suitable function of the filesystem (usually ext2_read_inode( ) or ext3_read_inode( ). When this function determines that the disk inode is relative to a device file, it invokes init_special_inode( ), which initializes the i_rdev field of the inode object to the major and minor numbers of the device file, and sets the i_fop field of the inode object to the address of either the def_blk_fops or the def_chr_fops file operation table, according to the type of device file. The service routine of the open( ) system call also invokes the dentry_open( ) function, which allocates a new file object and sets its f_op field to the address stored in i_fop,that is, to the address of def_blk_fops or def_chr_fops once again. Thanks to these two tables, every system call issued on a device file will activate a device driver's function rather than a function of the underlying filesystem.