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


一、硬盘控制器

我们前面已经讲过硬盘控制器是一种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. Python 默认环境

    查看pip默认安装目录 python -m site 查看已安装 pip list installed 查看安装位置 pip show PyMySQL

  2. 27 python 发送短信

    腾讯云短信服务,来进行发送短信. 注册账号 开通服务 + 缴费 (实名.企业认证,公众号) API服务.SDK服务 API,接口 import requests # 在此之前还会处理签名和加密的工作量 ...

  3. json字符串让里面的""和null不显示出来

    工具类 ------------------------------------------------------------------------------------------------ ...

  4. 关于unity游戏的类名查找

    这里我用火影演示 首先我们知道,鸣人的决斗场技能代码为900010151,0251,0351,0451等等 我们进行搜索 然后再转到第二个进去(第一个为忍者技能的序列表) 注:序列表里的代码与那个他相 ...

  5. vue后台管理系统——订单管理模块

    电商后台管理系统的功能--订单管理模块 1. 订单管理概述 订单管理模块用于维护商品的订单信息, 可以查看订单的商品信息.物流信息,并且可以根据实际的运营情况对订单做适当的调整. 2. 订单列表 在c ...

  6. vue实现按钮多选

    需求是这样: 首先考虑使用elementui中的组建实现,但是有时候会忽略组建.实现方式两种: 1.直接使用element实现 let weekTimeData: [ '星期一', '星期二', '星 ...

  7. Vue中的input输入框无法输入强制渲染

    刚开始以为是键盘的问题,然后发现别的地方都可以输入,唯独这个input无法输入,可能因为我循环嵌套了三次,太深入无法渲染 后来我发现这个方法可以使用 1 <el-input 2 v-model= ...

  8. verilog 硬件描述语言

    第一章 绪论 verilog--数字电路设计技术--ASIC/SOC芯片设计--协议pcie SATA USB--系统知识(个人计算机,芯片组,网络连接,嵌入式系统,硬件和软件的互操作) 第二章 寄存 ...

  9. ESP32(WeMos D1 R32)开发资料

    1.乐鑫官网 2.ESP32踩坑 ESP32控制摇杆,定义sw的引脚时一定要设置为上拉才行. 3.ESP32入门之arduino IDE环境搭建 4.ESP32 MicroPython编程官网文档 E ...

  10. 消息队列 RocketMQ4.x介绍和新概念讲解

    消息队列 RocketMQ4.x介绍和新概念讲解 Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件 RocketMQ4.x特点 支持Broker和Consumer端消 ...