[自制操作系统] 第03回 认识硬盘
目录
一、前景回顾
二、硬盘的工作原理
三、IDE硬盘接口技术
前面说到,开机的启动过程有如下三点:
1、按下开机键后,CPU将cs:ip寄存器初始化为0xf000:0xfff0,这个位置是BIOS程序的入口处,这个位置存放的代码是jmp far f000:e05b,通过这行代码CPU又将cs:ip寄存器初始化为0xf000:0xe05b,这里才是BIOS真正开始执行的地方。
2、BIOS执行了一系列的硬件检测工作和创建中断向量表IVT后,将MBR(主引导记录)加载到内存0x7c00处,并且跳转到该位置,也就是将cs:ip寄存器初始化为0x0000:0x7c00。
3、MBR的工作是加载操作系统内核,最后跳转到操作系统内核中,随后便是熟悉的启动动画,也就完成了开机过程。
在上回,我们已经实现了MBR的创建,并且简单地测试了一下这个MBR的可行性。
回到主线来,我们知道MBR的工作是加载操作系统内核。那么问题来了,在我们平时的电脑中,这个操作系统内核在哪里呢?这里就不卖关子了,它是事先被存放在硬盘中的,随后被MBR加载到指定位置。可是我们现在要实现自己的操作系统,所以,首先这个内核肯定得是我们自己编写;其次,如何从硬盘中读取到这个操作系统内核也是一个亟待解决的问题。
我相信很多初学者和我一样,一开始对操作系统内核还是感到比较害怕的。感觉应该会是特别复杂,难以理解,而且还要自己去实现,这简直是想都不敢想的事。不过关于操作系统内核的实现,我们现在暂且不用管,这个内核再神秘,究其本质也就是一段代码罢了,我们后面再来啃它。
当务之急是我们要认识硬盘,并且能驾驭它,学会如何读取它才是目前的主要任务。
这里只讲解传统的机械硬盘的工作原理,因为我们在BOCHS中配置的硬盘就是此种硬盘。
主轴上有两个盘片,其实不止两个,这里只是示意性地画了两个。盘片固定在主轴上随主轴高速旋转,。每个盘片分为上下两面,每一面都存储数据,每个盘面都各有一个磁头来读取数据,故一个盘片上对应两个磁头。磁头的编号从上到下以0开始计数,所以用磁头0来表示第一个盘面。磁头不会自己在盘片上移动,它需要被固定在磁头臂上,在磁头臂的带动下,沿着盘片边缘向圆心的方向来回摆动。通过盘片的自转以及磁头的摆动,这两种动作的合成便能够使磁头访问盘片任意位置的数据。
说完了硬盘内部各部件的运动,接下来说一下存储逻辑。盘片表面是用于存储数据的磁性介质,为了管理磁盘,将整个盘面划分为多个同心环,以圆心画扇形,扇形与每个同心环相交的弧状区域作为最基本的数据存储单元。整个同心环就称作磁道,磁道的编号和磁头也是一样,从0开始。而同心环上的弧状区域是扇形的一部分,被称为扇区,它作为我们向硬盘存储数据的最基本单元,大小为512字节。一般来说,一个磁道上有63个扇区,扇区的编号是从1开始的。
相同编号的磁道组成的管状区域被称为柱面,柱面的编号是从0开始的。它的作用是为了缩减机械式硬盘的寻道时间。
上面比较简单地介绍了一下硬盘的工作原理,因为我对这个也不是很懂。总之我们现在知道了,通过磁头号、磁道号和扇区号就可以唯一定位一个扇区。这就是CHS(Cylinder Head Sector),但是每次我们都要事先算出扇区在哪个盘面,哪个柱面和哪个磁道上。这样的方法对于磁头来说很直观,但是对于我们来说还是比较麻烦,我们希望能有一套对于人来说较为直观的寻址方法,我们希望磁盘中扇区从0开始依次递增编号,不用考虑扇区所在的物理结构,于是LBA法呼之欲出:
LBA = (柱面号 * 磁头数 + 磁头号) * 扇区数 + 扇区编号 - 1
谁来控制硬盘呢?我们知道CPU只会不停地取指令、读指令,这才是CPU高效工作的原因。因此控制硬盘的任务肯定不是交给CPU,那么交给了谁呢?聪明的工程师们设计了一个叫做硬盘控制器的东西,CPU只同硬盘控制器打交道,由它将CPU的命令转译给硬盘。现在的硬盘和硬盘控制器是整合在一起的,也就是说我们买的硬盘中,其实就附带了硬盘控制器,而不是说在我们主板的某个地方还有一个所谓的硬盘控制器电路。
硬盘需要插在主板上才能正常工作,我们将硬盘的这种接口称为集成设备电路(IDE),随着IDE标准接口的影响力越来越大,全球标准化协议将此接口使用的技术规范归纳为全球硬盘标准,这样也就产生了ATA(Advanced Technology Attachment)。不过由于IDE这个名字已经叫开了,所以大家依然习惯称硬盘为IDE硬盘。后面又出现了新的硬盘串行接口(Serial ATA, SATA),这个我相信很多人就比较熟悉了。为了区分不同的接口,习惯性地将以前的ATA接口称为并行ATA,即(Parallel ATA, PATA)。
PATA接口线缆 SATA接口线缆
以前的一般主机只支持4个并口硬盘。仔细看PATA接口线缆,我第一次看还比较好奇怎么有三个接口。其实这个接口线缆可以挂载两块硬盘,一个是主盘(Master),一个是从盘(Slave),因此主板上提供两个IDE接口,两个接口便可以连接四块硬盘。这两个接口也是以0为起始编号,一个称为IDE0,另一个称为IDE1。在ATA的标准中,IDE0又叫做Primary通道,IDE1又叫做Secondary通道。
铺垫了这么多,我们该来说说如何控制硬盘了。其实我们是通过读写硬盘控制器的端口,也就是一系列寄存器来让硬盘正常工作。硬盘控制器的寄存器数量众多,我们这里不能一一列出,就贴一下主要的端口寄存器。
关于这些寄存器的详细描述建议读者参考一下原书《操作系统真象还原》的p126~129页。
回到正题,如果我们要写一个程序来从硬盘中读取文件的话,整个步骤如下:
1、先选择通道,往该通道的sector count寄存器中写入待操作的扇区数。
2、往该通道上的三个LBA寄存器写入起始地址的低24位
3、往device寄存器中写入LBA地址的24~27位,并置第6位为1,使其为LBA模式,设置第4位,选择操作的硬盘是master硬盘还是slave硬盘。
4、往该通道上的command寄存器写入读指令的操作命令。
5、不断读取该通道上的status寄存器,判断硬盘工作是否完成。
6、如果硬盘工作完成,则从该通道的数据寄存器Data读取出数据到内存指定区域。
关于硬盘的介绍就结束了,如果仔细去看书的话,会发现书上对这些寄存器的讲解较多,可能会让人觉得头大,其实我觉得关于寄存器这块,能大概看懂就好了,看不太懂也没关系。我学习的时候也就是对这块大概看看,没有详细地去深究,我还是更加注重全局上的理解。
预知后事如何,请看下回分解。