3. file、inode结构体及chardevs数组等相关知识解析

https://blog.csdn.net/zqixiao_09/article/details/50850004

下图描述了Linux中虚拟文件系统,一般的设备文件与设备驱动程序间的函数调用关系

上图展现了一个应用程序调用字符设备驱动的过程,在设备驱动程序的设计中,一般而言,会关系file和inode这两个结构体。

用户空间使用open()函数打开一个字符设备fd = open("/dev/hello", o_READ);这一函数会调用两个数据结构struct inode{}&struct file{}.二者均在虚拟文件系统VFS处,下面对这两个数据结构进行解析:

1、file文件结构体

(1)在设备驱动中,这是非常重要的数据结构

(2)这里的file与用户空间出现中的FILE指针式不同的,用户空间FILE是定义在C库中,从来不会出现在内核中。而struct file,确是内核中的数据结构,因此,它也不会出现在用户层程序中。

(3)file结构体指示一个已经打开的文件(设备对应设备文件),其实系统中每个打开的文件在内核空间都有一个相应的struct file结构体,它由内核在打开文件时创建,并传递给在文件上进程操作的任何函数,直至文件被关闭。如果文件被关闭,内核就会释放相应的数据结构。

(4)在内核源码中,struct file要么表示为file,或者为filp(意指“file pointer”), 注意区分一点,file指的是struct file本身,而filp是指向这个结构体的指针。

下面是几个重要成员

a -- fmode_t f_mode;

此文件模式通过FMODE_READ, FMODE_WRITE识别了文件为可读的,可写的,或者是二者。在open或ioctl函数中可能需要检查此域以确认文件的读/写权限,你不必直接去检测读或写权限,因为在进行octl等操作时内核本身就需要对其权限进行检测。

b -- loff_t f_pos;

当前读写文件的位置。为64位。如果想知道当前文件当前位置在哪,驱动可以读取这个值而不会改变其位置。对read,write来说,当其接收到一个loff_t型指针作为其最后一个参数时,他们的读写操作便作更新文件的位置,而不需要直接执行filp ->f_pos操作。而llseek方法的目的就是用于改变文件的位置。

c -- unsigned int f_flags;

文件标志,如O_RDONLY, O_NONBLOCK以及O_SYNC。在驱动中还可以检查O_NONBLOCK标志查看是否有非阻塞请求。其它的标志较少使用。特别地注意的是,读写权限的检查是使用f_mode而不是f_flog。所有的标量定义在头文件中

d -- struct file_operations *f_op;

与文件相关的各种操作。当文件需要迅速进行各种操作时,内核分配这个指针作为它实现文件打开,读,写等功能的一部分。filp->f_op 其值从未被内核保存作为下次的引用,即你可以改变与文件相关的各种操作,这种方式效率非常高。

e -- void *private_data;

在驱动调用open方法之前,open系统调用设置此指针为NULL值。你可以很自由的将其做为你自己需要的一些数据域或者不管它,如,你可以将其指向一个分配好的数据,但是你必须记得在file struct被内核销毁之前在release方法中释放这些数据的内存空间。private_data用于在系统调用期间保存各种状态信息是非常有用的。

/*********************************/

原文地址:https://www.cnblogs.com/Ocean-Star/p/9245663.html

时间: 2024-10-01 02:46:00

3. file、inode结构体及chardevs数组等相关知识解析的相关文章

c#中关于结构体和字节数组转化

最近在使用结构体与字节数组转化来实现socket间数据传输.现在开始整理一下.对于Marshal可以查阅msdn,关于字节数组与结构体转代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.InteropServices; namespace FileSendClient { [StructL

C#结构体和字节数组的转换函数

在通信过程中,一般我们都会操作到字节数组.特别是希望在不同语言编程进行操作的时候. 虽然C#提供了序列化的支持,不用字节数组也行.但操作字节数组肯定会碰到. 一般都会采用结构来表示字节数组.但结构与字节数组直接的转换实在很麻烦. 字节操作不但容易出错,而且每增加一个结构,就自己实现一遍,实在是烦不胜烦. 有没有简单的方法呢?当然有.可以采用非托管区的一些方法来实现. 首先,导入命名空间:System.Runtime.InteropServices; 定义结构的时候,要给结构指定特性. 如: //

inode结构体及软链接和硬链接

首先先了解一下block(块的概念),块是文件存取的最小单位,通常8个扇区为一个块,而每个扇区的大小为512个字节也就是0.5K,所以一个块的大小也就是8*0.5K=4K. 系统通过inode来识别文件 可以用命令stat查看某文件的inode信息,如:stat client.c 可看到除了文件名以外的文件信息都在inode中 因此,inode是保存文件的信息的,称为索引节点 命令: stat 文件名     //查看某个文件的inode信息 df -i         //查看硬盘分区的ino

c语言结构体中动态数组的使用

[背景] c语言结构体中动态数组使得用户能够根据需要来申请空间,相比静态数组,更能有效利用存储空间. [正文] 1. 动态数组在结构体中间 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int a; char buf[0]; // 或者char buf[]; int b; }Node; int main() { printf("%d\n", si

Go -- 中结构体与字节数组能相互转化

编码时如下,假设默认你的结构体为data func Encode(data interface{}) ([]byte, error) { buf := bytes.NewBuffer(nil) enc := gob.NewEncoder(buf) err := enc.Encode(data) if err != nil { return nil, err } return buf.Bytes(), nil } 解码时如下,data为需要解码的字节数组,to为相应的接收结构体,记住to的结构体结

c++与C# winform的消息通讯--(结构体与byte数组的使用)

近期正在做一个蓝牙驱动的使用程序,其中有一块从c++发送数据到C#的部分,网上查了很多资料,大多都是介绍如何通过调用函数获取用户数据.并且在消息发送中,很少介绍如何发送一个结构体,并且结构体里面有 byte数组(硬件开发常用)等如何进行处理. 首先c++里面要建立一个dll文件: 1 BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved) 2 { 3 switch (ul_reason

c结构体里的数组与指针

/* 訪问成员数组名事实上得到的是数组的相对地址.而訪问成员指针事实上是相对地址里的内容 */ struct buf_str { int length; char buf[0]; }; struct foo { buf_str* pbuf; }; void test_funny() { foo f = {0}; printf("%x\n", f.pbuf); printf("%x\n", &f.pbuf->length); printf("%

inode结构体

inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS inode, 而后者以EXT2为代表,我们称为Ext2 inod.这里说明的是VFS inode. 重要成员: 1. struct cdev *i_cdev; 若是字符设备,为其对应的cdev结构体指针. 2. struct block_device *i_bdev; 若是块设备,为其对应的block_device结构体指针 3. dev_t i_rdev; 若是设备文件,此成员记录设备的设备号 1 st

c动态分配结构体二维数组

这个问题我纠结了蛮久了,因为前面一直忙(自己也懒了点),所以没有能好好研究这个.希望这篇文章能够帮助你们. 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stddef.h> 4 5 typedef struct LNode { 6 int F; 7 struct LNode* next; 8 }LNode, *LinkList; 9 int main() 10 { 11 LNode** map = (LNo