学习操作系统原理最好的方法是自己写一个简单的操作系统。


一、硬盘控制器

我们前面已经讲过硬盘控制器是一种I/O接口,CPU通过它就能间接的读写硬盘。硬盘控制器主要有IDE和SATA两种,我们这里只考虑IDE控制器。

电脑里硬盘控制器有2个,一个叫主控制器,另一个叫从控制器。而每个硬盘控制器能连接两个硬盘,一个叫主盘,另一个叫从盘。所以一般一台电脑里最多能安装4个硬盘。

二、硬盘控制器端口

硬盘控制器上的端口很多,下表中只列出我们可能用到的。

I/O端口号 端口用途 端口位数
主控制器 从控制器 读取操作 写入操作
0x1f0 0x170 Data Data 16
0x1f1 0x171 Error Features 8
0x1f2 0x172 Sector count Sector count 8
0x1f3 0x173 LBA low LBA low 8
0x1f4 0x174 LBA mid LBA mid 8
0x1f5 0x175 LBA high LBA high 8
0x1f6 0x176 Device Device 8
0x1f7 0x177 Status Command 8

关于上面这张表,其中的端口号不用记,用的时候翻看一下这里就行。从控制器与主控制器除了端口号不同,其它完全相同,以下我们以主控制器为例讲解。需要注意的是同一个端口在读端口和写端口两种操作下可能用途不一样,比如上表里的0x1f1和0x1f7。

端口0x1f0

首先看第1个端口0x1f0,它是这个表中唯一的16位端口,其它都是8位。从硬盘读取的数据或向硬盘写入的数据都是经过这个端口中转的。之前我们讲过硬盘是按扇区读写的,每个扇区都是512个字节,对硬盘每次读写的数据量都是512字节的整数倍。而这个端口是16位,也就是2个字节。如果你要读取一个扇区的数据,需要从这个端口连续读取256次。同样,写一个扇区,也需要向这个端口连续写入256次。

端口0x1f1

下面来看第二个端口0x1f1,在8个端口中,GrapeOS没有用到这个端口,其它都用到了。虽然没有用到,但还是简单介绍一下。当读操作时,里面保存的是错误信息;当写操作时,曾经需要向该端口写入一些参数,目前已废弃。

端口0x1f2

继续看第三个端口0x1f2,该端口保存的是读取或写入硬盘的扇区数量。该端口是8位端口,取值范围是0~255,但当设置为0时,表示读或写256个扇区。也就是说一次读写操作,最多读写256个扇区。

端口0x1f3~0x1f5

往下3个端口0x1f3、0x1f4、0x1f5是存放读取或写入硬盘时的起始扇区编号。这里用的扇区编号方式叫LBA或LBA28,意思是扇区从0开始编号,用28位二进制数来表示扇区号,最多表示2的28次方个扇区,由于每个扇区512字节,所以最大支持128GB的硬盘。对GrapeOS来说足够了。这里需要注意的是28位是3个半字节,这里的3个端口中,0x1f3存放LBA中的最低1个字节(0 ~ 7位),0x1f4存放中间的那个字节(8 ~ 15位),0x1f5存放高处的那个字节(16 ~ 23位),还剩下最高的半个字节(24 ~ 27位)存放在下个端口0x1f6中。

端口0x1f6

接着看0x1f6端口。这个端口中的低4位存放LBA中的最高4位(24~27位)。第4位0表示主盘,1表示从盘。第6位表示扇区寻址模式,0表示CHS,是一种古老的模式,1表示LBA,我们选LBA。另外第5位和第7位固定为1。参见下表:

bit 内容 说明
7 1 固定为1。
6 MOD 选择寻址模式,0为CHS模式,1为LBA模式。
5 1 固定为1。
4 DEV 选择硬盘驱动器,0为主硬盘,1为从硬盘。
3 [27] LBA地址的第24~27位。
2 [26]
1 [25]
0 [24]

端口0x1f7

我们来看最后一个端口0x1f7,这个端口有两种用途。

