Author Topic: GNU/Linux fb and fbcon rotation  (Read 10957 times)

0 Members and 5 Guests are viewing this topic.

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #25 on: June 27, 2025, 06:38:28 pm »
Have you drawn an RGB565 test image or color bar image yet, to check if the display is OK?

With fbi, yes.

I converted my png image into pnm/P6 (P6 means "rgb888, binary"), and I am using this file.
Code: [Select]
2025-06-13--23-33-21---2025-06-13--23-36-49 - [ media-libs/netpbm ] - success - [email protected]/13
(pngtopnm image.png image.pnm)

The original image is black/white, there are no other colors.
I think I will use a full scale color image.



But there is an other problem now.
I moved the code to an IBM ThinkPad T23, running GNU/linux on a Savage S3 video card.

And ....
Code: [Select]
# hinv
...
fb0: 800x600,8
...

8bit color mode only, wtf!?!  :-//

Plus
Code: [Select]
    xres           = p_vinfo->xres; /* virtual */
    yres           = p_vinfo->yres; /* virtual */

yres_virtual is 600, but xres_virtual is 4096, wtf!?!?

Code: [Select]
# fbset

mode "800x600-60"
    # D: 40.000 MHz, H: 37.879 kHz, V: 60.317 Hz
    geometry 800 600 800 4096 8
    timings 25000 88 40 23 1 128 4
    hsync high
    vsync high
    accel true
    rgba 8/0,8/0,8/0,0/0
endmode

so i have to add some more code to handle this color mode too
  • 8bit
  • 16bit
  • 18bit <---- found used in a PDA
  • 24bit
  • 32bit ?!?

I don't want to use SDL or other stuff, so writing a "bare metal" frambuffer library with primitives { pixel, line, rect } that is universally usable on all GNU/linux SBCs seems to be much more complicated than expected.
« Last Edit: June 27, 2025, 10:41:40 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #26 on: June 27, 2025, 08:53:11 pm »
yres_virtual is 600, but xres_virtual is 4096, wtf!?!?

looking at the kernel source, it seems - by default - the framebuffer driver may have set an oversized yres_virtual to "support VT scrolling" via the "panning" interface.

makes sense, but umm :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #27 on: June 27, 2025, 09:14:23 pm »
I moved the code to an IBM ThinkPad T23, running GNU/linux on a Savage S3 video card.
The 800x600,8 mode is what the savagefb driver reports for LCD panels when probing (i.e. "by default").  You can use VESA CVT reduced timings to set different video modes, and the savagefb.mode_option kernel command line parameter to set the video mode using kernel modedb syntax.

AFAIK, T23 has a LCD panel with native resolution of either 1024×768 or 1400×1050.  The corresponding LCD panel (CVT reduced) modelines are 1024x768MR-BPP@60 and 1400x1050MR-BPP@60, where BPP is bits per pixel, i.e. 16, 24, or 32.

Therefore, I'd reboot the machine with Linux boot command line savagefb.mode_option=1024x768MR-16@60 or savagefb.mode_option=1400x1050MR-16@60 before anything else.

yres_virtual is 600, but xres_virtual is 4096, wtf!?!?
AFAIK, T23 has an S3 SuperSavage IX/C graphics "card" with 16 MB of dedicated frame buffer memory.
xres_virtual just means that in this particular mode (800x600-8) each scanline is 4096 bytes long.
Usually it is the yres_virtual that is extended to fill the entire framebuffer, though.

The 2D accelerator in Savage is such that xres_virtual and yres_virtual must not exceed 4096 (0x1000).
You can see the details in the drivers/video/fbdev/savage/savagefb_driver.c:savagefb_probe() function.

Put simply, to boot Linux using optimal LCD framebuffer mode, you do need to use the savagefb.mode_option= kernel commandline option.

I don't want to use SDL or other stuff, so writing a "bare metal" frambuffer library with primitives { pixel, line, rect } that is universally usable on all GNU/linux SBCs seems to be much more complicated than expected.
I only support
    fb_fix_screeninfo.type == FB_TYPE_PACKED_PIXELS &&
       (fb_fix_screeninfo.visual == FB_VISUAL_TRUECOLOR ||
        fb_fix_screeninfo.visual == FB_VISUAL_DIRECTCOLOR) &&
       (fb_var_screeninfo.bits_per_pixel == 8 ||
        fb_var_screeninfo.bits_per_pixel == 16 ||
        fb_var_screeninfo.bits_per_pixel == 32)
