由于最近在学习linux0.11内核,需要用到软盘启动,于是就抽空学习了一下软盘结构;
1、软盘结构
1.44软盘结构:2个盘面(0和1),一个盘面有80条磁道(或称磁柱),一个磁道有18个扇区,一个扇区大小为512Byte,于是软盘总容量:2*80*18*512Byte=1474560Byte=1.44M;
2、相对扇区号及转换
在系统中,于是可以通过盘面+磁道+扇区,就访问到相应的内容,但这明显比较繁琐,于是为了管理和使用方面,就有了相对扇区号概念,实质是给每个扇区编号;
相对扇区即从0开始依次对磁盘上的扇区进行编号,具体情况如下:
编号顺序:
扇区物理号相对扇区号
0面,0道,1扇区0
0面,0道,2扇区1
0面,0道,3扇区2
…………………….
0面,0道,18扇区17
1面,0道,1扇区18
……………
1面,0道,18扇区35
0面,1道,1扇区36
...................
0面,1道,18扇区53
1面,1道,1扇区54
于是从上述编号可以推算出相对扇区号的计算方法:
相对扇区号={盘面(0~1)*每条磁道扇区数(18)} + {2*磁道(0~79)*每条磁道扇区数(18)} +{扇区(1-18)-1};
而当知道相对扇区号,怎么推算出盘面、磁道、扇区呢?
具体步骤:
(1)从上面公式可以看出,相对扇区号对每条磁道扇区数(18)取余数 加1 就得到扇区;
(2)再根据(1)得到的商,如果盘面为1则商为奇数,否则为偶数,于是通过判断商的奇偶性,就可以得出盘;同时也可以算出磁道;
3、软盘读写
在系统中,是怎么读和写软盘?
通过BIOS中断13,详细见下图:
其中:
磁盘号:指的是软盘中的磁道或磁柱;
扇区号:指的是软盘的扇区;
CH存放磁道的低8位,CL的高两位存放磁道的高2位,CL的低6位存放扇区
磁头号:指的是软盘中的盘面;
驱动器号:指具体的软盘,如软盘A,软盘B...
CF为1则表示读取错误;
4、实例
通过如下具体的例子,大家可以更好的理解;(注:以下例子摘自网上http://blog.csdn.net/littlehedgehog/article/details/2147361)
文章图片
;
----------------------------------------------------------------------------
文章图片
;
函数名: ReadSector
文章图片
;
----------------------------------------------------------------------------
文章图片
;
作用:
文章图片
;
从第 ax 个 Sector 开始, 将 cl 个 Sector 读入 es:bx 中
文章图片
ReadSector:
文章图片
;
-----------------------------------------------------------------------
文章图片
;
怎样由扇区号求扇区在磁盘中的位置 (扇区号 -> 柱面号, 起始扇区, 磁头号)
文章图片
;
-----------------------------------------------------------------------
文章图片
;
设扇区号为 x
文章图片
;
┌ 柱面号 = y >> 1
文章图片
;
x┌ 商 y ┤
文章图片
;
-------------- => ┤└ 磁头号 = y & 1
文章图片
;
每磁道扇区数│
文章图片
;
└ 余 z => 起始扇区号 = z + 1
文章图片
pushbp
文章图片
movbp
,
sp
文章图片
subesp
, 2 ;
辟出两个字节的堆栈区域保存要读的扇区数: byte [bp-2]
文章图片
文章图片
movbyte
[
bp-2
]
,
cl
文章图片
pushbx
;
保存 bx
文章图片
movbl
, [
BPB_SecPerTrk
] ;
bl: 除数
文章图片
divbl
;
y 在 al 中, z 在 ah 中
文章图片
incah
;
z ++
文章图片
movcl
,
ah
;
cl <- 起始扇区号
文章图片
movdh
,
al
;
dh <- y
文章图片
shral
, 1 ;
y >> 1 (其实是 y/BPB_NumHeads, 这里BPB_NumHeads=2)
文章图片
movch
,
al
;
ch <- 柱面号
文章图片
anddh
, 1 ;
dh & 1 = 磁头号
文章图片
popbx
;
恢复 bx
文章图片
;
至此, "柱面号, 起始扇区, 磁头号" 全部得到 ^^^^^^^^^^^^^^^^^^^^^^^^
文章图片
movdl
, [
BS_DrvNum
] ;
驱动器号 (0 表示 A 盘)
文章图片
.GoOnReading:
文章图片
movah
, 2 ;
读
文章图片
moval
,
byte
[
bp-2
] ;
读 al 个扇区
文章图片
int13h
文章图片
jc.GoOnReading
;
如果读取错误 CF 会被置为 1, 这时就不停地读, 直到正确为止
文章图片
文章图片
addesp
, 2
文章图片
popbp
文章图片
文章图片
ret
5、总结
【软盘结构及软盘数据的读取】在软件中,可以通过层层封装实现设备访问的简单;
推荐阅读
- Application|linux应用编程笔记(5)系统调用文件编程方法实现文件复制
- Java|快到35岁了,担心失业(这篇文章告诉你什么才是中年危机)
- Linux|fcntl即F_SETFL,F_GETFL的使用,设置文件的flags
- Linux|关于getsockname函数的使用
- android x86虚拟机 网络正确配置
- 工具|Spring特点中关于DI,IOC及AOP的个人理解
- c#用法技巧|c# winform 通过编程取消事件(event)的注册
- C|va_list 原理以及用法
- linux|MongoDB 内存解析 Python
- 剑指offer|牛客网_剑指Offer_Python实现_更新中