chap2.4_读取磁盘_CHS方式
软盘和硬盘
软盘
- 软盘,目前已经淘汰。
目前主流的硬盘分为两种:
- 机械硬盘
- 固态硬盘
硬盘最早分为两种接口方式:
- 并行接口(PATA),目前已经淘汰。
- 串行接口(SATA)。
磁盘寻址两种方式:CHS和LBA
CHS方式, LAB28 和 LAB48
IO操作读取硬盘的三种寻址方式:
- chs寻址方式 :小于8G (8064MB)
- LBA28寻址方式:小于137GB
- LBA48寻址方式:小于144,000,000 GB
CHS和LBA的转换
CHS地址可用以下公式转成LBA,
1 | LBA = (C * H + H) * S + S - 1 |
LBA可用以下公式对应到CHS:
1 | C = LBA / (SPT * HPC) |
C = cylinder : 磁柱编号
H = head: 磁头编号
S = sector: 扇区编号
HPC=heads per cylinder,每个磁柱的磁头数
SPT=sectors per track,每磁道的扇区数
磁盘寻址:CHS方式
磁盘的三层定位结构分别为
- 磁头(Head) :每张磁盘的正面和反面都有一个磁头,一个磁头对应着一张磁盘的一个面,因此,用第几个磁头就能表示数据在哪个盘面.
- 柱面(Cylinder): 由所有磁盘中半径相同的同心磁道构成,在这一系列的磁道水质叠放在一起,就形成了一个柱面的形状。所以柱面数 = 磁道数。
- 扇区(Sector): 一个扇区512字节
磁盘寻址,是指根据给出的方式找到扇区的位置。
按顺序根据柱面,磁头,扇区,这种方式称之为CHS方式。
例如: 磁盘的第一个扇区,位于 1柱面,1磁头,0扇区
CHS方式表示的容量上限
这种模式及下,支持的最大柱面数为1024,最大磁头数为16,最大扇区数为63,(每个扇区字节数为512Bit)因此最大访问硬盘容量为:
1024 x 16 x 64 x 512 = 528MB
虽然后面又拓展了large模式读取,但是没有解决根本问题。
所以后来有LBA的读取方式,可以描述更大容量。
软盘
一张软盘有80个柱面,2个磁头,18个扇区
软盘大小为 80x2x18x512=1440KB
较旧的硬盘驱动器,如 MFM 和 RLL 驱动器,将每个柱面划分为相等数量的扇区,并且 CHS 值与驱动器的物理构成相匹配。 CHS 值为 500 x 4 x 32 的驱动器的每个盘片每侧有 500 个磁道,两个盘片,每个柱面有 32 个扇区,总共有 32,768,000 字节(约 31 兆字节)。 大多数现代驱动器都有一个不构成柱面边界的剩余空间。 每个分区应始终在柱面边界处开始和结束。 只有一些最现代的操作系统可能会忽略这一规则,但这会导致一些兼容性问题,尤其是当用户想要在同一驱动器上启动多个操作系统时。
IDE 驱动器已经取代了 MFM 和 RLL 驱动器,并且在存储数据方面效率更高。 他们使用区域位记录 (ZBR),其中一个柱面中的扇区数随其在驱动器上的位置而变化。 靠近盘片边缘的柱面比靠近主轴的柱面包含更多扇区,因为在盘片边缘附近的给定磁道中有更多空间。 由于每个柱面的扇区数量不同,CHS 寻址系统不适用于这些驱动器。 IDE 驱动器可以在系统 BIOS 中配置为不超过驱动器容量的柱面、磁头和扇区的任何配置。 驱动器将给定的 CHS 地址转换为特定硬件配置的实际地址。
读取磁盘_CHS方式
BIOS读取磁盘
读取磁盘功能02H
读取磁盘也是调用BIOS:
中断命令: INT 13H
1)入口参数
| 寄存器 | 说明 | 值 |
|---|---|---|
| AH | 功能:02H读取扇区 | 02H |
| AL | 扇区数 | — |
| CH | 柱面数 | — |
| CL | 扇区 | — |
| DH | 磁头 | — |
| DL | 驱动器号 | 00H-7FH:软盘驱动器号;80H-0FFH:硬盘驱动器号 |
| ES:BX | 缓冲区的地址 | 00H-7FH:软盘驱动器号;80H-0FFH:硬盘驱动器号 |
2)出口参数
读取成功:
| 寄存器 | 说明 | 值 |
|---|---|---|
| AH | 00H | — |
| AL | 输的扇区数 | — |
读取失败:
| 寄存器 | 说明 | 值 |
|---|---|---|
| AH | 状态代码 | — |
定义磁盘读取函数
1. 读取一个扇区
1 | .read_one_sector |
1 | ; ------------------------------------------------------------------------ |
2. 读取多个扇区
读取时要根据 扇区<磁头<柱面 的方式来读取。继续添加代码,读取18个扇区:(即完整的读取了一个柱面)。
代码如下:
3. 读取多个柱面
继续添加代码,读取10个柱面。
然后调用函数
1 | ;读取磁盘初始化 |
CHS方式读取(使用LBA值转换后读取)
1 | ; ============================================== |
完整代码
最后,完整的boot.asm文件代码如下:
1 | ; RASTOS BOOT |
运行
创建build.sh脚本
1 | !/bin/bash |
创建run.sh脚本
1 | !/bin/bash |
运行结果如下:

上面代码的作用
首先boot.asm会被加载到内存并且执行.后面开始读取磁盘的10个柱面(10*18个扇区).
读取的扇区数据复制到 内存 0x8000 开始的位置.
然后打印输出”hello,rats os start”