《自己动手写操作系统 》第九章 一 简易硬盘驱动的实现

来源:互联网 发布:信贷规模数据 编辑:程序博客网 时间:2024/05/16 05:53

摘要:我们都知道磁盘由控制器、磁头等组件组成。我们在终端编辑文件的时候,文件内容是如何从内存到达磁盘的呢?磁盘驱动主要完成哪些工作?硬盘中断是如何触发的?等等,这些都是硬盘工作的基本原理。本文主要从“自己动手写操作系统” 出发,通过实现一个简单的硬盘驱动,来解释硬盘工作的基本原理。


1.程序执行流程:

1)task_hd()作为一个守护进程,初始化硬盘,然后一直运行,等待接收来自其他进程的消息
2)如果收到打开设备的消息,那么将执行identify(0);否则,出错信息提示
3)identify(0):想硬盘发送IDENTIFY命令,等待中断的到来,中断到来后,从数据寄存器中读取硬盘的信息
4)打印步骤3)中得到的硬盘信息

5)中断处理程序的内容:读取硬盘忙的状态;通知驱动程序

*6)文件系统向驱动程序发送“打开设备”的命令


2.疑问解答

2.1.硬盘能够接收哪些命令?有什么样的处理结果?

硬盘能够接受很多命令(都是硬件定义的,和系统无关)。这里,我们用到了IDENTIFY DEVICE 命令,下面解释一下:参考手册:AT Attachment with packet Interface 文档P113:

The IDENTIFY DEVICE command enables the host to receive parameter information from the device.

Some devices may have to read the media in order to complete this command.

When the command is issued, the device sets the BSY bit to one, prepares to transfer the 256 words of device
identification data to the host, sets the DRQ bit to one, clears the BSY bit to zero, and asserts INTRQ if nIEN
is cleared to zero. The host may then transfer the data by reading the Data register. Table 27 defines the
arrangement and meaning of the parameter words in the buffer. All reserved bits or words shall be zero.

Some parameters are defined as a 16-bit value. A word that is defined as a 16-bit value places the most
significant bit of the value on signal line DD15 and the least significant bit on signal line DD0 (see 3.2.9).

Some parameters are defined as 32-bit values (e.g., words (61:60)). Such fields are transferred using two
successive word transfers. The device shall first transfer the least significant bits, bits (15:0) of the value, on
signal lines DD(15:0) respectively. After the least significant bits have been transferred, the most significant
bits, bits (31:16) of the value, shall be transferred on DD(15:0) respectively (see 3.2.9).

Some parameters are defined as a string of ACSII characters. Such fields are transferred as defined in 3.2.9.

2.2.如何通知驱动程序?
参见inform_int()相关代码

3.其他要注意的事项

一个进程拥有哪些资源?需要到哪里注册?
PCB中的相关信息!我们添加一个任务之后,需要到task_table或者其他地方进行注册。
3.1不要忘记在proc_tabel等的相关更新

4.关于port_read:不可预取类型

    IO操作有两种类型,可预取类型和不可预取类型,前者主要是RAM,后者主要是设备寄存器。你有没有对这个port_read函数感到奇怪呢?为什么连续读取多次,就能读取到不同的信息?——这是因为设备寄存器本身就是FIFO队列的接口,是一种不可预取类型。
其中,insw指令的用法如下:
INS m8, DX
从 DX 指定的 I/O 端口将字节输入 ES:(E)DI 指定的内存位置
INS m16, DX
从 DX 指定的 I/O 端口将字输入 ES:(E)DI 指定的内存位置
INS m32, DX
从 DX 指定的 I/O 端口将双字输入 ES:(E)DI 指定的内存位置
INSB
从 DX 指定的 I/O 端口将字节输入 ES:(E)DI 指定的内存位置
INSW
从 DX 指定的 I/O 端口将字输入 ES:(E)DI 指定的内存位置
INSD
从 DX 指定的 I/O 端口将双字输入 ES:(E)DI 指定的内存位置
 

 这里,如果我们一定要记得导出port_read函数,不然这个函数无法被外部模块使用。


5.硬盘中断是如何同驱动程序交互的呢?

这里有一个非常重要的函数:hd_identify(),里面的关键过程如下:
hd_cmd_out();
interrup_wait();
port_read();

向硬盘发送命令——等待中断到来——读取数据端口

6.硬盘的构造和工作原理

硬盘内部结构由固定面板、控制电路和板、磁头、盘片、主轴、电机、接口及其它附件组成,其中磁头盘片组件是构成硬盘的核心,它封装在硬盘的净化腔体内,包括有浮动磁头组件、磁头驱动机构、盘片、主轴驱动装置及前置读写控制电路这几个部份。
我们向硬盘发送一个命令之后,硬盘控制器接受到命令,然后开始执行,命令执行完毕之后,将触发硬盘中断,通知驱动程序,数据已经准备完毕。

7.总结

        现在,你脑海里有没有硬盘工作的清晰图景呢?BIOS开机检测到硬盘,将硬盘的基本信息读取到内存的特定位置,通过PCIE配置,给硬盘寄存器分配对应的端口号码;操作系统将硬盘中断绑定特定的中断处理程序(主要是驱动程序);驱动程序运行,文件系统运行,文件系统向驱动程序发送读取硬盘信息的请求,硬盘驱动向硬盘发送相应操作命令并等待硬盘中断的回应;收到硬盘中断回应之后,驱动程序读取端口数据到缓冲区,交给文件系统进行处理。
1 0