
Writing to the Framebuffer - __sb__
http://seenaburns.com/2018/04/04/writing-to-the-framebuffer/
======
Jasper_
Keep in mind that /dev/fb, on a modern system, isn't an actual framebuffer on
your GPU. It's a land of make-believe, mostly supported to get the kernel
console ("fbcon") working. Going back for at least 10 years, the kernel mode-
setting API (KMS) is used to display buffers, and there's compatibility code
which sets up a user-space buffer in the KMS subsystem [0] which is swapped to
when fbcon happens through a large chain of strange events that are hard to
describe. This explains why you can't write to a /dev/fb during an active X11
session and have it show up: it's a fake buffer that only shows up when KMS
isn't in use.

[0]
[https://github.com/torvalds/linux/blob/master/drivers/gpu/dr...](https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_fb_helper.c)

~~~
therein
That is correct. One exception perhaps is embedded devices with displays,
including EInk tablets.

For instance one thing I have been working on is a library that allows writing
to and partially refreshing an EInk display with low latency enabling this[0].

I am curious what would happen if I got xorg working on this and used an
additional application to call the `refresh` ioctl so that the changes get
displayed on the screen.

[0]
[https://gfycat.com/CornyHugeIndianRhinoceros](https://gfycat.com/CornyHugeIndianRhinoceros)

~~~
gandreani
That's very awesome! What tablet and project is that?

~~~
therein
Thanks. It is the Remarkable Tablet but the API is entirely undocumented. Took
a fair bit of analysis to get it to this state but now it is actually ready
for people to build their own applications upon it.

The GitHub project:
[https://www.github.com/canselcik/libremarkable](https://www.github.com/canselcik/libremarkable)

~~~
codetrotter
This is cool, you should post it as a “Shown HN”. And don’t get discouraged if
it doesn’t immediately garner attention. Post it again later if you only get
an insignificant amount of upvotes. Your project is front page worthy and if
it doesn’t get there the first time then it’s just bad timing / bad luck (or
poorly worded title, that’s a possibility as well of course).

Post it until it gets to the front page, waiting a couple of days or more
between each time you post it.

~~~
hultner
I agree, this is super cool and deserves attention.

~~~
therein
Thank you. :)

------
tbirdz
The reason why sudo wasn't working is that it runs the command with root
privileges, but redirecting to a file with > is done through the shell, which
is running under your normal user level privileges. If you want to redirect to
a file that only root can write to, you can use the tee command. That command
will write anything passed to it via stdin to the file given as an arg.

For example, echo "foo" | sudo tee /path/to/file

or any of the other ways listed here:
[https://stackoverflow.com/questions/82256/how-do-i-use-
sudo-...](https://stackoverflow.com/questions/82256/how-do-i-use-sudo-to-
redirect-output-to-a-location-i-dont-have-permission-to-wr)

~~~
digi_owl
My first thought was to use the sh -c method.

~~~
pwg
Or, just use 'su' to become root, then write to the device file.

~~~
rusk
su isn't an option that's available to "regular" users. In particular in an
environment where sudo has been set up correctly then it may be for the reason
that you want regular users to be able to perform "some" powerful functions
without giving them the keys to the system.

------
jwilk
> one horizontal line at a time, with one byte for Blue,Green,Red,Alpha(?) per
> pixel (seems like 24-bit true color).

You can (and should if you are writing software not only for yourself) ask the
kernel about the framebuffer layout using FBIOGET_FSCREENINFO and
FBIOGET_VSCREENINFO ioctls.

[https://www.kernel.org/doc/Documentation/fb/api.txt](https://www.kernel.org/doc/Documentation/fb/api.txt)

------
vardump
There may be more than just one simultaneous framebuffer per display on the
hardware level.

GPUs can actually scan to a display from _multiple overlapping framebuffers_
in different resolutions and color formats _in the same time_. Alpha blending
and rotations are often supported as well.

A bit like a very large mouse cursor. In a way, mouse cursors are also
framebuffers. Or like hardware video layers in the nineties.

~~~
derefr
> GPUs can actually scan to a display from multiple framebuffers in different
> resolutions and color formats in the same time.

This is also how early SLI worked: each GPU has a framebuffer, one holding the
"even" scanlines and one holding the "odd" scanlines. Each GPU does its own
rendering work to its own framebuffer, each rendering a vertically-squashed
scene, with one scene offset by one pixel vertically. The master GPU then
interleaves the two framebuffers together (pulling data from the slave GPU's
framebuffer over the SLI link) when outputting a field.

~~~
jimmies
To add to that, "early SLI" stands for Scan-Line Interleave, not Scalable Link
Interface like it is now. CRT was some crazy shit to deal with. I'm glad I
never had to deal with it.

If you ever wondered why some old Youtube video looked like crap and has lines
that don't match up, interleaving was why.

~~~
codedokode
Usually artifacts are not the result of using interleaved source but the
result of recoding done wrong. I remember reading mencoder manual about
"pulldown" and other recoding options.

------
hazeii
Worth noting that the framebuffer works really well on the Raspberry Pi; you
can switch between console and X, all while using the framebuffer. It's even
happy switching between bit depths (using 'fbset') at the same time.

If you want a really fast framebuffer system, get something like an old Nvidia
7600GT and use 'nvidiafb'; while this won't work with X at the same time, it's
blazingly fast and gives brilliant console text output (modern GPUs are super-
slow by comparison).

------
pjc50
Is /dev/fb writing directly to the framebuffer or is there translation going
on kernel side? Is the card in VESA / BIOS mode when on a virtual console
without X?

~~~
yjftsjthsd-h
I _think_ the kernel docs[0] indicate that it's a kernel-managed abstraction?

[0]
[https://www.kernel.org/doc/Documentation/fb/framebuffer.txt](https://www.kernel.org/doc/Documentation/fb/framebuffer.txt)

------
codedokode
I have a feeling that framebuffer must be something very slow. When I used
both Windows and Linux without proprietary drivers for a video card (so they
use some generic VGA or VESA driver), GUI would be slower. For example,
scrolling in a window was laggy. Or dragging a window around the screen. Why
it could be so? Do video card vendors intentionally slow down video memory
access or is VGA or VESA some poorly designed standard?

I was not using Compiz or something like this so it cannot be explained with
the lack of 3D acceleration.

Also, with generic VGA driver you cannot have 100Hz frame rate on high
resolutions.

------
sevensor
In DOS, in real mode, the framebuffer was just mapped directly into memory. If
you wanted to put something on the screen, you wrote to that memory address
(often segment A000). For text modes, you would write ASCII characters
straight into the buffer. For bitmap modes, your bytes would be interpreted as
colors (or shades of gray, depending on the mode.) It was very exciting when I
figured out how to use extended memory to draw high-resolution (640x480)
graphics.

------
yoz-y
Brings back memories. When I started coding graphical applications, writing
directly to the graphic card's memory was the only way I understood. As I
didn't know any better I had to recode stuff like line, circle and sprite
drawing on my own. It was super slow but a very fun way to get into coding.

Maybe it's just me but I have the impression that drawing arbitrary things on
screen has become harder since then.

------
jonny789
I am trying to run as root user :: cat /dev/graphics/fb0 in my android (oreo)
phone. But showing 'No such device' error. Could anyone guide me on how to
make it work so that I could take screenshot directly and do some graphics
stuff on my phone directly.

------
mnemotronic
note: I don't know linux...

Is it possible to get the GPU to copy kernel / system memory to the
framebuffer, then read that back with user space app? I.e. can we convince the
GPU or framebuffer to give us the contents of protected system memory?

~~~
Relys
On the Nintendo Wii U we were able to do this. Check out "GX2 unchecked memory
read/write":
[http://wiiubrew.org/wiki/Wii_U_System_Flaws](http://wiiubrew.org/wiki/Wii_U_System_Flaws).
Same issue with "gspwn" on the Nintendo 3DS:
[https://www.3dbrew.org/wiki/3DS_System_Flaws](https://www.3dbrew.org/wiki/3DS_System_Flaws)

------
mar77i
I have this C project based on CodingTrain videos that also ships an
fbdev_runner: [https://github.com/mar77i/cgbp](https://github.com/mar77i/cgbp)

------
phibz
Given how wayland works and how similar it is to the KMS fbcon abstraction it
might be interesting to discuss that as well.

------
voltagex_
I wonder if there's a way to take over another VT so you don't have the
console text over your images.

~~~
Jasper_
You can do this without taking over another VT by using ioctl(KDSETMODE,
KD_GRAPHICS). This tells fbcon in the kernel to stop drawing console text to
/dev/fb.

