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