and if I ever encounter one,
    fb_fix_screeninfo.type == FB_TYPE_FOURCC && fb_fix_screeninfo.visual == FB_VISUAL_FOURCC
with fb_var_screeninfo.grayscale having one of the 8-bit, 16-bit, or 32-bit V4L2_PIX_FMT_[ABGRX]*[0-9]*X? values defined in <linux/videodev2.h>, since they map to compatible modes with component positions and sizes depending on the fourcc code.

That means I only need three variants:
Code: [Select]
// unsigned char *fb_origin;
// int32_t fb_xstride, fb_ystride, fb_xsize, fb_ysize;

// The following functions assume (x >= 0 && y >= 0 && x < fb_xsize && y < fb_ysize)

static void set_pixel_none(const int32_t x, const int32_t y, const uint32_t c) {
    // Nothing
}
static void set_pixel_8bpp(const int32_t x, const int32_t y, const uint32_t c) {
    *(fb_origin + x*fb_xstride + y*fb_ystride) = c;
}
static void set_pixel_16bpp(const int32_t x, const int32_t y, const uint32_t c) {
    *(uint16_t *)(fb_origin + x*fb_xstride + y*fb_ystride) = c;
}
static void set_pixel_32bpp(const int32_t x, const int32_t y, const uint32_t c) {
    *(uint32_t *)(fb_origin + x*fb_xstride + y*fb_ystride) = c;
}

// Use the function pointer to avoid switch statement.
static void (*set_pixel)(int32_t, int32_t, uint32_t) = set_pixel_none;
For filled rectangles and blitting, I do implement three different variants, depending on the target bits per pixel.
For lines, curves, arcs I use the set_pixel function pointer.

In 2D, there are 8 possible axis-aligned orientations including mirroring through either or both axes, and they can be reached if you use one bit for X-Y transpose, one bit for mirroring in X, and one bit for mirroring in Y, applied in that order (for example).  You only need 8×3 = 24 bit lookup table to find which is which rotated by 90 degrees clockwise, and another for counterclockwise, and another for the inverse rotation.  This means that a blitting function that supports blitting some source pixmap to the framebuffer in any orientation, can optimize the draw order to be consecutive in framebuffer, but "random" order in pixmap.  If the framebuffer is larger than the pixmap, this yields better cache locality, and can speed up blits a bit.

For me, the most important blitting routine is one that expands N-bit data to full color on framebuffer.  The blitting routine gets the reference corner coordinates on framebuffer, the drawing orientation (0..7), the origin of the pixmap, the stride and size of the pixmap, the data shift and N, and the (1<<N)-entry color table (in uint32_t format).
The drawing orientation is applied to the pixmap origin and strides.  Then, the framebuffer strides are compared to the pixmap strides, and the framebuffer strides and reference corner adjusted so that blitting is consecutive in framebuffer access.  Finally, the blitted rectangle is compared to valid coordinates, and only the visible portion is blitted.  For each pixmap byte (or uint32_t), it is first shifted right by the data shift amount, then ANDed with (1<<N)-1.

While that means that bits 0..3 of the pixmap bytes hold one pixmap, and the higher bits some other pixmap or pixmaps, this minimizes the per-pixel work and allows very fast blitting.  For anti-aliased fonts, the first color table entry is the background, the last is the foreground, and the rest of the entries blend between the two.
Interpolating the middle colors in L*a*b or HSL color space often yields visually better results than interpolating RGB values, unless one of the end colors is black or white.
« Last Edit: June 27, 2025, 09:16:31 pm by Nominal Animal »
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #28 on: June 28, 2025, 09:46:54 am »
can't you change the bpp mode at runtime?

I tried this method
Code: [Select]
...
    is_ok = False;

    if (is_ok isEqualTo False)
    {
        is_ok = fb_mode_try_32bit(p_myscreen);
    }
    if (is_ok isEqualTo False)
    {
        is_ok = fb_mode_try_16bit(p_myscreen);
    }


