Вопрос

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 

Can one explain why this holds We can directly access only the 640k-1MB area?

Это было полезно?

Решение

Short answer: Because Linus decided to do it that way.

Long answer: Actually, it think it's wrong that you should be able to access even that area without a driver signing up for it. But never mind that.

In the old days, sometime in the 1990's, PCI didn't exist, and graphics cards, network cards, etc, were using something called ISA bus. It didn't have fancy features that allow you to request information from the card, or configure things onto the card with regards to where it thinks it's hardware addresses should be. All of the ISA memory is between A0000 (640K) and FFFFF (1MB-1). So, in the early days of Linux, this was where graphics and such things lived, and the kernel couldn't really know where these things were. Either way, we don't have these sorts of hardware these days, thanks to evolution of better hardware. Good riddance!

For compatibility reasons, this memory space is still used during boot, since until you get the drivers loaded and PCI hardware set up, it behaves in "legacy mode", so you can still run really old DOS and other old software on the machine without it behaving weird.

However, once your graphics card, for example, is configured, it will have BAR's (Bus Address Range) set up to tell the world where it is located in the bus address space (physical address). ioremap will map the physical address to a virtual address that you can use in the kernel - baseptr in this example. [I could go into much more detail about ioremap, as I've been working on some code derived from that recently].

As the other answer says, you will need to ask the device what it's BAR is (which is part of the PCI configuration space), and then map it's memory to a virtual address. You can see where things are using lspci -v|grep Memory (of course, using just lspci -v will give you a lot more information, including which device has what memory). These addresses are the physical addresses.

Другие советы

As far as I can tell, the comment you're looking at is wrong and should be "0x000A0000 to 0x000BFFFF" (or "640 KiB to 768 KiB").

This corresponds to the legacy VGA display memory areas on 80x86 PC systems (where you have to access a potentially large amount of video display memory through one of 2 small 64 KiB windows and bank switching), which was superseded by "linear frame buffer" techniques that allowed you to access the entire video display memory directly.

In addition to the comment being wrong, I'd also assume that the code is misguided and that the parameter 0xFC000000 (the "bus address of the memory") is just a random number someone made up.

Essentially what I'm saying here is that the example is an example of using IO mapping; and is not intended to be used to determine which (physical, virtual or bus) addresses are valid under any specific architecture for any device under any circumstances.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top