IO系统—相关数据结构初始化及调用详解(文件描述符表、文件结构表、文件节点表、设备节点表、内核驱动表等)

news2024/9/22 4:21:52

文章目录

  • 数据结构总述
  • 数据结构初始化流程概述
  • 各结构初始化及关联说明
    • 文件描述符表
    • 文件结构(文件表)
    • 文件节点
    • 设备节点
    • 内核驱动表

数据结构总述

在这里插入图片描述
本文基于NEW_1 型内核数据结构展开,通过上图可以看出了使用三种数据结构(文件描述符表项、文件结构、文件节点)来表示打开的文件,它们的关系决定了在文件共享方面,一个进程对另一个进程可能产生的影响。

  • 每个进程都维护着自己的一个文件描述符表,每个文件描述符占其中一项,与每个文件描述符相关联的是:
     指向文件结构的指针;
     文件引用计数;
     文件描述符标志(FD_CLOEXEC)。
  • 内核为所有打开的文件维护一个文件结构表,每一个文件结构表项包括(部分):
     设备头指针(这个指针指向设备节点);
     文件名;
     文件节点指针;
     文件属性标志(读、写等,更多信息 点击查看iFlag选项描述);
     文件当前指针(指示文件偏移)。
  • 每个打开的文件都有一个文件节点,文件节点包括(部分):
     设备描述符;
     inode(同一个文件只有一个 inode,SylixOS 中 inode 并不和 Linux 中的 inode 一样,SylixOS 中 inode 可看做是一种文件识别码);
     文件权限信息(可读、可写、可执行);
     文件用户信息;
     当前文件大小;
     文件记录锁指针。

下图展示了两个独立进程各自打开了同一个文件的情景,我们假定第一个进程在文件描述符 3 上打开该文件,而另一个进程在文件描述符 4 上打开相同文件。打开该文件的每个进程都获得各自的一个文件结构,但对于一个给定的文件只有一个文件节点。之所以每个进程都获得自己的文件结构,是因为这可以使每个进程都有它自己的对该文件的当前读写指针(文件操作偏移量)。

文件描述符标志和文件属性标志在作用范围方面是有区别的,前者只用于一个进程中的一个文件描述符,而后者则应用于指向该给定文件结构的任何进程中的所有文件描述符。
在这里插入图片描述

数据结构初始化流程概述

• iosDevAddEx()以注册驱动函数为参数,创建设备;(dev_hdr)
• _IosFileNew() 创建并初始化 fd_entry 文件结构;(fd_desc)
• _IosFileDup() 以 fd_entry 为参数,创建并初始化 fd_desc 文件描述符;(fd_desc->fd_entry)
• API_IosFdNodeAdd() 以 dev_hdr 为参数,创建初始化并返回 fd_node 文件节点;(fd_desc->fd_entry)(fd_node->dev_hdr)
• _IosFileSet() 以 dev_hdr 、fd_node为参数,配置 fd_entry 结构;(fd_desc->fd_entry->fd_node->dev_hdr) ;

各结构初始化及关联说明

文件描述符表

○ 文件描述符表:_G_fddescTbl[LW_CFG_MAX_FILES],type:LW_FD_DESC;
	§ 每个进程都维护着自己的一个文件描述符表(数组),每个文件描述符占其中一项;
○ 应用层调用 open/create 函数时,底层会调用 INT  _IosFileDup (PLW_FD_ENTRY pfdentry, INT iMinFd),_IosFileDup() 调用 vprocIoFileDup (PLW_FD_ENTRY pfdentry, INT iMinFd) ,以 PLW_FD_ENTRY(文件结构)为参数对 LW_FD_DESC(文件描述符) 结构体进行初始化,并返回一个文件描述符(对应文件描述符表数组的下标),(PLW_FD_DESC 结构体内包含 PLW_FD_ENTRY 成员);
○ 以 PLW_FD_ENTRY(文件结构)为参数初始化并返回一个文件描述符(对应文件描述符表数组的下标),(PLW_FD_DESC 结构体内包含 PLW_FD_ENTRY 成员);
	§ INT  open (CPCHAR  cpcName, INT  iFlag, ...)
		□ static INT _IoOpen (PCHAR pcName, INT iFlag, INT iMode, BOOL bCreate)
			® INT  API_IosFdNew (PLW_DEV_HDR    pdevhdrHdr, CPCHAR pcName, LONG lValue, INT iFlag)        //返回文件描述符
				◊ PLW_FD_ENTRY  INT  _IosFileDup (PLW_FD_ENTRY pfdentry, INT iMinFd)                      //申请并初始化一个新的文件描述符
					※ INT  vprocIoFileDup (PLW_FD_ENTRY pfdentry, INT iMinFd)                            //查找空文件描述符, 初始化文件描述符结构体
