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

0x9*_*x90 2 c linux kernel linux-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 
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*son 7

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

答案很长:实际上,如果没有司机注册,你应该能够访问该区域,这是错误的.但别介意.

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

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

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

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