2

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吗?

4

2 回答 2

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会给你更多的信息,包括哪个设备有什么内存)。这些地址是物理地址。

于 2012-12-25T12:32:13.230 回答
1

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

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

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

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

于 2012-12-25T12:19:03.563 回答