On Sun, 27 Aug 2023, Ahmad Nouralizadeh wrote:

Thanks (also Dave and Carsten)! Full of useful information not easily found (if 
even found) on the Internet!

You are welcome :)

So, in summary, the communication is done through a series of memory mapped 
regions in
the address space of the graphics library (e.g., OpenGL).
The image data is transferred 1) from the X client to the X server and 2) from 
there to the graphics library. Are both of these transfers made using shared 
memory?



To be pedantic, the memory mapped regions have address space of whatever process mapped them, and there can be several mappings active at the same time (think two OpenGL apps running on different cores).

Some memory regions are mapped by DRI driver in the kernel, some by X server, some by OpenGL apps (via calls to OpenGL library). The mapped sets don't have to be the same and this depends a lot on the particular graphics card and the driver - I don't know well Intel onboard graphics, so someone else please chime in.

The shared memory (as POSIX shared memory) is a different mechanism that also does memory mapping. From the point of view of programmer you acquire POSIX shared memory via calls like shm_open().

The memory involved in OpenGL is all mapped using calls to "mmap()".

mmap() is much simpler to use - you issue it on a file and you memory mapped a portion of it. You can do this on any file - for example, I made a library libMVL and R package RMVL that uses memory mapping of files on SSD to analyze large data.

Unlike mmap() POSIX shared memory was designed as method of communication between different processes and has mechanisms to arbitrate access - this is what makes it complicated. As far as I know, POSIX share memory does not give access to any hardware devices.

If you want to have fun, try memory mapping /dev/mem as root and then reading it carefully - this gives direct access to physical memory of your computer.

I think the first page is either filled with 0, or contains interrupt pointers - its been a while so I don't remember it.

If you do lspci -v it will list available memory mapped regions of various device. For example, the laptop I am typing this on has an NVidia card:

01:00.0 3D controller: NVIDIA Corporation GM108M [GeForce MX130] (rev a2)
        Subsystem: Dell GM108M [GeForce MX130]
        Flags: bus master, fast devsel, latency 0, IRQ 255
        Memory at d2000000 (32-bit, non-prefetchable) [size=16M]
        Memory at c0000000 (64-bit, prefetchable) [size=256M]
        Memory at d0000000 (64-bit, prefetchable) [size=32M]
        I/O ports at e000 [disabled] [size=128]
        Expansion ROM at d3000000 [disabled] [size=512K]
        Capabilities: <access denied> (you get these by running lspci as root)
        Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia

This card has three mappable regions of memory. The ioports exist in a separate memory space specific to Intel processors - these are going out of fashion. The expansion ROM could have been mappable, but isn't because, I think, it has been copied to memory after boot - ROM access is slow.

The non-prefetchable region contains registers - prefetching will screw up access to them.

The 256M region is likely the video memory, so if you memory map /dev/mem starting at 0xc0000000 you will be able to read and write to it. Try filling with some pattern like 0xAA - you will muck up your screen and, maybe, crash X. Issue "sync" before trying to save your data in case of hard lockup. There might be a chance of damage to video card, depending on which one your have and whether you wrote to registers or some other sensitive place accidentally and made a video card overheat, or apply too big a voltage to the chip.

Many modern hardware device are very programmable so the hardware starts up cold with bare minimum of functionality and then the firmware programs the voltage regulators to whatever is specified in ROM and sets PLLs to correct frequencies for the clocks. I don't actually know whether any video cards have programmable voltage regulators, but they do have programmable PLLs and they might be set to too high a frequency. With cards I played with, setting PLLs by accident is not that easy, and if you do it wrong the lockup is instantaneous. If you pull the plug right away you should not get much damage as thermal processes are one of the few things that are usually slower than human reflexes (though read about hot-wire barretter as a counterexample).

Writing to video card memory should be safer, but it usually contains programs for execution by the GPU, so by writing there you create a random program that could be triggered by X server that does not know about your write. I don't think the chance of that programming the PLL by accident is very high, but worth mention for the sake of pedantism. And you might be able to do it on purpose.

I don't know what the third region does, maybe a different view of the registers - prefetching makes access much faster, so you would read and write non-critical data there, issue a barrier of some sort and then trigger by writing to register in non-prefetchable space. This is pure speculation, read noveau driver to find out.

best

Vladimir Dergachev

Reply via email to