操作系统开发:磁盘操作重要基础知识!
本文章仅提供学习,切勿将其用于不法手段!
一、INT13 中断错误码对照表
| AH 错误码 | 错误含义 | 常见原因分析 | 排查方向 |
|---|---|---|---|
| 0x00 | 操作成功 | 中断调用参数正确,磁盘操作正常 | - |
| 0x01 | 非法命令 | 功能号不支持、参数格式错误(如扇区数为 0) | 检查 AH 功能号、AL(扇区数)等参数合法性 |
| 0x02 | 地址标记未找到 | CHS/LBA 地址错误、磁盘未分区、MBR 无效 | 校验地址转换正确性、确认 MBR 已写入并含 0xAA55 签名 |
| 0x03 | 磁盘写保护 | 镜像文件只读权限、挂载为只读模式 | 调整文件权限、关闭占用镜像的程序 |
| 0x04 | 扇区未找到 | 目标扇区不存在、分区表范围错误 | 检查总扇区数、分区起始 / 结束扇区是否合法 |
| 0x05 | 重置失败 | 磁盘挂载错误、BIOS 未识别磁盘 | 检查 Bochs 配置、确认磁盘为 ATA0-master 设备 |
| 0x06 | 磁盘更换 | 虚拟磁盘未正确加载 | 重启 Bochs、确认镜像路径无空格 / 特殊字符 |
| 0x07 | 驱动器参数错误 | CHS 参数超出 BIOS 限制(如 Bochs3.0 heads≤16) | 调整 CHS 参数至支持范围 |
| 0x08 | 介质类型不匹配 | 文件系统格式与 BIOS 识别不兼容 | 确认分区为 FAT32/16 等 BIOS 支持格式 |
| 0x09 | 介质已更换 | 镜像文件被修改 / 替换 | 重新写入 MBR/DBR,确保镜像完整性 |
| 0x0A | 写故障 | 镜像文件不可写、磁盘空间不足 | 以管理员身份运行、清理磁盘空间 |
| 0x0B | 读故障 | 镜像损坏、扇区数据错误 | 重新创建镜像、校验 dd 写入命令参数 |
| 0x0C | 无介质 | 未挂载虚拟磁盘 | 检查 Bochs 配置中磁盘项是否启用 |
| 0x10 | 读 CRC 错误 | 数据传输校验失败、镜像损坏 | 重新写入镜像、降低虚拟磁盘容量 |
| 0x11 | ECC 错误(纠错失败) | 镜像数据错误、BIOS 纠错功能触发 | 重新创建空白镜像、简化磁盘配置 |
| 0x20 | 控制器错误 | ATA 通道配置错误 | 调整 Bochs 中 ata0-master/slave 配置 |
| 0x40 | 寻道失败 | 柱面地址超出磁盘范围 | 校验柱面数计算是否正确、总扇区数是否匹配 |
| 0x80 | 超时(无设备响应) | 磁盘未就绪、配置路径错误 | 确认镜像路径正确、等待磁盘初始化完成 |
| 0xAA | 设备未就绪 | 磁盘正在初始化、BIOS 未完成检测 | 增加启动延时、检查 BIOS 初始化流程 |
| 0xBB | 介质类型未知 | 未分区 / 未格式化、文件系统不识别 | 先创建分区表、格式化 FAT32 文件系统 |
| 0xCC | 介质更改已检测 | 镜像文件被外部程序修改 | 关闭占用镜像的程序、重新加载镜像 |
| 0xE0 | 状态错误(通用) | 多种异常叠加(如地址 + 权限错误) | 按优先级排查地址、权限、配置问题 |
| 0xFF | 检测到错误(无具体信息) | BIOS 不支持该操作、硬件兼容性问题 | 降低磁盘容量、使用简化 CHS 参数(如 heads=2) |
二、CHS-LBA 转换工具脚本(Python 版)
功能说明
支持两种核心转换:
- LBA→CHS:根据 LBA 地址、磁头数(heads)、每磁道扇区数(spt),计算对应 CHS 参数
- CHS→LBA:根据柱面数(cyl)、磁头数(head)、扇区号(sect)、每磁道扇区数(spt),计算对应 LBA 地址同时支持校验转换结果是否匹配磁盘总扇区数,避免地址越界。
Python 脚本代码
def lba_to_chs(lba: int, heads: int, spt: int) -> tuple[int, int, int]:
"""
LBA地址转换为CHS参数
:param lba: 逻辑扇区号(从0开始)
:param heads: 磁头数(如16)
:param spt: 每磁道扇区数(如63)
:return: (柱面数cyl, 磁头数head, 扇区号sect) —— 扇区从1开始,柱面/磁头从0开始
"""
if spt <= 0 or heads <= 0:
raise ValueError("每磁道扇区数(spt)和磁头数(heads)必须为正整数")
if lba < 0:
raise ValueError("LBA地址不能为负数")
sect = (lba % spt) + 1 # 扇区从1开始计数
head = (lba // spt) % heads
cyl = lba // (spt * heads)
return cyl, head, sect
def chs_to_lba(cyl: int, head: int, sect: int, spt: int) -> int:
"""
CHS参数转换为LBA地址
:param cyl: 柱面数(从0开始)
:param head: 磁头数(从0开始)
:param sect: 扇区号(从1开始)
:param spt: 每磁道扇区数(如63)
:return: LBA地址(从0开始)
"""
if spt <= 0:
raise ValueError("每磁道扇区数(spt)必须为正整数")
if cyl < 0 or head < 0:
raise ValueError("柱面数(cyl)和磁头数(head)不能为负数")
if sect < 1 or sect > spt:
raise ValueError(f"扇区号(sect)必须在1~{spt}之间")
lba = (cyl * spt * (head + 1)) + (sect - 1)
return lba
def verify_address(lba: int, total_sectors: int) -> bool:
"""
校验LBA地址是否在磁盘总扇区范围内
:param lba: 待校验LBA地址
:param total_sectors: 磁盘总扇区数(cylinders * heads * spt)
:return: 合法返回True,否则False
"""
return 0 <= lba < total_sectors
if __name__ == "__main__":
# -------------------------- 配置参数(根据你的磁盘修改)--------------------------
DISK_HEADS = 16 # 磁头数(对应Bochs配置heads=16)
DISK_SPT = 63 # 每磁道扇区数(对应Bochs配置spt=63)
DISK_CYLINDERS = 2081 # 柱面数(对应Bochs配置cylinders=2081)
TOTAL_SECTORS = DISK_CYLINDERS * DISK_HEADS * DISK_SPT # 磁盘总扇区数
# -----------------------------------------------------------------------------
print("="*60)
print("CHS-LBA 转换工具(适配你的磁盘:cyl=2081, heads=16, spt=63)")
print("="*60)
# 示例1:LBA→CHS(读DBR,LBA=1)
target_lba = 1
try:
cyl, head, sect = lba_to_chs(target_lba, DISK_HEADS, DISK_SPT)
is_valid = verify_address(target_lba, TOTAL_SECTORS)
print(f"\n【示例1:LBA→CHS】")
print(f"输入LBA:{target_lba}")
print(f"转换结果:柱面={cyl}, 磁头={head}, 扇区={sect}")
print(f"地址合法性:{'合法' if is_valid else '非法(超出磁盘范围)'}")
print(f"提示:INT13读取时,CL={sect}(扇区),CH={cyl}(柱面),DH={head}(磁头)")
except ValueError as e:
print(f"转换失败:{e}")
# 示例2:CHS→LBA(验证柱面0、磁头0、扇区2)
target_cyl = 0
target_head = 0
target_sect = 2
try:
lba = chs_to_lba(target_cyl, target_head, target_sect, DISK_SPT)
is_valid = verify_address(lba, TOTAL_SECTORS)
print(f"\n【示例2:CHS→LBA】")
print(f"输入CHS:柱面={target_cyl}, 磁头={target_head}, 扇区={target_sect}")
print(f"转换结果:LBA={lba}")
print(f"地址合法性:{'合法' if is_valid else '非法(超出磁盘范围)'}")
except ValueError as e:
print(f"转换失败:{e}")
# 自定义转换(用户可修改这里的参数)
print(f"\n【自定义转换】")
choice = input("请选择转换类型(1=LBA→CHS,2=CHS→LBA):")
if choice == "1":
lba_input = int(input(f"请输入LBA地址(0~{TOTAL_SECTORS-1}):"))
try:
cyl, head, sect = lba_to_chs(lba_input, DISK_HEADS, DISK_SPT)
is_valid = verify_address(lba_input, TOTAL_SECTORS)
print(f"转换结果:柱面={cyl}, 磁头={head}, 扇区={sect}")
print(f"地址合法性:{'合法' if is_valid else '非法(超出磁盘范围)'}")
except ValueError as e:
print(f"转换失败:{e}")
elif choice == "2":
cyl_input = int(input("请输入柱面数(0~{DISK_CYLINDERS-1}):"))
head_input = int(input(f"请输入磁头数(0~{DISK_HEADS-1}):"))
sect_input = int(input(f"请输入扇区号(1~{DISK_SPT}):"))
try:
lba = chs_to_lba(cyl_input, head_input, sect_input, DISK_SPT)
is_valid = verify_address(lba, TOTAL_SECTORS)
print(f"转换结果:LBA={lba}")
print(f"地址合法性:{'合法' if is_valid else '非法(超出磁盘范围)'}")
except ValueError as e:
print(f"转换失败:{e}")
else:
print("输入错误,仅支持1或2")
使用方法
- 安装 Python 环境(3.7 及以上版本);
- 打开脚本,修改
DISK_HEADS、DISK_SPT、DISK_CYLINDERS为你的 Bochs 磁盘配置参数; - 运行脚本,可查看示例转换结果(如 LBA=1 对应的 CHS),也可自定义输入 LBA 或 CHS 进行转换;
- 转换结果中的 “地址合法性” 可直接判断该地址是否在你的磁盘扇区范围内,避免 INT13 读取时因地址越界失败。
注:本文仅用于教育目的,实际渗透测试必须获得合法授权。未经授权的黑客行为是违法的。

978

被折叠的 条评论
为什么被折叠?



