当前课程知识点:操作系统 > 第二讲 实验零 操作系统实验环境准备 > 2.7 演示实验操作过程 > 2.7 演示实验操作过程
接下来给大家demo一下
有关lab0的一些实验环节
特别是实验环节的一些建立的过程
可以看到我们现在
已经打开virtualBox虚拟的这个模拟器
那在virtualBox里面呢
我们其实已经建立好了一个叫moocos.lab
这么一个虚拟的硬盘
这里面可以看出这个配置怎么回事呢
我们配置这个Ubuntu64一个环境
有4G的内存
然后这是一些显卡等等
这个就是一些常规的设置
比较重要是这个硬盘
我们这个硬盘已经建立好了
叫mooc-os.vdi
给它虚拟了8G这个内存空间
还有网卡
我们可以看看点击 启动
那它就开始模拟一台计算机启动
在这个启动过程中呢
可以看到Ubuntu的一个启动过程
我们接下来的操作呢
基本上就是在
这个Ubuntu环境中来完成的
那可以看出来这里面
这是一个linux Ubuntu的一个环境
那我们用14.04这么一个版本
我们首先进入全屏模式
好 你可以看到现在进入全屏模式
其实就和我们在一般的linux操作
是差不多的了
那在这里面呢 我们打开一个shell
那我们的这个实验环境
是放在moocos下面的
那我们可以看到所有的
code放在ucor_lab下面
这里面有两部分
一部分是labcodes
可以看到lab1到lab8
需要去填空的代码放在这儿了
但是呢我们也提供了答案
这是lab1到lab8的答案
如果大家确实做不出来的话
也可以参考相应的答案
以及做出来之后
可以跟这个参考答案做一个对比
这里面呢没有绝对的对错
只是做一个参考而已
那接下来我们可以看到
我们已经用到了OS命令是吧显示目录
pwd呢是显示当前目录 还有什么呢
比如说我们再建一个目录
那会看到多了一个test目录
当然我们也可以做比如把前面那个
这么一个文件移到这儿来
移到当前目录下
当前目录下
那可以看到test多了这么一个文件
还有呢 我可以把它删除
这个文件就没有了
这是简单的创建目录显示
然后移动文件
还有创建文件等等
都可以用这个来实现
那这是所谓的通常的
基于这个shell的一些操作命令
当然我们也可以
通过一种图形界面方式
比如打开这个
这是一个类似于资源管理器
你也可以在这里面打开moocos
我们刚才看到这个mooclab
然后看到test
那你可以采取这种图形界面方式改名
test2这种改名
删除呢 move to trash移到垃圾箱里面去
看这儿可以看到
还可以恢复它
这儿
restore那在这儿我可以把它彻底的删掉
shift delete 那就可以把它彻底删掉了
那这也是通过这种图形界面来使用
很多同学可能对这个也比较熟悉
这是一些
常见的一些对文件的一些访问
还有一个就是什么呢
我们开发环境中也有一些命令
比如说gcc你可以看到
我们这里面有是有gcc的代码
还有gdb 退出quit
退出这个gdb的代码 make等等
另一方面我们还可以看到
我们希望有一个很方便
来完成我们实验的一个环境
当然我们完全可以
用这种字符方式来完成
就基于命令行的方式
举个例子比如说
我们现在到lab_answer目录下
然后看一下lab1
比如make clean一下
make clean这时候因为有makefile
所以make clean找Mmake file
然后来执行clean这个命令
会把相应的这些
生成的这些执行文件给删除掉
那我们make 回车
那你看到它整个编译过程
会把虚拟磁盘镜像给建立好
这里面包含了kernel
在bin目录下有kernel这么一个文件
如果用file看一下的话
这个文件可以看到
它是一个可执行的一个文件
它会把我们bootloader给加进去
那bootloader放哪呢
它这个Bin目录下还有一个什么文件呢
ucore.img这实际上就是
我们用到bootloader它生成一个磁盘镜像
这个磁盘镜像包含了bootloader
以及ucore的这个kernel
我们怎么来运行它呢
make qemu 那么它会调qemu来执行它
这里面可以看到这是lab1
其实lab1的代码 我们只是来做测试一下
可以看出来它可以跑起来了
而且这个时钟中断可以正常工作
这是一个qemu它可以通过串口输出
也可以输到屏幕上
这是ctrl c
Ctrl c整个中断了
那么又回到了初始状态
看到我们这里面
当你做完make时候呢
它生成了很多文件
包括obj文件 包括bin文件等等
那我们可以去编辑它
比如说我们曾经说过有vim
看一下这个Mmake file什么内容
那可以看到这里面
有定义很多的一些变量
当然这些变量都是
符合makefile的语法格式的
大家需要去了解
我们现在退出了vim
当然这些操作都是字符方式
如果大家对字符方式很熟的话
用字符方式足够了
但是也有很多同学
可能不太熟悉这种字符方式
需要跟windows类似的
图形化的一种操作界面
那我们这里面也提供了
比如说我们这里面建立了
这个eclipse-CDT环境
单击一下可以把它打开
稍微等一下
因为它有一个加载的过程
我们这里面可以看到是一个
比如说我们到一个c++的一个开发环境中
我们可以看到我们把刚才
这个lab1_ans的目录导进来了
可以看到这是一个Project
这是C的一个Project
其实是lab1的工程
这里面包含了我们所有代码
比如说这里面是boot代码
你要想看这个代码点击一下 双击一下
那么就可以看它的源代码
就可以去分析它 这里面有c
有足够的注释 这是bootmain.c
这是bootloader主体函数
它负责加载
我们可以看到这里面
比如这个readseg只要点一下它
它大致的一个位置可以发现出来
如果敲一下F3 那甚至可以到这个函数
可以跳到这个函数里面来
再敲一下F3 比如到了readsect
那可以到这儿来
它可以跨文件来查找不同函数这种引用
通过它很好的可以来分析源代码
那我们怎么来编译它呢
这在编辑环境中
我们编译它其实在这儿也是一样的
你可以把它这里面有一个build
build Project
因为刚才已经编译过了
现在啥也不用做了
它已经编译好了
如果把它clean掉的话
比如说我们把这个shell打开 make clean
再看它这个obj目录和刚才
看到的bin目录已经消失了
已经被删除了
用rm-r是递归删除的意思
就把这两个目录下的
所有文件都删除了
这个时候我们来切换到
就alt tab切换到这个eclipse环境中来
那我们可以再编译一次
你可以看到刚才的重复这个过程
在命令行在这里面也重现了 那编好了
编好了我们怎么运行它呢
我们特别是希望能够debug是吧
运行已经看到make qemu那debug怎么办
debug的话相对来说需要做一些配置
在这里面 我们可以看着
对于这个Project
我们要有一个debug configure
假定我们已经装了
这个Zylin Embedded debug
那大家可能好奇 这个plug in在哪装呢
其实我们先把这个先关掉可以看一看
在install new software这里面呢
你可以看到我们当时装这个地址在这儿
这么一个地址
把它敲进去之后呢
就可以查找它的那个plug in那个主键
那么可以看到
另一方面其实你也可以看着
这里面已经安装的主键
在这儿 installation Detalls
可以看出来装好了这个软件
那么同学可以先把这个软件装好
就可以用来便于我们做调试
我们再回头来看看这个配置
有了这个之后呢
我们在这个debug configuration里面呢
会有一个lab1的一个配置
这个名字随便敲
我们这里面叫lab1 ans Default
那Projectlab也是一个optional
这是随便填的
debugger这很重要
你要选择哪种debugger
我们这边就用了EmbeddedGDB
然后stop on startup at bootmain
我们想停在刚才说的bootloader
这个函数里面
这里面写个bootmain
或者把它关掉也行
因为我们在后面Commands里面
也会在这儿有一个gdb命名break
好 bootmain 这是设置debug
到底用哪个debugger呢
所以用的gdb的debugger
这是一个命令行方式的一个调试工具
我们这里面只是把它加个壳
可以更方便在eclipseide环境中
来调试应用程序
其它这些设置保持不变
这里面commands相当于是说
当如果我们要启动这个调试的时候
需要做的一些工作
这里面工作包括
怎么来跟qemu建立一个连接
从而可以控制qemu来调试我们的lab1
这里面有一些命令你大致能理解一些
这是用来完成对qemu的连接
这个呢第二行是干什么的呢
你要调bootloader的话
那我们前面已经看到的
在boot目录下的是一个程序
是bootloader
在kern目录下是另一个程序
是我们ucore
bootloader会加载ucore
那所以说在这里面呢
我们首先要把bootloader
这个符号加载进来
用这个命名
这是一个在obj目录下
有个bootblock.o
这个文件实际上
是bootloader的主体执行程序
它里面包含了符号信息
比如这个函数它的位置有break bootmain
等于是说在bootmain所对应的
那个虚拟地址里面呢
设置一个断点
这是gdb初始化命名
所以continue是让它执行
在这个执行之前
首先要把我们说的这个qemu启起来
那么这里面我们也配好了一个
外部工具来启qemu
比如说在这里面你可以看到
我们准备了一个什么工具呢
lab1ans有一个运行一个make命令
make命令会根据makefile里面
查找一个gdb一个选项
然后make gdb就可以把qemu提起来
我们可以看一看
假设我们在这里面run一下
这所有操作都在这个集成开发环境里面
选择外部工具 你可以看着qemu在等待
等待跟gdb建立一个联系
处于一个刚开始运行的状态
然后如果我们现在之后
再运行一下debug这个的话
那我们就可以看到 就会有些问题
我们这里面
可以看到qemu先把它设在最前端
这样可以时刻观察它的变化
它问你是否要进入
一个debug一个view的一个状态
我们认为yes
因为我们需要在debugview下面
更好来调试和分析我们程序
你看到现在这个已经断在了debug
你看debug current指令指针
我们接下来干什么呢
很简单就像我们通常
调应用程序一样 step Over
就是跳过这个函数去执行它
它为什么会跳几下
是由于它这个做了优化
使得这个地址和源码之间的
对应关系并不是完全对应好的
如果你不做任何优化就可以对上
这里面我们可能好奇
这个ph到底是多少值 它现在是零
因为一开始还没有做赋值
做完这个赋值之后就不应该是零了
可以看到什么呢
再看ph 它已经赋了一个值
可以看出来这种方式
就可以把这个程序的执行过程
很容易的分析清楚
在这里面需要注意
我们如果要调试ucore
为此我们需要把ucore
那个符号信息加载进来
在这里面我们会到Console这个里面呢
会把这个加进来 在哪加呢
会把这个叫做file bin kernel加进来
reading symbols读进来之后呢
这里面有一个起止函数
这是ucore那个最开始跑的
一个c程序的函数
设置好了 然后这时候
我们如果再让它继续运行
你可以看到
它现在已经跑完了就是bootloader的工作
然后把控制权交给了ucore另外一个程序
同时因为我们刚刚设的断点
我们可以接着继续调试它
这里面有一个字符串 message
message等于多少呢
刚才说的THUCST这一块
那么cprint就会打印出来
那我们再继续执行这个函数
可以看到它已经进去了
字符串已经打印出来了
在这边你看着了有这个字符串的显示
如果我们想进入这里面看它的细节
step in 那你就可以看着
它怎么一步步完成这个打印
这是一个简单的调试
当然我们可以看更复杂一点
比如说我们关注的是
刚才那一段c代码对应的汇编代码
就在这边有展示
我还可以看到特定里
关注的一些变量的一些情况
比如说这个等于多少
这里面其实它等于这些已经列出来
etext等于这么一个值 在这里面有展示
这是大致的一个
在这个eclipse环境下来调试这么一个过程
那我们现在要继续运行的话
那它这个跟刚才
我们在用make qemu这种方式是一样的
比如说举个例子
可以看到一个是在eclipse环境下
调试的这一个qemu
第二个呢是直接执行的一个qemu
这两者呢都可以看出来是差不多一个效果
但是这里面有一些不同之处
我们可以对它进行打断来执行
这是它实际上在这儿 这个已经停止了
但另一个qemu还在继续执行
看这个qemu还在执行
那我大致就把这个通过eclipse来调试呢
给大家做了简单的介绍
当然eclipse功能很强大
大家还可以在使用过程中
再进一步去了解和熟悉
它不仅仅是调试
它还可以用来做分析开发等等
这是很好的开发环境
另外一个工具呢
给大家做个简单介绍 Understand
其实向老师也给大家
做过一个简单的介绍
new Project
那c代码和汇编码
那它在哪加一个目录 这个目录在哪呢
其实就你可以指定一下
比如说你的机器的刚才的地址
在这儿 ucorelab
ucorelad answer然后是lab1 result
那这里面选择一个choose
然后ok next
它会帮你做分析 建好这个目录
那这可以看到
关于这里面的一些调用的函数
比如说readline
那我们可以看到它的一个调用关系
readline它调了这么多其它的函数
同时也被kmonitor这个函数调用
这个实际上通过understand
可以更好看到一个它的
一个函数调用关系图
也便于大家对
这个操作系统整体的一个把握
这个工具是用来比较的
比如说举个例子
让我们看看lab1和lab2到底有什么不同
那就可以看出来
它里面展示出来它们之间的不同
比如打开这个文件
那你看lab2就多增加了一些内容
也还有lab1和lab2之间
其它地方的一些不同
也都逐一展示出来了
那可以通过很方便的
一个一个的选择来看出
比较它们之间的一些差异性
这是一个diff的一个图形化的工具
当然还有字符方式diff
这个相对来说比较简单一些
但是呢就是如果分析复杂软件的话
用meld好像比较容易一些
至于apt系列 apt.get来查找安装一些软件
sudo是确保是处于
超级用户的权限才能够安装软件
这属于系统一个工具
那比如刚才cdt空格口令
它已经发现eclipse cdt已经安装了
所以说你不需要再重新安装
那么git呢是用来分析这个版本的
或者是上载版本管理
在这里面git status看当前状态
你现在整个是一个很干净的一个环境
你没有做任何更新
那这里面所以说你的工作clean等等
你还有其它一些命令 git Pull
下载新代码 git push
推你的代码到git池里面去等等
这都是一些常见的命令
如果大家需要了解的话
结合我们的文档中给出的链接
可以去进一步学习一下
那大致的一个调试和整个过程呢
就给大家介绍到这儿
我想还有很多一些细节呢
特别是gdb一些使用呢
其实也有必要
大家去看看它怎么来调试的
你可以用小的应用程序来调试
也可以用刚才说的那个工具
比如说命令行方式也可以调试
我们刚才展示了eclipse方式来调试
比如make debug
那你可以看着我起了qemu一样的
然后它起了一个字符方式的cgdb
那其实一样它也断到了这一点 next
可以看到它走到哪去了
走到了88行 86行 88行到91行等等 p.ph
打出来这个值
如果执行完91行的话
发现它结果是不一样的
刚才我们在那儿实验是一样的
就是你可以选择你不同方式来调试
如果continue 那你可以看着
刚才我们把这个设置成always on top的话
那么我们continue可以看到
它的一个变化过程也很类似
然后ctrl c中断一下
它执行到了一个我们看不到的地方
是100073对应不到源代码
所以是两个问号 这是用gdb来调试一个简单
做退出 quit退出 把这个要关掉
我们可以看着了就是通过不同的方式
有图形方式 有字符方式
都可以用来编辑分析和运行调试
我们的操作系统的实验
这里面还有很多工具
可以值得大家去探索和摸索
关于工具的介绍大致就讲到这里
谢谢大家
-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