如果读取该端口,该端口将作为状态端口,可以获得硬盘的状态信息。如下表所示,该端口8个位中已经有4个位废弃了,有用的是另外4个位。

bit 内容 说明
7 BSY 此位为1表示硬盘正忙,勿扰。
6 DRDY 此位为1表示设备就绪,等待指令。
5 已废弃。
4 已废弃。
3 DRQ 此位为1表示可以从数据端口读写硬盘数据了。
2 已废弃。
1 已废弃。
0 ERR 此位为1表示有错误发生,错误信息见Error寄存器。

如果写入该端口时,该端口将作为命令端口,需要向该端口写入合适的命令。在GrapeOS中只用到两个命令:

  • 读命令:0x20
  • 写命令:0x30

三、硬盘操作方法

在GrapeOS中只有一块硬盘,安装在了主硬盘控制器主盘的位置,下面讲解读写硬盘时的操作步骤。

读硬盘操作步骤

  1. 读取Status端口,如果该端口位7为0,第6位为1,进入下一步,否则循环当前步骤。
  2. 向Sector count端口中写入要读入的扇区数。
  3. 向LBA low、LBA mid、LBA high3个端口依次写入LBA起始扇区号的低24位。
  4. 向Device端口写入LBA起始扇区号的24~27位,并置第4位为0,第6位为1。
  5. 向Command端口写入0x20。
  6. 读取Status端口,如果该端口位7为0,位3为1,则进入下一步,否则循环当前步骤。
  7. 从Data端口读取数据。如果读1个扇区,则循环读取该端口256次。

写硬盘操作步骤

  1. 读取Status端口,如果该端口位7为0,第6位为1,进入下一步,否则循环当前步骤。
  2. 向Sector count端口中写入要写入的扇区数。
  3. 向LBA low、LBA mid、LBA high3个端口依次写入LBA起始扇区号的低24位。
  4. 向Device端口写入LBA起始扇区号的24~27位,并置第4位为0,第6位为1。
  5. 向Command端口写入0x30。
  6. 读取Status端口,如果该端口位7为0,位3为1,则进入下一步,否则循环当前步骤。
  7. 向Data端口写入数据。如果写入1个扇区,则循环写入该端口256次。

读硬盘操作和写硬盘操作都是7个步骤,其中只有第5步和第7步不同,其它步骤完全相同。


本讲视频版地址:https://www.bilibili.com/video/BV1854y1M7vx/

配套的代码与资料在:https://gitee.com/jackchengyujia/grapeos-course

GrapeOS操作系统交流QQ群:643474045

自己动手从零写桌面操作系统GrapeOS系列教程——19.硬盘读写理论知识的更多相关文章

  1. 别人写的一个Bootstrap系列教程

    http://www.cnblogs.com/lansy/category/659061.html

  2. 一个人写的操作系统 - Sparrow OS

    一个人写的操作系统 - Sparrow OS 自己写一个操作系统,这是在过去的几年里我一直为之努力的目标,现在终于完成了. 缘起 自己动手写操作系统的动机最初来自于学习Linux遇到的困难. 我是一个 ...

  3. 自制 os 极简教程1:写一个操作系统有多难

    为什么叫极简教程呢?听我慢慢说 不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统.我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识.不论是为了 ...

  4. 【操作系统】关于Linux桌面操作系统

    以前是Win+Ubuntu+黑苹果,周末想体验一下deepin,于是简单安装了一下,安装过程很简单,这里不再描述.安装之后,第一次打开系统,确实很惊艳,赏心悦目的操作系统. 之前用Ubuntu时候,C ...

  5. 盘点|2021年最受欢迎Linux桌面操作系统前十名

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 阿里云开源镜像站利用云服务上的优势,提供快速.稳定的镜像分发服务.和免费的CDN加速服务.更新频率高,基本上一天一更新,对于Centos/Ubun ...

  6. 手把手教你从零写一个简单的 VUE

    本系列是一个教程,下面贴下目录~1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 今天给大家带来的是实现一个简单的类似 VUE 一样的前端框架,VUE 框架现在应 ...

  7. 《一步一步写嵌入式操作系统》读书笔记1—Skyeye介绍、安装和HelloWorld

    2013-11-14 最近在看<一步一步写嵌入式操作系统>,感觉此书甚好,许多地方讲得很清楚.可操作性强,计划边读边实践边写笔记,希望能够逐步熟悉嵌入式操作系统底层的东西,最终剪裁出一套实 ...

  8. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

  9. Zedboard学习(一):移植Ubuntu桌面操作系统 标签: ubuntu移植zedboardFPGA 2017-07-04 21:53 26人阅读

    环境准备: 首先,需要的肯定是Ubuntu操作系统.可以在自己的电脑上安装物理机,也可以是虚拟机下运行的.我的是在Vmware下运行的Ubuntu14.04 32位操作系统. 由于zedboard上的 ...

  10. 27、从零写UVC驱动之分析数据传输(设置ubuntu通过串口打印,指定打印到文件,ubuntu切换root用户)

    A. 设置ubuntu让它从串口0输出printk信息a. 设置vmware添加serial port, 使用文件作为串口(在vmware中设置,文件是保存在windows中)b. 启动ubuntu, ...

