Keeping the Screen Turned off While Getting Inputs

Vladimir Dergachev volodya at mindspring.com
Sun Aug 27 15:52:09 UTC 2023



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


More information about the xorg mailing list