○ vprocIoFileDup() 函数中,获取进程控制块 LW_LD_VPROC *pvproc,初始化进程fd表(PLW_FD_DESC pvproc->VP_fddescTbl[iFd])中最小未使用的文件表描述符;

在这里插入图片描述
在这里插入图片描述

文件结构(文件表)

○ 文件结构表头:_S_plineFileEntryHeader,type:LW_LIST_LINE_HEADER;
	§ 内核为所有打开的文件维护一个文件结构表;
○ 应用层调用 open/create 函数时,底层会调用 _IoOpen (PCHAR pcName, INT iFlag, INT iMode, BOOL bCreate),其中:
	§ iFd = iosFdNew(pdevhdrHdr, cFullFileName, PX_ERROR, iFlag);           //返回申请的文件描述符
		□ pfdentry = _IosFileNew(pdevhdrHdr, pcName);                                                  //创建并初始化 fd_entry 结构
		□ iFd = _IosFileDup(pfdentry, 0);                                                                                //查找空的fd_desc文件描述符, 配置文件结构 pfdentry 
		□ _IosFileSet(pfdentry, pdevhdrHdr, lValue, iFlag, state);                                     //设置一个 fd_entry 结构(初始配置)
	§ lValue = iosOpen(pdevhdrHdr, cFullFileName, iFlag, iMode);
		□ lFValue = pfuncDrvOpen(pdevhdrHdr, pcName, iFlag, iMode);
			® PLW_FD_NODE API_IosFdNodeAdd(LW_LIST_LINE_HEADER  *pplineHeader, dev_t dev, ino64_t inode, INT iFlags, mode_t mode, uid_t uid, gid_t gid, off_t oftSize, PVOID pvFile, BOOL *pbIsNew);                                 //创建初始化并返回 fd_node 文件节点,见文件节点章节
		§ iosFdSet(iFd, pdevhdrHdr, lValue, iFlag, FDSTAT_OK);
			□ pfdentry = _IosFileGet(iFd, LW_TRUE);                                                               //通过 fd 获得 fd_entry
			□ _IosFileSet(pfdentry, pdevhdrHdr, lValue, iFlag, state);                                  //设置一个 fd_entry 结构(补充配置,填充fd_entry的fd_node和dev_hdr)
○ 底层会调用PLW_FD_ENTRY _IosFileNew (PLW_DEV_HDR  pdevhdrHdr, CPCHAR  pcName),以 PLW_DEV_HDR(设备头指针)为参数创建并初始化文件结构,(LW_FD_ENTRY 结构体内包含 PLW_DEV_HDR 成员);
	§ INT  open (CPCHAR  cpcName, INT  iFlag, ...)
		□ static INT _IoOpen (PCHAR pcName, INT iFlag, INT iMode, BOOL bCreate)
			® INT  API_IosFdNew (PLW_DEV_HDR    pdevhdrHdr, CPCHAR pcName, LONG lValue, INT iFlag)         //返回文件描述符
				◊ PLW_FD_ENTRY  _IosFileNew (PLW_DEV_HDR  pdevhdrHdr, CPCHAR  pcName)                      //创建并初始化 fd_entry 结构
○ _IosFileNew() 通过_List_Line_Add_Ahead(PLW_LIST_LINE &(PLW_FD_ENTRY->FDENTRY_lineManage), LW_LIST_LINE_HEADER *  (&_S_plineFileEntryHeader)) 函数将 (LW_FD_ENTRY 文件结构的) FDENTRY_lineManage 成员加入文件结构表;

在这里插入图片描述
在这里插入图片描述

文件节点

○ 文件节点链表:pplineHeader,type:LW_LIST_LINE_HEADER  *;
	§ 设备私有链表,一个设备节点对应一个文件节点链表。
○ 应用层调用 open/create 函数时,底层会调用_S_deventryTbl[__LW_DEV_MAINDRV].DEVENTRY_pfuncDevOpen((PLW_DEV_HDR pdevhdrHdr, PCHAR pcName, INT iFlag, INT iMode));
	§ INT  open (CPCHAR  cpcName, INT  iFlag, ...)
		□ static INT _IoOpen (PCHAR pcName, INT iFlag, INT iMode, BOOL bCreate)
			® LONG  API_IosOpen (PLW_DEV_HDR    pdevhdrHdr, PCHAR pcName, INT iFlag, INT iMode)
				◊ _S_deventryTbl[__LW_DEV_MAINDRV].DEVENTRY_pfuncDevOpen((PLW_DEV_HDR pdevhdrHdr, PCHAR pcName, INT iFlag, INT iMode));
