显存读写

        要在显示屏显示图像,方法有两种,mmio pio。现在的显卡都应当支持vbe。

         vbe 提供了保护模式的接口,bios方式太旧了,且保护模式操作太复杂,故想找个简单的方式,但这方面的资料太少,花了不少时间,终于成功。

         利用bios 10号中断取得保护接口信息,除5、7、9号程序,还有几个端口信息,好不容易找到保护模式切换显示模式的使用方法。不过还不确定bios返回端口的具体用途,但显示设置的函数实验成功。

        显存的访问,在低分辨率及字符模式,地址在0xa0000---0xbffff之间,但到了高分辨率就一般在高端内存。网上查的说可以直接访问,我怎么实验都没成功。搞了一个星期,终于可以正确显示。

      要想访问显存,有3步:

     1. 显存的物理地址,英文叫LFB,可以bios 1号中段获取,资料上说可以自主设置,不过我在bochs上没成功,不知哪里出错了,后来没搞了。

      2. MTRR,说起来有点复杂,意思就是把显存地址注册到地址空间。独显、核显、仿真对地址分配有没区别,还待实验。

      3. 显卡设置,开启lfb。好象只能显示真彩色,低色彩的还没成功。

    开启之后,就显存地址就是物理地址了,统一在4G之内,读写也正常,屏幕显示正常,不过bochs显示内存指令不能显示,不知道是bochs的问题,还是本来就这样。关键代码在下面

void BgaSetVideoMode(unsigned int Width, unsigned int Height, unsigned int BitDepth, int UseLinearFrameBuffer, int ClearVideoMemory)
{
    // VBE disabling
    BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
    //
    BgaWriteRegister(VBE_DISPI_INDEX_XRES, Width);
    BgaWriteRegister(VBE_DISPI_INDEX_YRES, Height);
    BgaWriteRegister(VBE_DISPI_INDEX_BPP, BitDepth);
    BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED |
        (UseLinearFrameBuffer ? VBE_DISPI_LFB_ENABLED : 0) |
        (ClearVideoMemory ? 0 : VBE_DISPI_NOCLEARMEM));
}

 

DWORD find_empty_mtrr()
{
    
        //RDMSR将64位由ECX寄存器指定的MSR(model specific register,
        //模式指定寄存器)的内容读出至寄存器EDX:EAX中
        //(在支持intel64架构的处理器中RCX的高32位忽略)。
        //MSR的高32位内容存放在EDX寄存器中,
        //MSR的低32位内容存放在EAX寄存器中
        //(在支持intel64架构的处理器中RDX和RAX的高32位忽略)。
        //如果MSR中没有64位(有些位没有实现),
        //则EDX:EAX中没有实现的位置则未定义。
        //寄存器2个一组
        DWORD empmtrr,port,val1,val2;
        empmtrr=0;
        for (port=0x201;port<0x200+16;port=port+2)
        {
            rdmsr(port,val1,val2);
            if (!(val1&0x0800))
            {
                port--;
                empmtrr=port;
                break;
            }
        }
        return empmtrr;
}
void enableMtrr(DWORD addr)
{

    DWORD mttr,val1,val2;
    mttr = find_empty_mtrr();
    // ; LFB , +8 M , write combine
    //|64 保留    | 物理地址 12|11  8|7 type |0
    //|64 保留    | 掩码|Valid 11|10 保留 |0    
    wrmsr(mttr,addr | 1,0);
    
    wrmsr(mttr+1,0xff800800,0xf); 
//     enable mtrr's
    rdmsr(0x2ff,val1,val2);  
    wrmsr(0x2ff,val1 | 0x800 ,val2);
     
        
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻雀123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值