Code: [Select]
private boolean_t fb_mode_try_32bit
(
    p_myscreen_t p_myscreen
)
{
    boolean_t             ans;
    p_fb_var_screeninfo_t p_vinfo;
    uint32_t              fbfd;
    sint32_t              res;
    boolean_t             is_ok0;
    boolean_t             is_ok1;
    boolean_t             is_ok;

    p_vinfo = p_myscreen->p_vinfo;
    fbfd    = p_myscreen->fbfd;

    /*
     * try setting an { 0,8,8,8 } pixel format
     */
    p_vinfo->bits_per_pixel = 32;
    p_vinfo->red.offset     = 0;
    p_vinfo->red.length     = 8;
    p_vinfo->green.offset   = 8;
    p_vinfo->green.length   = 8;
    p_vinfo->blue.offset    = 16;
    p_vinfo->blue.length    = 8;
    p_vinfo->transp.offset  = 0;
    p_vinfo->transp.length  = 0;

    res    = (ioctl(fbfd, FBIOPUT_VSCREENINFO, p_vinfo));
    is_ok0 = (res isEqualTo 0);
    is_ok1 = (p_vinfo->bits_per_pixel isEqualTo 32);
    is_ok  = (is_ok0 logicalAnd is_ok1);
    if (is_ok isEqualTo True)
    {
        p_myscreen->width  = p_vinfo->xres;
        p_myscreen->height = p_vinfo->yres;
        p_myscreen->depth  = p_vinfo->bits_per_pixel;
    }
    dbg_print_boolean_test(is_dbg, is_ok, "Switching to 32bpp mode ...", "\n");

    ans = is_ok;
    return ans;
}

It seems working  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #29 on: June 28, 2025, 09:52:18 am »
if it's correct, the problem is: how to "probe" all the supported (by kernel and hw) bpp-modes?

guinea pigs (humor for "testhing machines"):
- mac-mini/ppc-g4, radeonfb
- Thinkpad-T23, savagefb
- PDA, PXA270-fb
...
- others?
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #30 on: June 28, 2025, 12:37:06 pm »
can't you change the bpp mode at runtime?
Of course you can.  All devices I have that support VGA, HDMI, or DisplayPort output do support at least 16 and 32 bits per pixel (RGB565 and RGB888), and various output sizes/resolutions, usually configurable using VESA VCT timings (standard for CRTs, reduced for LCD panels).

The order of the color components may vary, but that only matters when you are encoding specific colors.  (For format conversion blitting, note that RGB565→RGB888 and BGR565→BGR888 do the exact same mapping.  I do recommend having different functions for each mode tuple for rectangle conversion blitting, which also considers the rotations of the source and destination so that the larger pixel format is scanned in native order, for maximum cache locality; ignoring cacheline size considerations because the source and target are rarely perfectly cacheline aligned anyway.)

Bits per pixel is only fixed for very limited devices like auxdisplays (in drivers/auxdisplay/) which tend to have all display properties fixed.  The graphics ones like old cfag12864b do provide a (very limited) framebuffer interface.  (Nowadays you tend to see custom auxdisplay drivers very rarely and only in kernel forks ("Linux SDKs"), because current Linux SoCs tend to have built-in graphics cores with support similar to VGA/HDMI/DisplayPort outputting ones.)

The reason for me to support both 16bpp and 32bpp is that many video devices use main RAM for the framebuffer, and at any given resolution, 16bpp needs half the RAM 32bpp does.  Although some video devices have their own framebuffer RAM which cannot be easily used for other purposes, memory bandwidth on older devices is limited, and 16bpp can be significantly faster than 32bpp.  Of course, 32bpp yields much better color reproduction and thus more pleasing visuals.

