磁盘的物理结构
基本概念
首先磁盘有几个个概念盘面(磁头),扇道(柱面),扇区。要理解他们的含义要结合磁盘的实际物理结构 :
每个磁盘有若干盘面摞在一起,每个盘有两个面,我觉得类似蒸笼一样。每个盘面分别有一个磁头,由一个机械臂连接在主转马达上。一个盘面被分成一些同心圆,这些圆就构成了磁道,每个磁道又分成若干扇形这个称为扇区。
读写的基本原理
磁盘的两面涂有磁性材料,根据N,S可以来记录0,1两种状态。
写入数据时,磁头电磁铁改变极性材料的磁性来写数据。
读入数据时,磁头的读取器可以得到磁性材料的极性然后还原成 0 ,1电信号。
处理器对磁盘的控制
再来回顾一下8086下1M内存的分配,我们先前已经介绍过在统一编址的模式下,显存对应的区域是0xb8000-0xbffff,通过从操作这里相应的内存就可以控制显示器上显示的字符。这里磁盘的访问车采用的是独立编址的方式,我的理解是好比一个单刀双掷开关拨到左边执行的是左边的电路,拨到右边执行右边的。处理器是通过一个M/IO#引脚,访问内存的时候M/IO#呈高电平状态,当要表示处理I/O端口的时候呈低电平状态,M/IO#中的#也表示IO低电平有效。
磁盘有SATA,PATA和IDE三种接口,但是我电脑上的两个都是SATA接口。他们通过IO接口和连接在地址总线上,由CPU传送指令给他们进行相应的操作。操作端口的指令是in和out,in al/ax 源操作数,out 目的操作数 al/ax,这样看来他们对寄存器操作数都是有一定限制。
通过控制端口对扇区进行读写
对磁盘的读写都是以扇区为单位,每次是512B。物理上磁盘分成一个一个扇区,逻辑上也应该分区,就想虚拟内存一样让程序员不用去考虑他物理上是如何分配的只要操作逻辑扇区就可以了。另外需要注意,物理扇区是1扇区开始,而逻辑扇区是从0扇区开始的,如果要用dd命令将2B数据写入第100扇区应该是这样的dd if=./文件 of=/home/sky/hd60M.img bs=512 conv=notrunc seek=100 count=2
。磁盘的逻辑扇区可以用28位表示称为LBA28,也可以用48位表示称为LBA48,位数多自然表示的逻辑扇区就多能控制的磁盘也大。
下面演示以LBA28为例如何通过端口读取主磁盘上(0x1f0-0x1f7)逻辑2扇区起的一个扇区为例的数据:
1.将要读取的扇区写入0x1f2端口
mov dx,0x1f2
mov al,0x01 ;读取0x01扇区数据
out dx,al ;源操作数必须是ax/al
2.设置要读取的起始扇区
LBA28逻辑扇区号需要占据28位一个端口只有8位所以需要3.5个端口,这3.5端口是这样分配的,0x1f3-0x1f5正常使用,至于0x1f6的高四位用作其他标志,4位0表示主盘1表示从盘,6位1表示LBA模式,0表示CHS模式。
mov dx,0x1f3
mov al,0x02
out dx,al ;LAB地址0-7
inc dx ;操作下一个端口
...
out ax,al ;LBA 23-16位
inc dx ;0x1f6
mov al,0xe0 ;LBA模式0xe0 1110 0000
out dx.al ;只写高四位是LBA模式,第四位地址全是0
3.向端口0x1f7写入读取指令0x20
mov dx,0x1f7
mov al,0x20
out dx,al
4.等待读取操作完成,判断读取操作是否完成也是通过0x1f7端口,所以0x1f7既是一个命令 端口也是一个状态端口。当且仅当该端口不忙(表示数据已经读完)且准备好和主机交换数据的时候才可以取得数据,所以当我们把读指令写入0x1f7之后就需要查看该端口的状态。
mov dx,0x1f7
.waits:
in al,dx ` ;将dx端口的数据写入al
and al,0x88 ;将al的3位和7位筛选出来
cmp al,0x08 ;这就是不忙且磁盘已就绪
jnz .waits
5.取出数据,8个端口我们使用了4+1+1个还剩下0x1f0和0x1f1两个端口,而0x1f0就是作为数据端口来供我们存取数据的,0x1f1端口是存储出错时候的一些错误信息,下面我们循环从数据端口读出数据即可。
mov cx.256 ;总共要读取的字数,字数就是字节数的两倍
mov dx,0x1f0 ;将端口号写入dx寄存器
.readw:
in ax,dx ;操作数是16位所以是双字
mov [bx],ax ;将读出的数据送往bx指向的内存处
add bx,2 ;向后偏移两个字节即一个字
loop .readw ;cx控制循环次数
至此循环结束后,我们便在bx为偏移地址处取得了磁盘上的内容存到我们的内存中,我觉得这其实就是将程序装载到内存里。