0 00:00:00,000 --> 00:00:06,880 1 00:00:06,920 --> 00:00:07,920 接下来我们再看一下 2 00:00:07,960 --> 00:00:11,680 I/O设备的一个接口分析 3 00:00:11,720 --> 00:00:12,240 首先我们看一下 4 00:00:12,280 --> 00:00:15,360 I/O设备接口的一个大致位置 5 00:00:15,400 --> 00:00:17,240 它在我们整个文件系统的 6 00:00:17,280 --> 00:00:18,800 靠底下这一部分 7 00:00:18,840 --> 00:00:22,200 它呢首先向上和我们VFS有一个接口 8 00:00:22,240 --> 00:00:25,360 使得它也能够被我们VFS统一管理 9 00:00:25,400 --> 00:00:26,720 同时呢 它也和我们 10 00:00:26,760 --> 00:00:28,560 具体文件系统有一个接口 11 00:00:28,600 --> 00:00:30,160 使得具体文件系统向它 12 00:00:30,200 --> 00:00:33,240 可以发出读 写 控制等请求 13 00:00:33,280 --> 00:00:34,400 向下呢它还进一步 14 00:00:34,440 --> 00:00:36,560 和我们的驱动有一个接口 15 00:00:36,600 --> 00:00:38,160 使得和不同的外设 16 00:00:38,200 --> 00:00:40,320 比如我们的硬盘 我们的串口 17 00:00:40,360 --> 00:00:44,000 我们的屏幕等等进行对接 18 00:00:44,040 --> 00:00:47,440 完成最底层的数据的访问 19 00:00:47,480 --> 00:00:53,280 这是I/O接口这一块大致的一个功能 20 00:00:53,320 --> 00:00:54,560 这里面很关键一个结构 21 00:00:54,600 --> 00:00:56,280 就是device这么一个结构 22 00:00:56,320 --> 00:00:57,720 可以看出来它和我们前面 23 00:00:57,760 --> 00:00:59,480 inode的定义相似之处 24 00:00:59,520 --> 00:01:00,920 它也是一系列函数指针 25 00:01:00,960 --> 00:01:03,000 和一些成员变量组成 26 00:01:03,040 --> 00:01:05,760 特别是open close I/O 27 00:01:05,800 --> 00:01:07,080 还有I/O control 28 00:01:07,120 --> 00:01:09,920 那么open close和我们前面讲的 29 00:01:09,960 --> 00:01:11,560 Inode 的open close是一个意思 30 00:01:11,600 --> 00:01:13,680 就是打开设备 关闭设备 31 00:01:13,720 --> 00:01:17,560 I/O呢它用一个这个来表示读或者写 32 00:01:17,600 --> 00:01:19,320 I/O control是用来表示什么 33 00:01:19,360 --> 00:01:20,680 表示一些 通常读写 34 00:01:20,720 --> 00:01:22,360 不太方便表示的一些操作 35 00:01:22,400 --> 00:01:24,760 比如说我要完成对某个设备的控制 36 00:01:24,800 --> 00:01:26,880 它不是读也不是写 37 00:01:26,920 --> 00:01:28,400 那么就需要有一个 特殊的一个 38 00:01:28,440 --> 00:01:33,320 函数的指针来完成 39 00:01:33,360 --> 00:01:36,080 它怎么和我们VFS进行对接呢 40 00:01:36,120 --> 00:01:37,880 在这里面它还有一个成员变量 41 00:01:37,920 --> 00:01:41,840 是对接着这里面的FS 可以看出来 42 00:01:41,880 --> 00:01:44,080 一个device是属于一个特殊的 43 00:01:44,120 --> 00:01:46,280 device VFS这么一个结构 44 00:01:46,320 --> 00:01:49,360 而device VFS呢 会挂到一个 45 00:01:49,400 --> 00:01:51,600 VFS一个总体框架之下 46 00:01:51,640 --> 00:01:54,600 从而完成了在VFS这个层面 47 00:01:54,640 --> 00:01:56,800 对device的一个有效的管理 48 00:01:56,840 --> 00:02:00,440 49 00:02:00,480 --> 00:02:02,200 那我们可以再结合 50 00:02:02,240 --> 00:02:05,360 整个device的初始化过程 51 00:02:05,400 --> 00:02:07,720 来了解怎么来实现 52 00:02:07,760 --> 00:02:09,840 对device的一个访问 53 00:02:09,880 --> 00:02:12,920 当然这个访问是通过VFS来实现的 54 00:02:12,960 --> 00:02:14,880 这里面并没有拿我们SFS 55 00:02:14,920 --> 00:02:17,800 所直接对接的disk来做一个介绍 56 00:02:17,840 --> 00:02:19,760 而是以另外两个设备 57 00:02:19,800 --> 00:02:22,880 就是stdin或者stdout 58 00:02:22,920 --> 00:02:25,640 stdout是往串口和显示器 59 00:02:25,680 --> 00:02:28,080 输出这么一个设备 60 00:02:28,120 --> 00:02:31,520 而stdin呢是接收键盘输入一个设备 61 00:02:31,560 --> 00:02:33,120 那么我们希望大家通过 62 00:02:33,160 --> 00:02:34,560 对这两个设备的了解 63 00:02:34,600 --> 00:02:37,280 来进一步自己去分析 64 00:02:37,320 --> 00:02:39,200 对于disk这么一个device 65 00:02:39,240 --> 00:02:40,920 怎么进行初始化的 66 00:02:40,960 --> 00:02:43,360 可以看出来 这是我们最早的那个 67 00:02:43,400 --> 00:02:45,960 uCore开始启动的时候 68 00:02:46,000 --> 00:02:47,960 做初始化的总控函数 69 00:02:48,000 --> 00:02:49,720 在这里面会增加一部分 70 00:02:49,760 --> 00:02:51,400 这一部分是fs_init 71 00:02:51,440 --> 00:02:54,600 这是lab8的一个增加的一部分内容 72 00:02:54,640 --> 00:02:56,000 在fs_init里面呢 73 00:02:56,040 --> 00:02:59,480 会进一步调device的init 74 00:02:59,520 --> 00:03:01,400 OK 这里面又会进一步 75 00:03:01,440 --> 00:03:02,680 调好几个不同类型的 76 00:03:02,720 --> 00:03:04,320 device的一个初始化 77 00:03:04,360 --> 00:03:06,720 先拿stdout来举例 78 00:03:06,760 --> 00:03:09,120 stdout呢会创建一个inode 79 00:03:09,160 --> 00:03:11,720 这个inode是专门针对device的inode 80 00:03:11,760 --> 00:03:14,160 这就把我们的device和inode 81 00:03:14,200 --> 00:03:15,360 建立了一个联系 82 00:03:15,400 --> 00:03:18,120 同时还有一个stdout_device_init 83 00:03:18,160 --> 00:03:19,880 那么这个呢 是完成了 84 00:03:19,920 --> 00:03:23,720 对它的函数的一个对接 85 00:03:23,760 --> 00:03:25,400 还有一个vfs_add_dev 86 00:03:25,440 --> 00:03:27,480 从而使这个device可以加入到 87 00:03:27,520 --> 00:03:32,160 这个VFS整个的管理之中来 88 00:03:32,200 --> 00:03:32,920 进一步可以看看这个 89 00:03:32,960 --> 00:03:34,960 device_init做什么事情 90 00:03:35,000 --> 00:03:38,880 它把刚才device所针对那些函数指针呢 91 00:03:38,920 --> 00:03:41,600 跟我们具体函数进行了对接 92 00:03:41,640 --> 00:03:44,720 包括了open close还有I/O 93 00:03:44,760 --> 00:03:47,360 这个I/O就是读 写的什么操作 94 00:03:47,400 --> 00:03:48,560 大家想一想 95 00:03:48,600 --> 00:03:52,640 这是stdout 那是一个写操作 96 00:03:52,680 --> 00:03:54,000 还有是一个control 97 00:03:54,040 --> 00:03:57,080 表明一些特殊操作 用control来表示 98 00:03:57,120 --> 00:04:00,160 这就是stdout一个device的初始化过程 99 00:04:00,200 --> 00:04:01,720 在这个初始化过程中我们可以看到 100 00:04:01,760 --> 00:04:05,640 它创建了inode 和VFS进行了对接 101 00:04:05,680 --> 00:04:08,480 把自己的一些特定的函数 102 00:04:08,520 --> 00:04:11,680 以device里面的虚函数指针进行了对接 103 00:04:11,720 --> 00:04:13,480 那么完成这些工作之后 104 00:04:13,520 --> 00:04:15,000 我们在VFS层面呢 105 00:04:15,040 --> 00:04:19,640 就可以有效地访问这个device了 106 00:04:19,680 --> 00:04:22,160 同理我们看一下stdin 这是输入 107 00:04:22,200 --> 00:04:23,800 相对是read操作 108 00:04:23,840 --> 00:04:25,680 那么跟前面不同在哪呢 109 00:04:25,720 --> 00:04:28,680 就在一个地方dev_init_stdin 110 00:04:28,720 --> 00:04:33,520 同时也一样有一个stdin一个device_init 111 00:04:33,560 --> 00:04:35,400 它和前面操作是类似的 112 00:04:35,440 --> 00:04:38,520 它也建立它自己一套函数体系 113 00:04:38,560 --> 00:04:41,760 和device函数指针进行对接 114 00:04:41,800 --> 00:04:43,080 其它两部分是一样的 115 00:04:43,120 --> 00:04:47,200 创建一个inode 和绑定VFS 116 00:04:47,240 --> 00:04:48,800 但这个对接有点不太一样 117 00:04:48,840 --> 00:04:53,760 它的I/O这个操作是对应stdin的I/O 118 00:04:53,800 --> 00:04:56,880 那这个是什么呢 是一个读操作 119 00:04:56,920 --> 00:04:59,880 因为它是需要从键盘读入数据 120 00:04:59,920 --> 00:05:02,200 还有一个不同在哪 在这儿 121 00:05:02,240 --> 00:05:05,440 它增加了一个等待队列的设置 122 00:05:05,480 --> 00:05:09,160 为什么会增加这么一个设置 大家想一想 123 00:05:09,200 --> 00:05:12,200 其实有可能 当它想去发出读请求之后 124 00:05:12,240 --> 00:05:13,680 不能马上得到回应 125 00:05:13,720 --> 00:05:16,160 在这个时候 由于资源得不到满足 126 00:05:16,200 --> 00:05:17,400 它需要去睡眠 127 00:05:17,440 --> 00:05:18,840 从而可以把CPU让出来 128 00:05:18,880 --> 00:05:20,680 这是我们前面讲同步互斥的时候 129 00:05:20,720 --> 00:05:22,040 涉及到的一些概念 130 00:05:22,080 --> 00:05:24,640 可以看出来在file system里面 131 00:05:24,680 --> 00:05:26,840 整个大的框架里面呢 132 00:05:26,880 --> 00:05:28,520 会涉及到进程 同步互斥 133 00:05:28,560 --> 00:05:30,160 内存管理等多方面内容 134 00:05:30,200 --> 00:05:32,680 是对我们前面一系列实验的 135 00:05:32,720 --> 00:05:35,360 进一步补充完善和使用 136 00:05:35,400 --> 00:05:35,440