随机推荐

  1. Tomcat 性能监控与调优

    Tomcat 性能监控与调优 Tomcat 远程 Debug JDWP bin/startup.sh 修改最后一行(添加 jpda) exec "$PRGDIR"/"$E ...

  2. 重写react-navigation的stackNaviagtor产生的默认导航栏header样式

    主要是默认的stackNavigator产生的效果,很难看 重写这个阴影,在当前路由配置的 navigationOptions里的 headerStyle写样式 navigationOptions:{ ...

  3. <<Python编程:从入门到实践>>踩坑记 Django

    <<Python编程:从入门到实践>>踩坑记 Django Django Python 19.1.1.5 模板new_topic 做完书上的步骤后,对主题添加页面经行测试,但是 ...

  4. noi 1.1 4 保留三位的浮点数

    描述 输入一个单精度浮点数,保留3位小数输出这个浮点数. 输入 只有一行,一个单精度浮点数. 输出 也只有一行,输入的单精度浮点数. 样例输入 12.34521 样例输出 12.345 题意 就是输入 ...

  5. maven父子项目,由于pom文件中的<packaging>pom</packaging>导致报数据源配置错误

    啊啊啊~~~ 又是踩坑的一天!!! 我在子模块中进行开发,然后子模块的pom文件中也写了<packaging>pom</packaging>导致报数据源配置错误.具体内容如下图 ...

  6. Jmeter-接口测试(三)

    一.jmeter接口关联 1.正则表达式实现接口关联 正则表达式可以这样测试 2.jsonpath表达式实现接口关联(只能作用于返回值是token的) 从根目录开始找$.token 从任意目录开始找( ...

  7. 创建一个Openpyxl

    from openpyxl import Workbook wb = Workbook(r'C:\Users\yjiang3\Desktop\23.xlsx') ws = wb.active from ...

  8. Navicat Premium 12 安装破解过程 (经过测试)

    @ 目录 下载安装 下载 解压文件目录 安装使用步骤截图 1. 安装navicat120_premium_cs_x64.exe 软件 2. 解压Navicat.Premium 破解补丁.rar 3. ...

  9. MSVC-用于其他IDE的手工环境配置,手工提取

    ​ 最近因为在使用Code::Blocks编程,遇到了MSVC编译的库,不愿意换VS,所以手工配置了MSVC路径.CB是有点老了,不像现在新的IDE都是自动搜索的,而且我又不会批处理orz. 这里面可 ...

  10. sql优化分三个方向

    SQL 规范性检查 select 检查 UDF 用户自定义函数 SQL 语句的 select 后面使用了自定义函数 UDF,SQL 返回多少行,那么 UDF 函数就会被调用多少次,这是非常影响性能的. ...