如何在不使用 BIOS 的情况下将数据写入显卡? [英] How to write data to a graphics card without using BIOS?

查看:24
本文介绍了如何在不使用 BIOS 的情况下将数据写入显卡?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个(非常简单的)操作系统.我目前正在学习显卡.

这是我目前所知道的(如果我错了,请纠正我):

  • 显卡有两种模式:文本模式和图形模式.
  • 您可以使用 BIOS 将数据写入显卡(而不是直接访问显卡).

我想做的是不使用 BIOS 直接写入显卡的显存(因为我想了解它是如何工作的).所以我有以下问题:

  1. 我怎么知道显卡显存的基地址是什么,是这个吗通过探测 PCI 总线获取基地址来完成,还是基地址是固定的(就像 COM 端口的基地址是固定的一样)?
  2. 是否所有显卡都以相同的方式访问,还是我必须为所有可用的显卡创建设备驱动程序?

<小时>

我使用的是 x86.

解决方案

简介

显卡是一个非常复杂的话题,我有信心说它们是您在 PC 上找到的最复杂的子系统.
如果您发现自己在编写

虽然这可能不是很容易理解,但了解程序员在编写现代视频卡之前必须了解的众多技术就足够了.

您当然可以查看 Linux 源代码,但请注意,即使对于简单的控制器,Linux 内核通常也无法立即理解 - 它不是玩具操作系统,它是具有自己的 API 和接口的真实操作系统必须适合硬件接口(实际上相反).
此外,只有 Intel 和 AMD 视频驱动程序是真正开源的,其他的要么是专有的,要么只是一堆未记录的代码.

常见VGA模式编程简述

如果您只想对 VGA 进行编程(确实是一项非常值得尊敬的任务!),您可以从 设置视频模式 03h(文本模式)或13h(图形模式).

视频模式 03h
帧缓冲区位于 0b8000h(物理地址),通常以 0b800h:0000h 的形式访问,因为零偏移量很方便.
屏幕由 80x25 个字符组成,每个字符在帧缓冲区中占用一个字(16 位).
低字节是字符代码 - 使用的字符映射将 glyph 关联到代码(例如41 小时到 A).
高位字节是属性字节 - 低半字节是前景色,高半字节是背景色.
更多信息可以在上面的 EGA/CGA/VGA 链接中找到.

视频模式 13 小时
这是一个 320x200 像素的图形模式,帧缓冲区位于 0a0000h(物理地址),通常以 0a000h:0000h 访问,原因同上.
每个像素都是一个字节,字节的值选择像素的颜色.
可以通过对 DAC 寄存器(VGA 适配器为 3c7h、3c8h、3c9h)进行编程来更改默认调色板.

答案

<块引用>

显卡有两种模式:文本模式和图形模式.

不一定,今天这种区别可能已经不存在了.
MDA 只有文本模式.
EGA、CGA和VGA和SVGA都有.

现代方法是绘制文本,但是在启动期间或在特定情况下(例如 BSOD) 使用文本模式下的基本视频驱动程序.
此驱动程序可能使用 BIOS 服务,因为视频驱动程序可能不可用/不可靠.

<块引用>

您可以使用 BIOS 将数据写入显卡

直到 SVGA 时代,BIOS 支持才停止.

<块引用>

我怎么知道显卡显存的基地址是什么,是通过探测PCI总线得到基地址,还是基地址是固定的(就像COM口基地址是例如固定)?

从历史上看,视频卡已连接到 ISA、PCI、AGP 和 PCIe 总线.
只有 ISA 总线是不可配置的(至少从一开始就不是),其他的每个功能(PCI 总线中最小的可寻址实体)都有可配置的 BAR(基地址寄存器).

为了获得显卡的 MMIO 寄存器的基地址,PCI 或 PCIe 总线 必须是枚举 并且必须读取/设置配置空间中的标准寄存器.

处理PCIe并不像处理PCI那么容易.

请注意,即使 UART 也没有固定地址,它们默认配置为映射到传统(3f8h、2f8h、3e8h 和 2e8h)地址,但硬件(是?)在 SuperIO 芯片位于模拟 PCI 到 ISA 桥的 PCI 到 LPC 桥后面.
随着 Intel 平台集线器架构的出现(即南北桥的消亡),SuperIO 芯片最终进入了 PCH 或移动到 SPI 控制器后面.

<块引用>

是否所有显卡都以相同的方式访问,还是我必须为所有可用的显卡创建设备驱动程序?

每张显卡本身就是一个美丽的恶毒生物.
每个型号都需要一个设备驱动程序.
某些驱动程序可以重复用于整个模型系列,但通常情况并非如此.

I want to make an (extremely simple) operating system. I am currently learning about graphics cards.

This is what I know so far (please correct me if I am wrong):

  • A graphics card has two modes: a text mode, and a graphics mode.
  • You can write data to a graphics cards using BIOS (instead of accessing the graphics card directly).

What I want to do is to write directly to the graphics card's video memory without using BIOS (because I want to understand how things work). So I have the following questions:

  1. How do I know what is the base address of the video memory of the graphics card, is this done by probing the PCI bus to get the base address, or is the base address fixed (just like the COM ports base addresses is fixed for example)?
  2. Are all graphics cards accessed in the same way, or do I have to create device drivers for all available graphics cards?


Edit: I am using x86.

解决方案

Introduction

Graphics cards are a very complex topic, I'm confident in saying that they are the most complex subsystem you'll find on a PC.
If you ever found yourself lost programming an XHCI (USB 3.0) or an old RTL8239A network interface card then be prepared because this is much more complex.

