第 1 部分
对于旧 VGA 模式,有一个固定地址可写入(旧版)显示内存区域。对于文本模式,该区域从 0x000B8000 开始。对于图形模式,它从 0x000A0000 开始。
对于高分辨率视频模式(例如,由 VESA/VBE 接口设置的模式),这不起作用,因为传统显示内存区域的大小限制为 64 KiB,并且大多数高分辨率视频模式需要更多空间(例如 1024 * 768 * 32-bpp = 2.25 MiB)。为了解决这个问题,VBE 支持两种不同的方法。
第一种方法称为“组切换”,在这种方法中,任何时候只有一部分显卡的显存映射到遗留区域(您可以更改映射的部分)。这可能会很麻烦——例如,要绘制一个像素,您可能需要计算该像素在哪个存储库中,然后切换到该存储库,然后计算存储库中的哪个偏移量。更糟糕的是,对于某些视频模式(例如,每个像素有 3 个字节的 24-bpp 视频模式),可能只有像素数据的第一部分在一个存储库中,而同一像素数据的第二部分在不同存储库中.这样做的主要好处是它适用于实模式寻址,因为传统显示内存区域低于 0x00100000。
第二种方法称为“Linear Framebuffer”(或简称为“LFB”),可以访问视频卡的整个显示内存区域,而无需任何混乱的银行切换。您必须询问 VESA/VBE 接口该区域在哪里(通常位于“PCI 孔”中,介于 0xC0000000 和 0xFFF00000 之间)。这意味着您无法在实模式下访问它,需要使用保护模式或长模式或“虚模式”。
要在使用 LFB 模式时找到像素的地址,您需要执行类似“pixel_address = display_memory_address + y * bytes_per_line + x * bytes_per_pixel”的操作。 “bytes_per_line”来自 VESA/VBE 接口(可能与“horizontal_resolution * bytes_per_pixel”不同,因为水平线之间可以有填充)。
对于“银行切换”VBE/VESA 模式,它变得更像:
pixel_offset = y * bytes_per_line + x * bytes_per_pixel;
bank_number = pixel_offset / bank_size;
pixel_starting_address_within_bank = pixel_offset % bank_size;
对于一些旧的 VGA 模式(例如 256 色“模式 0x13”),它与 LFB 非常相似,除了行之间没有填充,您可以执行“pixel_address = display_memory_address + (y * Horizontal_resolution + x) * bytes_per_pixel ”。对于文本模式,它基本上是相同的,除了 2 个字节确定每个字符及其属性 - 例如“char_address = display_memory_address + (y * Horizontal_resolution + x) * 2”。对于其他旧的 VGA 模式(单色/2 色、4 色和 16 色模式),视频卡的内存排列完全不同。它被分成“平面”,其中每个平面包含一位像素,并且(例如)要在 16 色模式下更新一个像素,您需要写入 4 个单独的平面。出于性能原因,VGA 硬件支持不同的写入模式和不同的读取模式,而且它可能会变得很复杂(过于复杂,无法在此处充分描述)。
第 2 部分
对于 I/O 端口(在 80x86 上,“PC 兼容”),有 3 个常规类别。第一个是使用固定 I/O 端口的“事实上的标准”遗留设备。这包括 PIC 芯片、ISA DMA 控制器、PS/2 控制器、PIT 芯片、串行/并行端口等。几乎所有描述如何对这些设备进行编程的内容都会告诉您设备使用哪些 I/O 端口。
下一个类别是传统/ISA 设备,其中设备使用的 I/O 端口由卡本身的跳线决定,并且没有理智的方法可以通过软件确定它们使用哪些 I/O 端口。为了解决这个问题,最终用户必须告诉操作系统每个设备使用哪些 I/O 端口。值得庆幸的是,这些硬壳的东西都已经过时了(尽管这并不一定意味着没有人在使用它)。
第三类是“即插即用”,其中有一些方法可以询问设备它使用哪些 I/O 端口(在大多数情况下,更改设备使用的 I/O 端口)。这方面的一个例子是 PCI,其中有一个“PCI 配置空间”,可以告诉您有关每个 PCI 设备的大量信息。对于这个类别,如果不在运行时进行,任何人都无法确定哪些设备将使用哪些 I/O 端口,并且更改某些 BIOS 设置可能会导致任何/所有这些设备更改 I/O 端口。
另请注意,英特尔 CPU 只是一个 CPU。没有什么可以阻止这些 CPU 用于与“PC 兼容”计算机完全不同的东西。英特尔的 CPU 手册绝不会告诉您任何有关 CPU 本身之外存在的硬件(包括芯片组或设备)的信息。
第三部分
http://osdev.org/(他们的 wiki 和论坛)可能是获取更多信息(面向操作系统开发人员/爱好者)的最佳去处。