To simplify, on smaller devices (say up to 7") I prefer 16bpp, and on larger ones, especially full-size displays, 32bpp.  As an example, 800×480-16 = 768,000 bytes, but 800×480-32 = 1,536,000 bytes.  If you only have 64M of RAM (sufficient to run minimal userspace with latest Linux kernels; it is the current minimum for e.g. OpenWRT), that is a significant difference.
« Last Edit: June 28, 2025, 12:40:38 pm by Nominal Animal »
 
The following users thanked this post: DiTBho

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #31 on: June 28, 2025, 12:50:39 pm »
I tried this method
I do recommend reading back the fb_fix_screeninfo and fb_var_screeninfo structures (using FBIOGET_FSCREENINFO and FBIOGET_VSCREENINFO ioctls, respectively), after a successful FBIOPUT_VSCREENINFO ioctl, and verifying the settings are compatible –– not that they are identical to what you requested, just that they are something you can support.

The reason is precisely the same when using termios and tcsetattr(): the functions return success even if the new settings were only partially applied.  (What it means for framebuffer devices, varies based on the framebuffer driver.)  Things like fb_fix_screeninfo.line_length tends to require some hardware-specific alignment (usually a power of two, but the power varies!) –– it is set based on the fb_var_screeninfo.xres_virtual even if you intend to do no panning at all, so to get a desirable line_length you use the largest xres_virtual that does not exceed the desired line_length; the position of the red/green/blue components might differ slightly, and so on.  Instead of the ioctl returning failure for every small detail, the drivers silently adjust minor details to the nearest supportable equivalent.
« Last Edit: June 28, 2025, 12:53:15 pm by Nominal Animal »
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #32 on: June 30, 2025, 04:13:55 pm »
Code: [Select]
/*
 * map fb to user mem
 *
 * void* mmap
 * (
 *     void* addr,
 *     size_t length,
 *     int prot,
 *     int flags,
 *     int fd,
 *     off_t offset
 * );
 */

Code: [Select]
    fbfd    = p_myscreen->fbfd;
    p_finfo = p_myscreen->p_finfo;

    prot = (PROT_READ | PROT_WRITE);
    len  = p_finfo->smem_len; /* fb.stride * fb.height ?!? */
    fbp  = mmap(NULL, len, prot, MAP_SHARED, fbfd, 0);

    /*
     * On success, mmap() returns a pointer to the mapped area.
     * On error, the value MAP_FAILED (that is, p_err) is returned,
     * and errno is set to indicate the error.
     */
    is_ok = (fbp isNotEqualTo p_err);
    if (is_ok isEqualTo False)
    {
        fbp = NULL; /* myC needs NULL on Error */
    }

    p_myscreen->fbp = fbp;


So, I open the "/dev/fb0" framebuffer (savagefb), try to set the color to 32 bits and then "mmap" it.

MMap is a bit strange for me, when it fails it doesn't return NULL but (void *) -1, which in the case of "myC" cannot be expressed directly (casting is forbidden by the language), so you have to define p_err.

Annoying, but it' not a problem, the code works ...
... except that... when the bootloader loads the kernel, before entering it, it "maps" the framebuffer and something strange happens.

The "logo" on the framebuffer disappears and the whole screen is replaced by an empty text console  :o :o :o

It's empty, because it hasn't been associated with any virtual terminal.

Why doesn't the framebuffer keep what the graphics mode draws on it?  :-// :-// :-//

Is this a way to preserve the logo during kernel boot?
I mean, without "embedding" the logo into the kernel.


p.s.
Code: [Select]
    len  = p_finfo->smem_len; /* fb.stride * fb.height ?!? */
This is a doubt that I haven't yet clarified, about which of the two is better.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #33 on: June 30, 2025, 05:25:36 pm »
  • MAP_SHARED -> changes will be written back to the underlying file
  • MAP_PRIVATE -> you read the file into a private buffer, and other processes can still mmap the file, they just see it unmodified
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #34 on: June 30, 2025, 07:13:35 pm »
    fbp  = mmap(NULL, len, prot, MAP_SHARED, fbfd, 0);
As I mentioned, I recommend using mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE, fbfd, 0);.  The MAP_NORESERVE means the framebuffer is never swapped to disk.  I use the same flags when I access existing files, too.

In practice, it only matters if you get high memory pressure, and things start swapping.

The "logo" on the framebuffer disappears and the whole screen is replaced by an empty text console  :o :o :o
Yeah.  This is annoying.  I wish there was a kernel command-line option to disable the clearing.  It is trivial to add to most framebuffer drivers, though.

