OSDev适配真实硬件:修改load.asm中柱面与磁头地址
如何适配BIOS磁盘读取的柱面(ch)和磁头(dh)寄存器值到真实硬件?
我正在跟随一个64位操作系统教程学习,在1.3章节的load.asm文件中,看到一段用于加载内核的BIOS磁盘读取代码:
; Next are the cylinder and cylinder head to read from. You ; would need to change these if reading from an actual drive, but with ; QEMU they're just 0 mov ch, 0x00 ; Cylinder goes in ch mov dh, 0x00 ; Cylinder head goes in dh ; other register inputs also set up with instructions omitted here mov ah, 0x02 int 0x13 ; BIOS disk read
教程里将ch(柱面寄存器)和dh(磁头寄存器)设为0x00,但这个值只适配QEMU模拟器。我想把这段代码改成能在真实硬件上运行的,作为汇编初学者,我有一定理论基础,但查资料没找到明确答案,请问应该把0x00替换成什么值?
回答:
首先明确:不能直接硬写固定值,ch和dh的值取决于你的内核代码在磁盘上的实际存储位置,以及真实硬件的磁盘几何参数,以下是具体解决思路:
先获取真实磁盘的CHS几何参数
BIOS提供了int 0x13的0x08功能,可以读取当前磁盘的柱面数、磁头数、每磁道扇区数等参数。调用该功能后:ch返回柱面数的低8位cl的高2位返回柱面数的高2位,低6位返回每磁道扇区数dh返回磁头数
拿到这些参数后,才能准确计算内核所在位置对应的CHS地址。
将内核的LBA地址转换为CHS地址
现代磁盘通常用LBA(逻辑块地址)来定位扇区,你需要把内核所在的LBA地址转换成CHS地址,公式如下:- 扇区数 = (LBA % 每磁道扇区数) + 1(BIOS扇区从1开始计数)
- 磁头号 = (LBA / 每磁道扇区数) % 磁头数
- 柱面数 = (LBA / 每磁道扇区数) / 磁头数
计算完成后: - 柱面数的低8位放入
ch - 柱面数的高2位放入
cl的高2位,同时把扇区数放入cl的低6位 - 磁头号放入
dh
更推荐使用LBA扩展模式(替代CHS)
CHS模式有严重的局限性(比如最多只能访问磁盘前8GB左右的空间),而且不同硬件的磁盘几何参数差异很大,适配难度高。现代BIOS几乎都支持int 0x13的0x42功能(LBA扩展读),这种模式直接使用LBA地址,不需要计算CHS,可靠性和兼容性都远高于CHS模式,更适合真实硬件。必须处理读取错误
真实硬件上磁盘读取可能失败,调用int 0x13后要检查CF标志位:如果CF置位,说明读取失败,需要重试几次(比如3次),避免单次失败导致启动中断。
内容的提问来源于stack exchange,提问作者TC-2ND-ACC
相关产品推荐
相关产品推荐

