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
可以解释一下为什么这样我们只能直接访问 640k-1MB 区域
吗?
最佳答案
简短回答:因为 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
将为您提供更多信息,包括哪个设备有什么内存).这些地址是物理地址。
关于c - 为什么我们只能直接访问一个PCI物理地址中的640k-1MB区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14030320/