○ DEVENTRY_pfuncDevOpen() 内调用 API_IosFdNodeAdd (LW_LIST_LINE_HEADER  *pplineHeader, dev_t dev, ino64_t  inode64, INT iFlags, mode_t mode, uid_t uid, gid_t gid, off_t oftSize, PVOID pvFile, BOOL *pbIsNew);
	§ pplineHeade 链表头通常初始化为设备控制块成员变量 ;
○ API_IosFdNodeAdd() 通过_List_Line_Add_Ahead(PLW_LIST_LINE  &PLW_FD_NODE->FDNODE_lineManage, LW_LIST_LINE_HEADER  *pplineHeader) 将(初始化完成的文件节点的)FDNODE_lineManage 成员添加至“同一设备的 fd_node 链表”进行统计管理;

在这里插入图片描述
在这里插入图片描述

设备节点

○ 设备表表头:_S_plineDevHdrHeader,type:LW_LIST_LINE_HEADER;
	§ 全局设备头链表为全局变量;
	§ 设备链表内会添加关联所有设备,包括不同驱动号(主设备号)的设备及相同驱动号(主设备号),不同子设备号的设备;
○ 使用 API_IosDevAddEx (PLW_DEV_HDR pdevhdrHdr, CPCHAR pcDevName, INT iDrvNum, UCHAR ucType)向系统中添加一个设备;
○ 使用 _List_Line_Add_Ahead(&pdevhdrHdr->DEVHDR_lineManage, &_S_plineDevHdrHeader); 将设备头的管理链表成员加入全局设备头链表;
○ LW_DEV_HDR 设备头通常初始化为设备控制块成员变量 ;

在这里插入图片描述
在这里插入图片描述

内核驱动表

○ 驱动程序表:_S_deventryTbl[iDrvNum],type:LW_DEV_ENTRY;
	§ 全局变量,保存所有设备驱动的底层操作实现;
	§ 每组驱动函数对应一个驱动程序索引号;
○ 使用 API_IosDrvInstallEx (struct file_operations  *pfileop)向内核注册设备驱动程序,输出“驱动程序索引号(iDrvNum)”;
○ 使用 pfileop(设备文件操作控制块) 初始化 _S_deventryTbl[iDrvNum];

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/401308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux系统编程】03:文件夹操作

文件夹操作 OVERVIEW文件夹操作一、文件夹操作1.修改目录chdir2.打开目录opendir3.关闭目录closedir4.读取目录readdir5.文件信息获取stat二、案例使用1.ls实现2.stat文件信息获取3.ls -la主要实现4.ls -la重点修改5.ls -la文件字典序6.ls -la文件颜色显示三、补充操作1.文件定…

【SPSS】交叉设计方差分析和协方差分析详细操作教程(附案例实战)

🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 方差分析概述 交叉设计方差分析

hibernate学习(三)