See e.g. 6.15.4/drivers/video/fbdev/savage/savagefb_driver.c:savage_map_video(), and the unconditional memset_io() at the end of that function.  This is what clears the display.  It is called from the savagefb_driver.c:savage_probe(), which itself is called when the PCI device is detected (see savagefb_driver.c:struct pci_driver savagefb_driver).

All other framebuffer drivers end up doing something equivalent in their _probe() function, because traditionally the framebuffer was not cleared by BIOS and was full of semi-random garbage, often leftovers from initial BIOS text mode.

    len  = p_finfo->smem_len;
For true color and direct color, and even pseudocolor (indexed/paletted) modes I've seen, fb_fix_screeninfo.line_length == fb_var_screeninfo.bits_per_pixel*fb_var_screeninfo.xres_virtualfb_fix_screeninfo.smem_len >= fb_var_screeninfo.bits_per_pixel*fb_var_screeninfo.xres_virtual*fb_var_screeninfo.yres_virtual, alwayssmem_len is often larger on devices that have more dedicated RAM than can be used by the accelerator in the current graphics mode, and is the maximum amount of memory you can safely mmap on the device.

Note that per Linux kernel Frame Buffer Library, each time you use FBIOPUT_VSCREENINFO successfully, fb_fix_screeninfo values will be reset too.  If you only use FBIOGET_VSCREENINFO afterwards to check if the new settings are acceptable, use only fb_var_screeninfo.

But, if you also use FBIOGET_FSCREENINFO, then use fb_fix_screeninfo.line_length for fb_ystride.  If you want to store pre-prepared pixmaps, you can map all of fb_fix_screeninfo.smem_len, and use everything not within the visible rectangle for offscreen buffers/caches/pixmaps.
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #35 on: July 01, 2025, 11:36:41 pm »
So, I added agetty to /dev/tty1 and the screen shows login and then /bin/bash correctly.

Then, remotely, via ssh, I run my bootloader, which opens /dev/fb0, mmaps and displays the logo.

Erm, the bootloader has a built-in shell, where you can issue commands and also type "exit" to end the bootloader, and this invokes fb_done, which in turn calls all the "done" methods.

So, when it ends, it "un-mmap" and "fclose" /dev/fb0.

And guess what? Before the bootloader is forced to exit, the screen displays the logo, but when it exits, it goes back to the text console, displaying exactly the same things as before the boot.

And here I really don't understand, it seems that there are two graphics memories, one for the text console, which is saved when I invoke mmap, and one that uses mmap.

Framebuffer memory should be just *one* memory, so if you do graphics on it, and then switch back to the text console, you should still have the graphics on the screen  :-// :-// :-//

In fact, you should clear the screen. Which is exactly what I do NOT want to do.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #36 on: July 01, 2025, 11:38:41 pm »
Code: [Select]
agetty -h -t 60 tty1 9600 vt100
(nothing special)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #37 on: July 02, 2025, 02:30:58 pm »
And here I really don't understand, it seems that there are two graphics memories, one for the text console, which is saved when I invoke mmap, and one that uses mmap.
The contents of the Linux console terminal (text and attributes, not graphics data) are saved in kernel memory, and accessible via /dev/vcsN (text only) and /dev/vcsaN (text and attributes).  This is what allows you to change the active terminal via keys or chvt, too.

There are several possible options, depending on the exact behaviour you want.

The best option to detach your application from the controlling terminal, open another tty (one not used by getty/mingetty/agetty etc.) as the new controlling terminal, and use the VT_ACTIVATE and VT_WAITACTIVE ioctls to switch to that console; see kbd/src/chvt.c (and kbd/src/libcommon/getfd.c) for details on how to do that.

(You can also tell fbcon which console terminals are mapped to which framebuffer, if you have more than one framebuffer device, using Linux kernel command line options.  See Linux fbcon documentation for details.)

In general, combining getty/mingetty/agetty with framebuffer application in the same console terminal with vgacon (CONFIG_VGA_CONSOLE) is complex, because vgacon will switch back to text mode.  AFAIK, CONFIG_FRAMEBUFFER_CONSOLE does not change the mode, but getty/agetty/mingetty will clear the screen whenever it gets in control.  The best option is to switch to a non-getty console.

