为什么我们只能直接访问PCI物理地址中的640k-1MB区域?

时间:2012-12-25 11:42:46

标签: c linux linux-kernel kernel ioremap

http://www.mjmwired.net/kernel/Documentation/IO-mapping.txt

153  - remapping and writing:
154     /*
155      * remap framebuffer PCI memory area at 0xFC000000,
156      * size 1MB, so that we can access it: We can directly
157      * access only the 640k-1MB area, so anything else
158      * has to be remapped.
159      */
160     void __iomem *baseptr = ioremap(0xFC000000, 1024*1024);
161 
162     /* write a 'A' to the offset 10 of the area */
163     writeb('A',baseptr+10);
164 
165     /* unmap when we unload the driver */
166     iounmap(baseptr);
167 

可以解释为什么这包含We can directly access only the 640k-1MB area吗?

2 个答案:

答案 0 :(得分:7)

简短回答:因为Linus决定这样做。

答案很长: 实际上,它认为如果没有驱动程序注册它就应该能够访问该区域是错误的。但别介意。

在过去,在1990年代的某个时候,PCI并不存在,而显卡,网卡等正在使用一种叫做ISA总线的东西。它没有花哨的功能,允许您从卡请求信息,或在卡上配置硬件地址应该在哪里。所有ISA内存都在A0000(640K)和FFFFF(1MB-1)之间。所以,在Linux的早期,这就是图形和这样的东西存在的地方,内核无法真正知道这些东西在哪里。无论哪种方式,由于更好的硬件的发展,我们现在没有这些类型的硬件。很好的摆脱!

出于兼容性原因,在启动过程中仍然使用此内存空间,因为在您加载驱动程序并设置PCI硬件之前,它的行为处于“传统模式”,因此您仍然可以运行真正的旧DOS和其他旧版软件没有它的机器表现得很奇怪。

但是,例如,一旦配置了您的图形卡,就会设置BAR(总线地址范围)来告诉全世界它在总线地址空间(物理地址)中的位置。 ioremap会将物理地址映射到您可以在内核中使用的虚拟地址 - 在此示例中为baseptr。 [我可以详细了解ioremap,因为我一直在研究从最近派生的代码]。

正如另一个答案所说,您将需要询问设备BAR是什么(它是PCI配置空间的一部分),然后将其内存映射到虚拟地址。您可以看到正在使用的内容lspci -v|grep Memory(当然,仅使用lspci -v将为您提供更多信息,包括哪些设备具有哪些内存)。这些地址是物理地址。

答案 1 :(得分:1)

据我所知,您所看到的评论是错误的,应为“0x000A0000至0x000BFFFF”(或“640 KiB至768 KiB”)。

这对应于80x86 PC系统上的传统VGA显示存储区(您必须通过2个小型64 KiB窗口和存储体切换之一访问可能大量的视频显示存储器),这被“线性帧”取代缓冲“允许您直接访问整个视频显示内存的技术。

除了评论错误之外,我还假设代码被误导,参数0xFC000000(“内存的总线地址”)只是某人编写的随机数。

基本上我在这里说的是该示例是使用IO映射的示例;并且不打算用于确定在任何情况下任何设备的任何特定架构下哪些(物理,虚拟或总线)地址有效。