session:类似connection对象是连接对象 一、session: 二、session中的API 三、get和load的区别 四、修改方法: void update(object obj) 五、删除方法: void delete(object obj&#xff0…

案例14-代码结构逻辑混乱,页面设计不美观

目录 目录 一:背景介绍 二:思路&方案 三:过程 问题1:代码可读性差,代码结构混乱 问题2: 代码逻辑混乱,缺乏封装的意识 问题3:美观问题:问题和图标没有对应上 四…

最短路专题——Dijkstra、Floyd、Bellman-Ford、SPFA

目录前言一、全源最短路1.1 Floyd二、单源最短路2.1 Dijkstra2.1.1 堆优化版的Dijkstra2.2 Bellman-Ford2.2.1 队列优化版的Bellman-Ford:SPFA前言 BFS是一种朴素的最短路算法,它可以找到无权图或边权都相同的图的最短路,但是对于边权不完全…

AbstractQueuedSynchronizer从入门到踹门

概念设计初衷:该类利用 状态队列 实现了一个同步器,更多的是提供一些模板方法(子类必须重写,不然会抛错)。 设计功能:独占、共享模式两个核心,state、Queue2.1 statesetState、compareAndSetSta…

LayerNormalization

目录 1.BN的问题 1.1 BN与batch size 1.2 BN与RNN 2.LN详解 2.1 MLP中的LN 2.2 RNN中的LN 2.3 LN与ICS和损失平面平滑 BN不适用于RNN等动态网络和batchsize较小的时候效果不好。LayerNormalization的提出有效的解决BN的这两个问题。LN和BN不同点是归一化的维度是互相垂直…

SQL总结-排名的使用

##一、通过排名或者范围条件连表筛选特殊行 第一行最后一行区间(第一行到第二行或者连续区间)找中位数通过排名进行分组或者连续区间 ######1.使用条件筛选连表找区间 Employee 表保存了一年内的薪水信息。 请你编写 SQL 语句,来查询每个…

基于ChatRWKV智能问答和内容创作

ChatRWKV是对标ChatGPT的开源项目,希望做大规模语言模型的Stable Diffusion,测试很一段时间确实很像ChatGPT,从使用方法和内容结果上都很相似,但是还有一些差异。 文章目录 准备工作环境配置创建虚拟环境激活虚拟环境pip安装匹配版本ChatRWKV 使用模型替换常用参数设置使用…

手机磁吸背夹散热器制冷快速方案

手机散热器是什么?手机散热器分为几种类型?手机散热的方式都有哪些? 因为经常玩游戏,手机发热得厉害,都可以煎鸡蛋了,心想着要买个东西给手机散散热,没想到还真的有手机散热器。 不知道手机散…

mysql锁分类大全

前言 为什么会出现锁 MySQL中的锁是为了保证并发操作的正确性和一致性而存在的。 当多个用户同时对同一份数据进行操作时,如果不加控制地进行读写操作,就可能导致数据不一致的问题。例如,当多个用户同时对同一行数据进行写操作时&#xff…

uniapp使用webview嵌入vue页面及通信

最近刚做的一个需求,web端(Vue)使用了FormMaking库,FormMaking是一个拖拉拽的动态设计表单、快速开发的一个东西,拖拽完之后最终可以导出一个很长的json,然后通过json再进行回显,快速开发&#…

【Spring Boot】Spring Boot经典面试题分享

文章目录1. SpringBoot 简介2. SpringBoot 的优缺点3. SpringBoot 固定版本4. SpringBoot 的使用方式5. SpringBoot 自动配置原理6. PropertySource7. ImportResource8. springboot 的 profile 加载9. SpringBoot 激活指定 profile 的几种方式10. SpringBoot 项目内部配置文件加…

项目中用到的责任链模式

目录 1.什么是责任链?它的原理是什么? 2.应用场景 ​3.项目中的应用 传送门:策略模式,工作中你用上了吗? 1.什么是责任链?它的原理是什么? 将请求的发送和接收解耦,让多个接收对象…

NetApp AFF A900:针对任务关键型应用程序的解决方案

NetApp AFF A900:适用于数据中心的解决方案 AFF A 系列中的 AFF A900 高端 NVMe 闪存存储功能强大、安全可靠、具有故障恢复能力,提供您为任务关键型企业级应用程序提供动力并保持数据始终可用且安全所需的一切。 AFF A900:针对任务关键型应…

关于BLE的一些知识总结

数据包长度对于BLE4.0/4.1来说,一个数据包的有效载荷最大为20字节对于BLE4.2以上,数据包的有效载荷扩大为251字节传输速率在不考虑跳频间隔的情况下,最大传输速率为:1)BLE4.0/4.1的理论吞吐率为39kb/s;2&am…

523-(ZCU102E的pin兼容替代卡) 基于 XCZU15EG的双 FMC通用信号处理板

(ZCU102E的pin兼容替代卡) 基于 XCZU15EG的双 FMC通用信号处理板 一、板卡概述 本板卡基于Xilinx Zynq Ultrascale MPSOC系列SOC XCZU15EG-FFVB1156架构,PS端搭载一组64-bit DDR4,容量32Gb,最高可稳定运行在240…

solidworks调用toolbox出现未配置怎么办

问题背景 本人最近在跟随B站恶补solidworks,学习链接如下 https://www.bilibili.com/video/BV1iw411Z7HZ/?spm_id_from333.337.search-card.all.click 但是在学习的过程中遇到了这样的问题 智能点现在配置,正常的应该是这样的 扒拉了网上所有的解决办…

04从零开始学Java之可能是最详细的Java环境配置教程

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者前言在上一篇文章中,壹哥给大家重点讲解了Java实现跨平台的原理,不知道你现在有没有弄清楚呢?如…

window vscode编辑appsmith源码

前言 本来最开始用的idea打开wsl中的appsmith,卡得一批。最后没办法,用自己的电脑装成ubuntu server,然后vscode的远程开发对appsmith源码进行编辑。如果自己电脑内存16个G或者更大可能打开wsl中的估计会还好,我公司电脑只有8g所…