Framebuffer memory should be just *one* memory, so if you do graphics on it, and then switch back to the text console, you should still have the graphics on the screen 
Well, it does not work that way in Linux, because of multiple console support (chvt or AltGr+F1..F12).
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #38 on: July 02, 2025, 04:41:32 pm »
And ... if I removed "fbcon" entirely? The bootloader doesn't need it, since it operates (the console is) on the serial.
fbcon seems only causing problems.

Umm, the second question is: I don't know the beavior of the kernel launched by exec().
What will it do on the framebuffer? Will it immediately (as soon as video drivers is initialized) clear the screen for the earlyboot console?

The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #39 on: July 02, 2025, 11:07:20 pm »
Well, it does not work that way in Linux, because of multiple console support (chvt or AltGr+F1..F12).

yup. In my case, for a diffeent project, the video card I an using for XINU/mips is a vhdl project made on the top of the "PCI MESA fpga card".
It's one of those that have a physical PLX chip to manage the PCI transactions. Very old tecnology, modern ones come with Spartan6, and the PCI is completely managed by the fpga, which may sound cool but it adds a lot of complexity and vhdl code, and I don't like it.

Anyway, I don't have more than 2Mbyte of SDRAM, dual port, on the card, and only 8Mbyte of ram on the SBC.
Xinu eats 2Mbyte, including the filesystem and the network stack. Not so bad, but I only have 6Mbyte free for the applications.
So I am using the video ram in a weird way.

If the user application is in "graph mode", the whole video ram is managed as rgb555 framebuffer.
If the user application is in "text mode", the video ram is split into chunks, addressing each pair of chunks as "text area and attribute area" for each terminal.

chunk0 and chunk1 --> /dev/tty1
chunk2 and chunk3 --> /dev/tty2
....

simpler design  :o :o :o

is rgb555 (15bpp) supported?!?
it seems 18bpps is addressed as 24bpps, just with 6bit per color instead of 8.

And ummm, I see the linux kenrel also mentions 1bit color? is it really supported? any hw example of this?
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #40 on: July 02, 2025, 11:13:15 pm »
What if I have or want to use a custom graphics card that can handle a 16-shade gray display(1)?

What do you do with Linux? 8-bit color seems to be synonymous with "pseudo color"  :-// :-// :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #41 on: July 03, 2025, 04:40:27 am »
is rgb555 (15bpp) supported?!?
Some do.

Others can support it via FB_VISUAL_DIRECTCOLOR, if one modifies the green mapping so that all even and odd entries have the same intensity; the lower one for the lower half entries, and the higher one for the upper half entries, and treat it as RGB565, but increment the green offset and decrement its length.

If you just increment the green offset and decrement its length for RGB565, you'll get a very slight magenta tint, because then "white" is #FFFBFF (31,62,31) instead of #FFFFFF (31,63,31).  In FB_VISUAL_DIRECTCOLOR, you have three ramps, one for each color component, usually used for gamma correction.  But also works for RGB555 support.

And ummm, I see the linux kenrel also mentions 1bit color? is it really supported? any hw example of this?
Yes, Hercules graphics (old!) and cfag12864 auxdisplay for example, probably many others.  I don't know how many users/testers these have, so bit rot is a risk.  In theory, it should work just fine.

What if I have or want to use a custom graphics card that can handle a 16-shade gray display(1)?
You use FB_VISUAL_STATIC_PSEUDOCOLOR (or FB_VISUAL_PSEUDOCOLOR), with all three components having offset 0 and length 4.  With FB_TYPE_PACKED_PIXELS, low nibbles are even pixels, and high nibbles odd pixels.

Several framebuffer drivers support 4-bit (16-color) pseudocolor modes.
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #42 on: July 03, 2025, 05:34:43 pm »
Look at this picture!
It's an old Apple laptop, G3 serie (early 2000s), running GNU/Linux Gentoo.

The kernel is 2.6.26, nothing special, and you see a text terminal, fbcon, running "/usr/bin/top".
But look at the background! There is a persistent graphical image as "background".

