【硬件】软盘的存储结构与读取
虽然现在软盘早已被淘汰(小时候用过3.5英寸软盘的同学们请举手!DOS时代1.44 MB的容量实在不敢恭维),但是从软盘开始学习操作系统编程确实很有帮助。特别是虚拟机,对于虚拟机,软盘是相当方便的工具。现在我来讲讲软盘的读写。在这里,我只说怎么用16位BIOS中断读取软盘数据,我并不打算说如何直接IO读取软盘数据。如果你是来找软盘IO读取方式的请绕行。但是,此贴在后面会说道软盘数据的分布方式和CHS寻址的问题,请留意。
首先就是读取问题,很简单,调用BIOS中断INT 0x13 AH=0x02为CHS方式读取磁盘功能,INT 0x13 AH=0x03为CHS方式写入磁盘功能。现在我们来详细说明一下它们的用法。
AH=功能号(0x02、0x03)
AL=要读取的扇区数量
CX=磁道号和扇区号,其中磁道号为CL的高2位和CH组成,扇区号为CL的低6位。扇区号是从1开始的数字。
DH=磁头号
DL=驱动器号(小于0x80的为软驱号,大于、等于0x80的为硬盘号)
ES:BX=缓冲区地址
详情请见以下网址:
CHS方式读取:http://www.ctyme.com/intr/rb-0607.htm
CHS方式写入:http://www.ctyme.com/intr/rb-0608.htm
下面来讲一下CHS寻址的问题。软盘的扇区是按照什么样的顺序排列的,特别是软盘镜像文件中的“扇区”是怎么分布的,这是一个问题。
它是先排列一整个盘面,然后换一个盘面排列,还是两个盘面交替排列?
我们可以亲自做个实验来解决这个问题。
实验工具:
Microsoft Virtual PC 2007 32位(虚拟机)NASM(编译器)
记事本
WinHex(查看文件的工具)
我们的思路是让虚拟机从软盘引导,软盘的引导扇区是我们编写好的指令,指令的作用是按照我们设想好的排序方式写软盘,给每个扇区写入一个“索引数字”。然后用WinHex打开软盘,查看索引数字的排序方式,以此来判断软盘的排序方式。
首先我们需要一个引导程序,看!代码如下
org 0x7C00
bits 16
%define FLP_SECPERTRACK 18
%define FLP_TRACKPERHEAD 80
%define FLP_HEADPERDISK 2
Start:
mov ax,cs
mov es,ax
mov ss,ax
mov ds,ax ;对齐各个用到的段,包括栈段
mov sp,Start ;栈指向Start处
mov bp,sp ;借助bp访问栈
xor si,si ;si被用作“扇区索引号”
mov cx,FLP_TRACKPERHEAD ;循环写入每个盘面
.LoopCyl:
push cx ;此时的cx被写入了
mov cx,FLP_SECPERTRACK ;循环写入每个扇区
.LoopSec:
push cx ;此时的cx被写入了
mov bx,0x600 ;0:0x600是缓冲区
mov di,bx
mov ax,si
mov cx,0x100
rep stosw ;把正面的扇区编号写入缓冲区
add ax,FLP_SECPERTRACK*FLP_TRACKPERHEAD
mov cx,0x100
rep stosw ;再把背面的扇区编号写入缓冲区
mov ax,0x0301 ;写入正面的扇区
mov ch,FLP_TRACKPERHEAD
sub ch,
mov cl,FLP_SECPERTRACK+1
sub cl,
mov dx,0x0000
int 0x13
mov ax,0x0301 ;再写入背面的扇区
inc dh
add bx,0x200
int 0x13
inc si ;扇区索引号+1
pop cx
loop .LoopSec ;循环写入磁道的每一个扇区
mov ah,0x0E ;每写入一个正反面磁道,打印一个字符
mov al,
mov dx,0x0007
int 0x10
pop cx
loop .LoopCyl ;循环写入盘面的每一个磁道
mov ax,0x0E01 ;最后打印一个笑脸,表示结束
mov dx,0x000F
int 0x10
cli ;当机
hlt
times 510-($-$$) nop ;填充剩余字节
dw 0xAA55
;填充字节,使这个文件的大小正好等于一个软盘的大小。
times (FLP_SECPERTRACK*FLP_TRACKPERHEAD*FLP_HEADPERDISK*0x100)-0x100 dw 0
哟西,这样就行了。保存为ShowFlp.asm。让我们运行NASM开始编译:
NASM ShowFlp.asm -o ShowFlp.img
嗯,NASM没有报错,现在要做的是启动虚拟机,让虚拟机以这个文件为软盘镜像引导。
送:ShowFlp.7z
感谢我吧。
然后呢,运行VM,设置新的虚拟机,操作系统为“其它”,内存不必太大,1 MB足够了。虚拟硬盘可有可无,以后如果要用的话设置个256 MB的,运行个DOS没问题了。
运行虚拟机,把虚拟机的软驱设置为“捕获软驱镜像文件”(Capture Floppy Image File),把我们刚才生成的ShowFlp.img弄进去,然后重启虚拟机。
看!虚拟机运行啦!我们预测的结果,是它在屏幕上打印一些奇怪的字符(中途会“嘀~”叫一声),然后显示一个笑脸字符“☺”,退出程序。
他果然按照预想的运行了!那么我们让它释放软盘镜像文件,然后用WinHex打开它!
果然,软驱的前几个扇区都是按照我们给的索引排序的。
那么我们来看看在第18扇区处的情况:
咦?居然是0x05A0(也就是1440)。 1440?这不是一个盘面的扇区量吗?
果然呢,软盘的存储方式是两磁头之间交替存储的呢。我们来总结一下。
软盘的存储,是每个磁道中的扇区是连续存储的,但是磁头是交替存储的,也就是说,最小单位是扇区,其次是磁头,最后是磁道。
这也是为什么磁道要被称作“柱面”的原因了。
最后给一个处理后的软盘镜像文件,望笑纳。
After.7z
页:
[1]