Graphics controllers are the products of a very competitive marketing - rarely a vendor opens the specifications and when it does, it gives an intentionally poor support.
If you add that the hardware itself deals with: codecs, audio (yes, audio streams too), 3D programmable pipelines, video signals and video outputs, surface formats, media formats, DMA and memory remapping then you can see that it is not an easy task to program a video card.

The better approach, in my opinion, is to "retrace the history" of the video cards. Start from the MDA then move to CGA then EGA and finally to VGA.

The VGA legacy is still supported, the specifications can be found here or in the first part of this PDF from Intel.
You can program the VGA without the BIOS "easily" - meaning that it is an already well-known and documented hardware architecture (but not necessarily easy to configure).
I don't remember if the previous adapters were subsets of the VGA or not, if not they aren't supported anymore probably.
You can try with a virtual machine or an emulator.

When you are satisfied with the VGA you can move to the SVGA.
Here come the troubles: as Wikipedia confirms, the VGA was the last truly standardised video card/adapter interface:

Unlike VGA—a purely IBM-defined standard—Super VGA was never formally defined.

The organisation VESA standardised a BIOS API called Video BIOS Extensions to allow the use of SVGA cards to driverless OSes but that's not what you were looking for.
You can try reverse engineering a VBE BIOS but I think it will be a nightmare - a senseless stream of writes to IO ports and MMIOs.
Making sense of tenths of configuration registers without any reference is almost impossible.

Note that we are still talking about 1998 technology up to this point.
After the VESA VBE effort, no more standard interfaces have been published - the only reliable way to program a video card with less than 20 years is by signing an NDA with its vendor.

Luckily, recently (actually, not anymore), Intel entered the market with its Intel GFX (a.k.a. Intel HD Graphics) cards.
Intel never aimed to manufacture top-of-the-notch video cards, not even closely - so they can be open about their architecture since that's not their core business.
The result is this marvellous set of Programming Reference Manuals that describe the functionality of their video cards.
Complete with (traditionalistic) minimal information to program them.

In general, hobbyists stops before this point (at the SVGA checkpoint), because the hardware has become very complex and the efforts very huge.
For example, my Haswell integrated video card is documented with 17 PDFs of about 250 pages each (on average).
The display part is documented in a PDF on its own, the framebuffer has disappeared in favour of Display surface and the display part alone of the hardware is this:

While this may not be very comprehensible, it should suffice to get an idea of the numerous technology that a programmer must understand before programming a modern video card.

You can surely take a look at the Linux source code but beware that the Linux kernel is no usually of immediate understanding even for simple controllers - it is not a toy OS, it is a real OS with its own API and interface that must fit the hardware interface (actually the other way around).
Furthermore, only the Intel and AMD video drivers are really open source, the others are either proprietary or just a bunch of undocumented code.

Brief outline of common VGA modes programming

If you just want to program the VGA (a very respectable task indeed!) you can start by setting the video modes 03h (text mode) or 13h (graphics mode).

Video mode 03h
The frame buffer is at 0b8000h (physical address), usually accessed as 0b800h:0000h as it is handy to have a zero offset.
The screen is made up of 80x25 characters, each characters occupy a word (16-bit) in the frame buffer.
The low byte is the character code - the character map used will associate a glyph to a code (e.g. 41h to A).
The high order byte is the attribute byte - the low nibble is the foreground colour, the high nibble is the background colour.
More information can be found in the EGA/CGA/VGA links above.

Video mode 13h
It is a graphical mode with 320x200 pixel, the frame buffer is at 0a0000h (physical address) usually accessed as 0a000h:0000h for the same reason of above.
Each pixel is a single byte, the value of the byte selects the colour of the pixel.
The default palette can be changed by programming the DAC registers (3c7h, 3c8h, 3c9h for the VGA adapter).

Answers

A graphics card has two modes: a text mode, and a graphics mode.

Not necessarily, today this distinction may not exist anymore.
The MDA had only a text mode.
EGA, CGA and VGA and SVGA had both.

The modern approach is to draw the text, however during boot or during particular situations (e.g. BSOD) a basic video driver in text mode is used.
This driver probably uses a BIOS service since the video driver may not be available/reliable.

You can write data to a graphics cards using BIOS

Up to the SVGA era, then BIOS support was discontinued.

How do I know what is the base address of the video memory of the graphics card, is this done by probing the PCI bus to get the base address, or is the base address fixed (just like the COM ports base addresses is fixed for example)?

Video cards have been connected through the history to the ISA, PCI, AGP and PCIe buses.
Only the ISA bus wasn't configurable (at least not from the beginning), the others had configurable BARs (Base Address Registers) per function (the smallest addressable entity in the PCI bus).

In order to get the base address of the MMIO registers of a video card the PCI or PCIe bus must be enumerated and the standard registers in the configuration space must be read/set.

Dealing with PCIe is not as easy as dealing with PCI.

Note that not even the UARTs have a fixed address, they are configured by default to map to the legacy (3f8h, 2f8h, 3e8h and 2e8h) addresses but the hardware was (is?) in a SuperIO chip behind a PCI-to-LPC bridge that emulated a PCI-to-ISA bridge.
With the advent of the Intel platform hub architecture (i.e. the death of the north and south bridge) the SuperIO chip eventually made it into the PCH or moved behind the SPI controller.

Are all graphics cards accessed in the same way, or do I have to create device drivers for all available graphics cards?

Each graphic card is a beautiful vicious creature on its own.
A device driver is needed for each model.
Some driver can be reused for a whole family of models but this is not true in general.

这篇关于如何在不使用 BIOS 的情况下将数据写入显卡?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