当前课程知识点:操作系统 > 第二十二讲 实验八 文件系统 > 22.6 执行流程分析 > 22.6 执行流程分析
那最后一部分呢
我们来给大家介绍一下
这个文件系统的执行流程
这里面举了两个例子
第一个例子是关于文件系统怎么启动
第二个呢 是看一下
当用户程序发出open操作的时候
我们整个这个执行过程是怎么回事
首先看一下这个文件系统初始化过程
从总控函数kern_init开始
专门增加一个fs_init
这是lab8增加内容
在这里面呢fs_init呢
进一步展开会分成三部分
第一个是虚拟文件系统的初始化
第二个是关于设备初始化
第三个是SFS
就是simple file system的初始化过程
我们再把这个vfs_init呢看一下
它干什么事情 第一建一个链表
就是专门针对device的list
使得它可以在后续过程中
管理这些device的fs
第二个呢是设置一个信号量
这是由于很多对共享资源的操作呢
需要信号量来进行保护
那么对于dev_init呢 就是device_init呢
它包含了三部分工作
第一个初始化device
disk stdin和stdout
这分别代表了三类不同的设备
再接下来是关于这个
simple file system的一个初始化过程
这最主要完成一个mount
就是加载这个文件系统
那么这三部分进一步细化可以看出来
第一部分 是关于这个
dev_list的一个初始化
它主要是初始化一个双向链表
这个双向链表是在我们整个
uCore操作系统里面经常使用的
然后也同样存在一个信号量
来保证对这个list操作一个互斥的保护
第二部分关于device的init
它会分别去调用disk0的device_init
stdin和stdout的device_init
那么这后两部分呢
我们在前面也给大家做了介绍
它怎么完成它的初始化过程
这个disk0的初始化过程
希望大家能够自己去看一下
对于simple file system而言
它的这个mount过程包含两部分
第一部分是vfs_mount
以及具体的一个SFS一个do_mount
那么在这个do_mount里面呢
它会完成把自身SFS
和VFS建立一个连接
然后呢把它的根目录
能够让我们的uCore
操作系统能感知得到
使得接下来的 针对这个文件系统的
一个读写操作能够正常执行
那这就是我们文件系统
一个大致初始化过程
这是整个一个初始化一个流程图
接下来我们再看一下
对于一个文件 我们要打开它
便于后续的读 或者写操作
大致执行什么事情
这是应用程序通常的写法
Open一个file
那么这是一个字符串
代表文件的名字
它可能带一些目录
它位于某一个目录下一个文件
这是一个字符串
那么如果这个open操作
正常地执行结束的话
它会返回一个fd
那么这个fd代表了文件
在这个进程控制块中的
一个文件链表中一个位置
从而可以根据这个位置
能访问更具体的file信息
那么当我们应用程序
执行open操作之后呢
它会进一步调系统调用 sys_open
然后呢发出sys_call 这个系统调用
sys_open这么一个信息
然后让我们操作系统做进一步处理
这是第一部分工作
我们操作系统
在接受到这个操作之后呢
它会通过进一步sys_open呢来往下处理
那么可以看出来
它会把文件名的字符串一步步往下传
然后到这儿 那么它会分配一个
Fd_array中的一个项给它
那么这个index
就是我们最终要访问那个fd
但是 需要注意是
这里面fd所对应那个file
它里面inode信息还没有
所以我们进一步要把文件名
所实际对应的inode信息给建立起来
这就需要我们进一步去处理
做vfs_open操作
但是我们知道 vfs_open呢
它只是一个壳
它需要去找到具体文件系统
做进一步打开操作
有两方面 第一方面是要有一个
查找文件名和inode对应信息
一旦找到之后 会把inode信息
给加载到内存中来
成为我们操作系统能够进一步去访问的
一个很重要一个关键数据结构
那么lookup干什么
vfs_lookup会进一步调什么呢
大家想一想
我们说这个lookup就要查找一个文件名
包含了目录也包含文件名本身
这么一个字符串
把所对应的inode是什么
我们需要进一步去看一下
前面的vfs_lookup最终会调到SFS
就simple file system的lookup
这里面它会根据path
就我们刚才说的文件名信息
来一步步的 递归地查找
一个文件它所对应的inode是多少
因为它首先要查找到
这个文件所在的目录
假设我们这里面只有一级目录
那会把这个目录所对应的inode找着
然后查找这个inode里面
所对应的目录项
看目录项里面的文件名
是否和path里面的最终文件名是一致的
如果是一致的
也意味着找着了这个文件
它会把inode对应文件名给取出来
然后进一步去load inode
从而可以把inode的信息
从硬盘加载到我们内存中来
你看这里面 sfs_load_inode
会进一步调sfs_rbuf 就是read buffer
而这一个会进一步device的I/O
最终会访问到IDE的read sector
这个操作是我们硬盘驱动的一个函数
从而把所需要的信息
一层一层再返回到我们应用态
那这就是整个open操作的执行过程
好 那我们把lab8的文件系统呢
给大家做了一个讲解
可以看着这里面涉及的层次很多
数据结构很多 调用关系很复杂
但是相对而言 它整个调用关系
是一个串行的一个调用关系
而包含数据结构的依赖关系呢
也是相对来说比较直观
从上层到底层
底层又返回来引用上层
那这个过程呢 虽然数据量比较大
但是大家通过阅读代码 调试
和具体执行 我相信能够很好地掌握
关于文件系统这一块的内容
一旦完成了文件系统这一块内容呢
我们可以让我们的uCore OS
可以很好访问文件系统中
存在那些文件
去执行 或者读写操作
完成了lab8之后呢
我想大家应该有一定的收获
可以对操作系统有更深入的理解
同时我们也提供了进一步labx
这个labx是希望大家在常规练习之后
去做一些更有挑战一些练习
我们称之为challenge练习
我们在uCoreLab中也给大家列出了
一系列的challenge练习
如果大家对操作系统有兴趣
那我们欢迎大家去迎接新的挑战
好 谢谢大家
-0.1 Piazza讨论区
--html
-0.2 在线实验平台
--实验平台使用帮助
--平台使用帮助
-0.2在线实验平台
--Raw HTML
-1.1 课程概述
--视频
-第一讲 操作系统概述--练习
-1.2 教学安排
--视频
-1.3 什么是操作系统
--Video
-1.4 为什么学习操作系统,如何学习操作系统
--Video
-1.5 操作系统实例
--视频
-1.6 操作系统的演变
--视频
-1.7 操作系统结构
--视频
-2.1 前言和国内外现状
-2.2 OS实验目标
-2.3 8个OS实验概述
-2.4 实验环境搭建
-2.5 x86-32硬件介绍
-2.6 ucore部分编程技巧
-2.7 演示实验操作过程
--Q6
--Q7
--Q10
-3.1 BIOS
--3.1 BIOS
-3.2 系统启动流程
-3.3 中断、异常和系统调用比较
-第三讲 启动、中断、异常和系统调用--3.3 中断、异常和系统调用比较
-3.4 系统调用
--3.4 系统调用
-第三讲 启动、中断、异常和系统调用--3.4 系统调用
-3.5 系统调用示例
-3.6 ucore+系统调用代码
-4.1 启动顺序
--4.1 启动顺序
-4.2 C函数调用的实现
-4.3 GCC内联汇编
-4.4 x86中断处理过程
-4.5 练习一
--4.5 练习一
-4.6 练习二
--4.6 练习二
-4.7 练习三
--4.7 练习三
-4.8 练习四 练习五
-4.9 练习六
--4.9 练习六
-5.1 计算机体系结构和内存层次
-5.2 地址空间和地址生成
-5.3 连续内存分配
-5.4 碎片整理
--5.4 碎片整理
-5.5 伙伴系统
--5.5 伙伴系统
-第五讲 物理内存管理: 连续内存分配--5.6 练习
-6.1 非连续内存分配的需求背景
-6.2 段式存储管理
-- 6.2 段式存储管理
-6.3 页式存储管理
-6.4 页表概述
--6.4 页表概述
-6.5 快表和多级页表
-6.6 反置页表
--6.6 反置页表
-6.7 段页式存储管理
-第六讲 物理内存管理: 非连续内存分配--6.8 练习
-7.1 了解x86保护模式中的特权级
-第七讲 实验二 物理内存管理--7.1 了解x86保护模式中的特权级
-7.2 了解特权级切换过程
-第七讲 实验二 物理内存管理--7.2 了解特权级切换过程
-7.3 了解段/页表
-第七讲 实验二 物理内存管理--7.3 了解段/页表
-7.4 了解UCORE建立段/页表
-第七讲 实验二 物理内存管理--7.4 了解UCORE建立段/页表
-7.5 演示lab2实验环节
-8.1 虚拟存储的需求背景
-8.2 覆盖和交换
-8.3 局部性原理
-8.4 虚拟存储概念
-8.5 虚拟页式存储
-8.6 缺页异常
--8.6 缺页异常
-9.1 页面置换算法的概念
-9.2 最优算法、先进先出算法和最近最久未使用算法
-第九讲 页面置换算法--9.2 最优算法、先进先出算法和最近最久未使用算法
-9.3 时钟置换算法和最不常用算法
-第九讲 页面置换算法--9.3 时钟置换算法和最不常用算法
-9.4 Belady现象和局部置换算法比较
-第九讲 页面置换算法--9.4 Belady现象和局部置换算法比较
-9.5 工作集置换算法
-第九讲 页面置换算法--9.5 工作集置换算法
-9.6 缺页率置换算法
-第九讲 页面置换算法--9.6 缺页率置换算法
-9.7 抖动和负载控制
-10.1 实验目标:虚存管理
-第十讲 实验三 虚拟内存管理--10.1 实验目标:虚存管理
-10.2 回顾历史和了解当下
-第十讲 实验三 虚拟内存管理--10.2 回顾历史和了解当下
-10.3 处理流程、关键数据结构和功能
-第十讲 实验三 虚拟内存管理--10.3 处理流程、关键数据结构和功能
-10.4 页访问异常
-第十讲 实验三 虚拟内存管理--10.4 页访问异常
-10.5 页换入换出机制
-第十讲 实验三 虚拟内存管理--10.5 页换入换出机制
-11.1 进程的概念
-第十一讲 进程和线程--11.1 进程的概念
-11.2 进程控制块
-第十一讲 进程和线程--11.2 进程控制块
-11.3 进程状态
-第十一讲 进程和线程--11.3 进程状态
-11.4 三状态进程模型
-11.5 挂起进程模型
-第十一讲 进程和线程--11.5 挂起进程模型
-11.6 线程的概念
-第十一讲 进程和线程--11.6 线程的概念
-11.7 用户线程
-第十一讲 进程和线程--11.7 用户线程
-11.8 内核线程
-第十一讲 进程和线程--11.8 内核线程
-12.1 进程切换
-第十二讲 进程控制--12.1 进程切换
-12.2 进程创建
-第十二讲 进程控制--12.2 进程创建
-12.3 进程加载
-第十二讲 进程控制--12.3 进程加载
-12.4 进程等待与退出
-第十二讲 进程控制--12.4 进程等待与退出
-13.1 总体介绍
-13.2 关键数据结构
-13.3 执行流程
-13.4 实际操作
-14.1 总体介绍
-14.2 进程的内存布局
-14.3 执行ELF格式的二进制代码-do_execve的实现
--14.3 执行ELF格式的二进制代码-do_execve的实现
-14.4 执行ELF格式的二进制代码-load_icode的实现
--14.4 执行ELF格式的二进制代码-load_icode的实现
-14.5 进程复制
-14.6 内存管理的copy-on-write机制
-15.1 处理机调度概念
-第十五讲 处理机调度--15.1 处理机调度概念
-15.2 调度准则
-15.3 先来先服务、短进程优先和最高响应比优先调度算法
--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-第十五讲 处理机调度--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
--15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
-第十五讲 处理机调度--15.4 时间片轮转、多级反馈队列、公平共享调度算法和uc
-15.5 实时调度和多处理器调度
-第十五讲 处理机调度--15.5 实时调度和多处理器调度
-15.6 优先级反置
-第十五讲 处理机调度--15.6 优先级反置
-16.1 总体介绍和调度过程
-16.2 调度算法支撑框架
-16.3 时间片轮转调度算法
-16.4 Stride调度算法
-17.1 背景
--17.1 背景
-17.2 现实生活中的同步问题
-第十七讲 同步互斥--17.2 现实生活中的同步问题
-17.3 临界区和禁用硬件中断同步方法
-第十七讲 同步互斥--17.3 临界区和禁用硬件中断同步方法
-17.4 基于软件的同步方法
-第十七讲 同步互斥--17.4 基于软件的同步方法
-17.5 高级抽象的同步方法
-第十七讲 同步互斥--17.5 高级抽象的同步方法
-18.1 信号量
--18.1 信号量
-第十八讲 信号量与管程--18.1 信号量
-18.2 信号量使用
-第十八讲 信号量与管程--18.2 信号量使用
-18.3 管程
--18.3 管程
-第十八讲 信号量与管程--18.3 管程
-18.4 哲学家就餐问题
-18.5 读者-写者问题
-19.1 总体介绍
-19.2 底层支撑
-第十九讲 实验七 同步互斥--19.2 底层支撑
-19.3 信号量设计实现
-第十九讲 实验七 同步互斥--19.3 信号量设计实现
-19.4 管程和条件变量设计实现
-第十九讲 实验七 同步互斥--19.4 管程和条件变量设计实现
-19.5 哲学家就餐问题
-20.1 死锁概念
-第二十讲 死锁和进程通信--20.1 死锁概念
-20.2 死锁处理方法
-第二十讲 死锁和进程通信--20.2 死锁处理方法
-20.3 银行家算法
-第二十讲 死锁和进程通信--20.3 银行家算法
-20.4 死锁检测
-第二十讲 死锁和进程通信--20.4 死锁检测
-20.5 进程通信概念
-第二十讲 死锁和进程通信--20.5 进程通信概念
-20.6 信号和管道
-第二十讲 死锁和进程通信--20.6 信号和管道
-20.7 消息队列和共享内存
-第二十讲 死锁和进程通信--20.7 消息队列和共享内存
-21.1 文件系统和文件
-第二十一讲 文件系统--21.1 文件系统和文件
-21.2 文件描述符
-第二十一讲 文件系统--21.2 文件描述符
-21.3 目录、文件别名和文件系统种类
-第二十一讲 文件系统--21.3 目录、文件别名和文件系统种类
-21.4 虚拟文件系统
-第二十一讲 文件系统--21.4 虚拟文件系统
-21.5 文件缓存和打开文件
-第二十一讲 文件系统--21.5 文件缓存和打开文件
-21.6 文件分配
-第二十一讲 文件系统--21.6 文件分配
-21.7 空闲空间管理和冗余磁盘阵列RAID
-第二十一讲 文件系统--21.7 空闲空间管理和冗余磁盘阵列RAID
-22.1 总体介绍
-第二十二讲 实验八 文件系统--22.1 总体介绍
-22.2 ucore 文件系统架构
-第二十二讲 实验八 文件系统--22.2 ucore 文件系统架构
-22.3 Simple File System分析
-第二十二讲 实验八 文件系统--22.3 Simple File System分析
-22.4 Virtual File System分析
-第二十二讲 实验八 文件系统--22.4 Virtual File System分
-22.5 I/O设备接口分析
-第二十二讲 实验八 文件系统--22.5 I/O设备接口分析
-22.6 执行流程分析
-23.1 I/O特点
--视频
-第二十三讲 I/O子系统--23.1 I/O特点
-23.2 I/O结构
--816C80A0F5E3B8809C33DC5901307461
-第二十三讲 I/O子系统--23.2 I/O结构
-23.3 I/O数据传输
--C58221E14388B9DB9C33DC5901307461
-第二十三讲 I/O子系统--23.3 I/O数据传输
-23.4 磁盘调度
--567A3F1FCBFB3F4C9C33DC5901307461
-第二十三讲 I/O子系统--23.4 磁盘调度
-23.5 磁盘缓存
--C327536B80D25CE79C33DC5901307461
-第二十三讲 I/O子系统--23.5 磁盘缓存
-html
--html