Last Regrets

硬盘LBA28读取以及BootLoader加载

· sdttttt

⚠这篇文章比较无聊,因为涉及到一些硬件相关的东西,所以大部分的知识内容都很刻板,基本只能当作字典用。

之前讲了关于主引导扇区上的内容,这次就来讲讲BootLoader具体是怎么编写和加载系统的.

首先我们需要知道硬盘是如何工作的,以及它的结构。

🤣服了,搞个软件还得知道硬件的工作方法就离谱。

首先每个扇区的大小是固定在512字节的,现代硬盘的寻址方式一般都是通过LBA(逻辑块寻址)来进行。老式的叫做CHS(柱面-磁头-扇区)。这篇文章主要使用的是LBA28方式,也就是最高支持28位寻址。

当下的计算机应该采用的是更高位的LBA了。不过基本原理都是差不多的。

硬盘内部也是存在类似寄存器的结构,我们在汇编中会用端口的方式来访问它们。

端口地址作用说明
0x1F0数据寄存器负责数据管理,用于读取或写入数据
0x1F1错误寄存器 / 特性寄存器记录错误信息(读)、设置功能(写)
0x1F2扇区计数寄存器指定待读取或写入的扇区数
0x1F3LBA 低 8 位LBA 地址的 0-7 位
0x1F4LBA 中 8-15 位LBA 地址的 8-15 位
0x1F5LBA 高 16-23 位LBA 地址的 16-23 位
0x1F6设备寄存器选择主盘/从盘,LBA 高 24-27 位
0x1F7状态寄存器 / 命令寄存器读时返回状态,写时执行命令

数据寄存器(0x1F0)

  • 作用:用于 读取/写入数据,一次传输 16 位(2 字节)。
  • 数据大小:一个扇区(512 字节)= 256 次 16 位传输。

扇区计数寄存器(0x1F2)

  • 作用:指定要读/写的 扇区数。
  • 数值范围:1-255,0 表示 256 个扇区。

LBA 地址寄存器

LBA 地址由 28 位组成,分布在 4 个寄存器:

端口地址寄存器位范围作用
0x1F3LBA 低 8 位0-7LBA 低 8 位
0x1F4LBA 中 8-15 位8-15LBA 中 8 位
0x1F5LBA 高 16-23 位16-23LBA 高 8 位
0x1F6LBA 最高 4 位 + 设备选择24-27LBA 最高 4 位

设备/磁盘选择寄存器(0x1F6)

  • 作用:选择 主盘 / 从盘,并存储 LBA 最高 4 位。
描述
7必须为 1
61 = LBA 模式,0 = CHS 模式
5必须为 1
40 = 主盘,1 = 从盘
3LBA 地址的 第 24 位
2LBA 地址的 第 25 位
1LBA 地址的 第 26 位
0LBA 地址的 第 27 位

状态寄存器(0x1F7,读)

  • 作用:用于检查硬盘状态,确定何时可以读取/写入数据。
名称描述
7BUSY1 = 硬盘忙,无法执行新命令
6DRDY1 = 硬盘准备就绪
5DF1 = 磁盘错误(写保护或数据错误)
4SEEK COMPLETE1 = 磁头已定位到正确位置
3DRQ1 = 数据准备就绪(可读/写)
2CORR1 = 硬盘纠错
1IDX索引标志(几乎不使用)
0ERR1 = 发生错误

命令寄存器(0x1F7,写)

  • 作用:向 0x1F7 端口写入命令,通知硬盘执行相应的操作。
  • 使用方式:在正确设置 LBA 地址和扇区数 后,向该寄存器写入相应命令。
命令值功能
0x20读取扇区(LBA 模式)
0x30写入扇区(LBA 模式)
0xEC识别硬盘信息
0xE7刷新硬盘缓存
0xF8设备重置

LBA 方式读取磁盘

LBA 是现代磁盘的标准寻址方式,它将磁盘看作 连续的扇区序列,计算方式如下:

LBA 地址 = (柱面号 × 磁头数 + 磁头号) × 每磁道扇区数 + 扇区号 - 1

LBA 读取磁盘步骤

  • 选择通道: 向 0x1F2(扇区计数寄存器)写入 待读取的扇区数。
  • 设置 LBA 地址: 1、将 LBA 低 24 位 写入 0x1F3、0x1F4、0x1F5;2、将 LBA 高 4 位 写入 0x1F6,并置位第 6 位(LBA 模式)。
  • 发送读取命令: 向 0x1F7(命令寄存器)写入 0x20(读取扇区命令)。
  • 检查状态: 读取 0x1F7(状态寄存器),确认硬盘数据准备就绪。
  • 读取数据: 从 0x1F0 读取 512 字节(1 个扇区)到内存。

知道了上述知识,我们就知道了如何控制硬盘,接下来我们可以开始编写BootLoader辣!