You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将自制简易OS从QEMU移植到物理机启动需做哪些修改?

实模式显存地址适配与自动获取方案

1. 0xb8000在真实笔记本上是否可用?

0xb8000是VGA文本模式的标准显存物理起始地址,在绝大多数支持传统BIOS的x86笔记本上都能正常工作——只要你的引导加载程序是从实模式启动(自制引导程序基本都是这个路径),直接写入该地址在大部分机器上都能显示内容。

唯一需要注意的例外:如果笔记本使用UEFI引导且关闭了CSM(兼容支持模块),实模式下可能无法直接访问VGA显存,但这类场景下你自制的引导程序大概率无法启动,所以0xb8000对你的当前场景基本通用。

2. 自动获取显存地址的方法

如果要追求更强的硬件兼容性(比如适配特殊显示卡,或后续进入保护模式/长模式),可以通过以下两种方式实现:

方式一:实模式下调用BIOS中断

在引导加载程序中调用BIOS中断int 0x10的相关子功能,获取显存信息后传递给内核:

  • 子功能0x0F:获取当前视频模式,返回的es寄存器会指向显存段地址(文本模式下通常是0xb800,结合偏移0即可得到0xb8000物理地址)
  • 子功能0x12:获取显示适配器扩展信息,可直接得到显存起始地址和大小

示例汇编代码(在引导程序中执行,结果存入内存固定位置供内核读取):

mov ah, 0x0F
int 0x10
; 返回值说明:
; al = 当前视频模式编号
; bh = 当前显示页号
; es 寄存器 = 显存段地址(文本模式下为0xb800)

方式二:保护模式下使用VBE扩展

如果内核后续要进入保护模式,推荐使用VESA BIOS Extensions(VBE)获取线性帧缓冲(LFB)地址:

  1. 调用int 0x10子功能0x4F00获取VBE控制器信息
  2. 调用0x4F01获取支持的显示模式列表
  3. 调用0x4F02设置目标模式,从返回的结构体中提取线性显存地址

这种方式能适配更多现代显示硬件,且支持更高分辨率的图形模式。

3. 现有内核代码的小优化

你的C代码存在局部变量覆盖全局变量的问题,且执行完main后会跑飞,建议修改为:

extern "C" void main() {
    char* addr = (char*)0xb8000;
    for (int i = 0x00; i < 0xff; i += 0x11) {
        *addr++ = 'A';
        *addr++ = i;
    }
    while(1); // 阻止执行完后跑飞
}

内容的提问来源于stack exchange,提问作者Blue Herring

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:05:27