获取EBDA基地址/常规内存最高可用地址最可靠的方法是什么?
获取EBDA基地址/常规内存最高可用地址的最可靠方案
下面是x86实模式下bootloader场景的分层校验方案,是目前工业界bootloader(GRUB、SeaBIOS等)通用的实现逻辑,可靠性最高:
- 优先调用
INT 0x15 EAX=0xE820BIOS中断获取全系统内存映射
该中断返回的内存描述符中,筛选出类型为可用内存(类型值为1)、地址范围低于1MB的段,取所有符合条件段的最高结束地址,即为常规内存的最高可用地址,该地址天然对应EBDA的起始基地址。所有2000年之后生产的x86 BIOS均支持该中断,准确性远高于直接读取BDA存储的值。 - 老旧BIOS降级兼容方案
若INT 0x15 EAX=0xE820调用失败(仅存在于2000年之前的极老设备),组合两个来源做交叉校验:- 调用
INT 0x15 AH=0x88中断获取常规内存大小,返回的AX寄存器值单位为KB,乘以1024得到第一个候选地址 - 读取BDA偏移
0x40E处的16位EBDA段基址,左移4位得到第二个候选地址
取两个候选地址的较小值作为最终结果,避免访问到被EBDA占用的内存区域。
- 调用
- 兜底容错规则
无论上述哪种方式获取到的地址,都要做范围校验:如果结果低于0xA0000(640KB)或高于0xFFFFF(1MB),直接丢弃异常值,强制使用0xA0000作为兜底的常规内存最高可用地址。该兜底逻辑最坏情况仅会损失少量可用内存,不会触发非法内存访问的严重问题。
注:若运行在UEFI环境下,不要使用上述BIOS中断方案,直接调用UEFI启动服务的
GetMemoryMap()接口读取内存描述符,筛选低于1MB的可用内存最高地址即可。
内容的提问来源于stack exchange,提问作者nexos
相关产品推荐
相关产品推荐

