type
status
date
slug
summary
tags
category
icon
password
Property
May 16, 2025 11:27 AM
⚠这篇文章比较无聊,因为涉及到一些硬件相关的东西,所以大部分的知识内容都很刻板,基本只能当作字典用。
之前讲了关于主引导扇区上的内容,这次就来讲讲BootLoader具体是怎么编写和加载系统的.
首先我们需要知道硬盘是如何工作的,以及它的结构。
🤣服了,搞个软件还得知道硬件的工作方法就离谱。
首先每个扇区的大小是固定在512字节的,现代硬盘的寻址方式一般都是通过LBA(逻辑块寻址)来进行。老式的叫做CHS(柱面-磁头-扇区)。这篇文章主要使用的是LBA28方式,也就是最高支持28位寻址。
当下的计算机应该采用的是更高位的LBA了。不过基本原理都是差不多的。
硬盘内部也是存在类似寄存器的结构,我们在汇编中会用端口的方式来访问它们。
端口地址 | 作用 | 说明 |
0x1F0 | 数据寄存器 | 负责数据管理,用于读取或写入数据 |
0x1F1 | 错误寄存器 / 特性寄存器 | 记录错误信息(读)、设置功能(写) |
0x1F2 | 扇区计数寄存器 | 指定待读取或写入的扇区数 |
0x1F3 | LBA 低 8 位 | LBA 地址的 0-7 位 |
0x1F4 | LBA 中 8-15 位 | LBA 地址的 8-15 位 |
0x1F5 | LBA 高 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 个寄存器:
端口地址 | 寄存器 | 位范围 | 作用 |
0x1F3 | LBA 低 8 位 | 0-7 | LBA 低 8 位 |
0x1F4 | LBA 中 8-15 位 | 8-15 | LBA 中 8 位 |
0x1F5 | LBA 高 16-23 位 | 16-23 | LBA 高 8 位 |
0x1F6 | LBA 最高 4 位 + 设备选择 | 24-27 | LBA 最高 4 位 |
ㅤ | ㅤ | ㅤ | ㅤ |
设备/磁盘选择寄存器(0x1F6)
- 作用:选择 主盘 / 从盘,并存储 LBA 最高 4 位。
位 | 描述 |
7 | 必须为 1 |
6 | 1 = LBA 模式,0 = CHS 模式 |
5 | 必须为 1 |
4 | 0 = 主盘,1 = 从盘 |
3 | LBA 地址的 第 24 位 |
2 | LBA 地址的 第 25 位 |
1 | LBA 地址的 第 26 位 |
0 | LBA 地址的 第 27 位 |
状态寄存器(0x1F7,读)
- 作用:用于检查硬盘状态,确定何时可以读取/写入数据。
位 | 名称 | 描述 |
7 | BUSY | 1 = 硬盘忙,无法执行新命令 |
6 | DRDY | 1 = 硬盘准备就绪 |
5 | DF | 1 = 磁盘错误(写保护或数据错误) |
4 | SEEK COMPLETE | 1 = 磁头已定位到正确位置 |
3 | DRQ | 1 = 数据准备就绪(可读/写) |
2 | CORR | 1 = 硬盘纠错 |
1 | IDX | 索引标志(几乎不使用) |
0 | ERR | 1 = 发生错误 |
命令寄存器(0x1F7,写)
- 作用:向
0x1F7
端口写入命令,通知硬盘执行相应的操作。
- 使用方式:在正确设置 LBA 地址和扇区数 后,向该寄存器写入相应命令。
命令值 | 功能 |
0x20 | 读取扇区(LBA 模式) |
0x30 | 写入扇区(LBA 模式) |
0xEC | 识别硬盘信息 |
0xE7 | 刷新硬盘缓存 |
0xF8 | 设备重置 |
LBA 方式读取磁盘
LBA 是现代磁盘的标准寻址方式,它将磁盘看作 连续的扇区序列,计算方式如下:
LBA 读取磁盘步骤
- 选择通道: 向 0x1F2(扇区计数寄存器)写入 待读取的扇区数。
- 设置 LBA 地址: 1、将 LBA 低 24 位 写入 0x1F3、0x1F4、0x1F5;2、将 LBA 高 4 位 写入 0x1F6,并置位第 6 位(LBA 模式)。
- 发送读取命令: 向 0x1F7(命令寄存器)写入 0x20(读取扇区命令)。
- 检查状态: 读取 0x1F7(状态寄存器),确认硬盘数据准备就绪。
- 读取数据: 从 0x1F0 读取 512 字节(1 个扇区)到内存。
知道了上述知识,我们就知道了如何控制硬盘,接下来我们可以开始编写BootLoader辣!
- 作者:sdttttt
- 链接:https://www.sdttttt.site/article/1f50e50d-3291-80e7-94aa-fa070e0081eb
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。