How is it possible?
How to achieve so?

 :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #43 on: July 03, 2025, 06:54:58 pm »
It's an old Apple laptop, G3 serie (early 2000s), running GNU/Linux Gentoo.

The kernel is 2.6.26, nothing special, and you see a text terminal, fbcon, running "/usr/bin/top".
But look at the background! There is a persistent graphical image as "background".
Which framebuffer driver?  Is that actually fbterm, and not getty over fbcon?  Or one of similar framebuffer virtual terminals?  There are a few.

To simplify a bit, getty on fbcon ≃ fbterm.  You don't necessarily need to have fbcon to use fbterm, since one is not forced to run any getty's at all.  (That is, you can replace getty with fbterm, and that only requires a framebuffer, not fbcon per se.)

I checked linux-2.6.26/drivers/video/console/fbcon.c, and while fbcon can display the logo (usually Tux), even centered on-screen, I'm not sure if it keeps it on the background.  I do know that fbterm can do that.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #44 on: July 03, 2025, 09:07:54 pm »
Is that actually fbterm, and not getty over fbcon?

It's really getty over fbcon.

I don't know what the trick is, but Yaboot includes an initrd file along with the kernel.

What's in the initrd? I don't know, I haven't looked into it yet  :-//

I found the kernel source code on the harddrive, the time stamp is about 2009, anyway it looks like Vanilla, nothing special with the ATIRage128 framebuffer kernel driver, fbcon or similar.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #45 on: July 03, 2025, 09:18:59 pm »
I'm not sure if it keeps it on the background

I don't even understand how this is possible, the memory used for text terminals is separate from the memory used for graphics, so technically how does agetty on fbcon maintain a graphical background?

I noticed something interesting today. If in a agetty fbcon I run my bootloader without cleaning the mmap memory during fb_init(), and without chaning the video mode (which probably internally invokes a clean method), I can draw something graphical in a corner, and it goes over the text.

How is it possible?


I do know that fbterm can do that.

There is no trace of "fbterm" on the hard disk :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #46 on: July 03, 2025, 10:00:51 pm »
Ummm, I think it was fb-splash userspace helpers and tools, using "Spoke's" fb-condecor kernel patches.

Looks like a dead project, cannot find the old Spoke's blog anywhere, neither patches for kernel 2.6.

It doesn't actually change the fbcon source, it adds other kernel modules.
Anyway, I don't really understand how it works.

It looks complex  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: GNU/Linux fb and fbcon rotation
« Reply #47 on: July 03, 2025, 11:34:41 pm »
(While I was writing this, I was reminded of your screen blanking issues on the terminal console.  Do check man 4 console_codes and specifically printf '\033[9;Xm\033[14;Xm', especially with X set to zero.)

It doesn't actually change the fbcon source, it adds other kernel modules.
Oh, it does; it adds the decor hooks to drivers/video/fbdev/core/fbcon.c.

Anyway, I don't really understand how it works.
fbcon is a kernel-side blitter, which renders the console terminal contents to the framebuffer.  You can use kernel command line parameters to map specific consoles to specific framebuffer devices.

fbterm is an old user-space framebuffer virtual terminal, that does the same thing in userspace.

fbcon does support display rotation, by blitting the characters rotated to the framebuffer.  By default, it does not keep any kind of a background image, it just blits text with attributes to the framebuffer, and moves data around when scrolling, just like the Linux console terminal does.  It is much more efficient if CONFIG_FB_TILEBLITTING is set.  It uses hardware panning and wrapping if available, falling back to hardware 2D blitting, and to software blitting if nothing else is available, so it should always be set.

If you use getty for your terminal, then standard input, output, and error are directed to the /dev/ttyN.  The kernel interprets the standard escape sequences, and keeps the terminal contents in /dev/vcsN (text only), /dev/vcsuN (Unicode glyphs), and /dev/vcsaN (text and attributes).  Kernel console drivers like fbcon use a include/linux/console.h:struct consw to register a set of callbacks that the kernel terminal console uses to render them to any other backing.

In userspace, fbterm and others can work in two different ways.  One is to provide a virtual terminal (pseudoterminal pair), interpreting the escape sequences (listed in man 4 console_codes), and keeping the virtual terminal contents in its own buffers, rendering them however one wants.  When used instead/as a getty, they read input from the terminal (because that's where they get the keyboard input), but might not use the terminal console for output at all.

The other is to use the terminal console, but scan /dev/vcsuN (and optionally /dev/vcsaN) for changes, and updating any changes to the actual output device.  The latter is used by screen readers and tools that mirror the terminal console contents to a separate device even when it is not active/foreground.  (For example, you can do an X/Wayland application that displays their contents as a read-only window.  It will need elevated privileges to access the /dev/vcsaN and /dev/vcsuN, however.

If one wanted to layer text and framebuffer contents to the actual display device, one option would be to create an fbcon derivative that also provides a synthetic framebuffer device (see auxdisplay framebuffer drivers for simple implementations), using say 16-bit ZRGB1555 format, with Z=0 shown beneath the text, and Z=1 above the text.  While the console terminal does have support for 24-bit RGB color (just try it: printf '\033[38;2;255;204;153mThis is #FFCC99.\033[0m\n'), it does not have an escape code to define RGBA, so the only way to define the opacities of the 16 standard colors is to use the FBIOPUTCMAP/FBIOGETCMAP ioctl on the framebuffer device, which is a bit oddish.
Then, the derivative kernel module would composite the currently active console terminal (if any) with the synthetic framebuffer data, to the actual framebuffer device.

The downside is the extra memory use, and the slowness.  A 1024×768 ZRGB1555 takes 1.5MBytes, and compositing the display contents with say a 8×12 fixed font (128×64 text window) takes its own lookup tables to do efficiently.  Some hardware can do something similar by themselves, of course.

If you have read this far, you'll now have a good idea why one of my hobby projects is a small IPS display panel "controller" that internally composites 3-4 such framebuffer layers; one full-color background one, and 3-4 indexed color (pseudocolor, 4-bit or 8-bit pixels, a 256-entry ARGB palette per layer).  It just opens up so many new shenanigans.  Well, old ones, because that what was made arcade and early home game consoles so visually powerful when processors and microprocessors just didn't have the grunt we have available today.  Doing it in software is somewhat taxing, so shortcuts and optimizations are quite important for performance.  I haven't tried implementing it as a pixel shader for OpenGL ES or similar, but I do believe it would be possible; on any Linux SBC with Mali or other supported OpenGL ES implementation the GPU hardware would do it once per display update (60 - 70 times per second).
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #48 on: July 04, 2025, 08:04:34 am »
I was a bit confused by what i found on the harddrive: /user/src/kernel/kernel-2.6.26 looks like a fresh vanilla
Probably genkernel or something else was used, which copied those sources to a temporary directory where patches were then applied

however, "lspatch" leaves no doubt, here are the files that are modified by one of the most recent patches
Code: [Select]
# lspatch fbcondecor-5.10.patch
linux-5.10/Documentation/fb/fbcondecor.txt
linux-5.10/drivers/Makefile
linux-5.10/drivers/video/console/Kconfig
linux-5.10/drivers/video/console/Makefile
linux-5.10/drivers/video/console/cfbcondecor.c
linux-5.10/drivers/video/console/fbcondecor.c
linux-5.10/drivers/video/console/fbcondecor.h
linux-5.10/drivers/video/fbdev/Kconfig
linux-5.10/drivers/video/fbdev/core/bitblit.c
linux-5.10/drivers/video/fbdev/core/fbcmap.c
linux-5.10/drivers/video/fbdev/core/fbcon.c
linux-5.10/drivers/video/fbdev/core/fbmem.c
linux-5.10/include/linux/console_decor.h
linux-5.10/include/linux/console_struct.h
linux-5.10/include/linux/fb.h
linux-5.10/include/uapi/linux/fb.h
linux-5.10/kernel/sysctl.c
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: GNU/Linux fb and fbcon rotation
« Reply #49 on: July 04, 2025, 08:45:00 am »
(that is, to understand, the laptop in the photo is mine
Many years ago, I lent it to a CCC event,
and it was returned to me all modified and hacked
I haven't used it for about 10 years)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: Nominal Animal


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf