Page MenuHomeFreeBSD

loader: implement framebuffer console
ClosedPublic

Authored by tsoome on Nov 30 2020, 1:09 PM.

Details

Summary

Draw console on efi.
Add vbe framebuffer for BIOS loader (vbe off, vbe on, vbe list, vbe set xxx).
autoload font (/boot/fonts) based on resolution and font size.
Add command loadfont (set font by file) and
variable screen.font (set font by size). Pass loaded font to kernel.

Export variables:
screen.height
screen.width
screen.depth
kern.vt.fb.default_mode

Add gfx primitives to draw the screen and put png image on the screen.
Rework menu draw to iterate list of consoles to enamble device specific
output.

Probably something else I forgot...

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

freqlabs added inline comments.
stand/lua/color.lua
59

๐Ÿ‘ ๐Ÿ‘ ๐Ÿ‘

setting hw.vga.textmode should switch gfx fb on or off.

left over screen-width after I did replace - by .
Use screen.depth instead of screen.width.

clean up the hw.vga.textmode
clean up autoload_fonts
provide set of fonts into /boot/fonts

Found a missing word.
I look forward to have this feature, thanks for implementing it.

stand/fonts/INDEX.fonts
16

s/lang empty/lang is empty/

tsoome marked an inline comment as done.

s/lang empty/lang is empty/

For maximum compatibility, I'd strongly suggest that hw.vt.textmode=1 for BIOS implementations (at least for 13) since that's historic behavior and there's no where near enough time to gather additional data. Since we're deployed overwhelmingly to server systems, and server systems tend to be harder to recover from failure than laptop/desktop, I'd hope this goes in like that. Many console redirectors work in text mode, but fail in graphics mode, for example.

The rest of this patch is too long for me to meaningfully review, alas

default BIOS build to create text mode loader; however, this can be
changed by adding into /etc/src.conf:
BOOT_FRAMEBUFFER_MODE=yes

also, even while built default text mode, setting in loader.conf either:

hw.vga.textmode="0"

or

vbe_max_resolution=XxY

Will trigger the console mode to linear framebuffer mode.

Also, even when built with framebuffer mode as default, setting
hw.vga.textmode="1"
will change console to text mode.

Please note: UEFI only does have framebuffer, it does not provide text mode,
therefore there is no way to set text mode for UEFI.

In D27420#613954, @imp wrote:

For maximum compatibility, I'd strongly suggest that hw.vt.textmode=1 for BIOS implementations (at least for 13) since that's historic behavior and there's no where near enough time to gather additional data. Since we're deployed overwhelmingly to server systems, and server systems tend to be harder to recover from failure than laptop/desktop, I'd hope this goes in like that. Many console redirectors work in text mode, but fail in graphics mode, for example.

The rest of this patch is too long for me to meaningfully review, alas

ACK, the default build updated and compile time knob added.

fix 32 to 8-bit indexed color translation in gfx_fb_putimage.

The resulting image is not the prettiest as for now, we only have 16 colors
(and no alpha).

kevans added inline comments.
stand/i386/libi386/vbe.c
715

This one's still going to bite me, unfortunately; I apparently have lots of garbage, because I see a bunch of modes that we skip over then a long series of 0x0 modes following my absolute load of 0x101 entries. This would need to break instead of return or else it will never find my 8-bit modes without help since it always hits the safety while it searches for 32-bit.

fix userboot.
update FB to support 256 colors (CSI 38;5;Xm where x is [0..255])
gfx_fb_putimage should translate to 256 colors in 8-bit mode, use terminal
bg color when alpha=0.

vbe_find_mode_xydm() mode lookup loop was a bit broken.

stand/i386/libi386/vbe.c
927

This one could also use s/100/0x100/, but obviously not critical-

VGA text mode should install 8x16 font.

Notable side effect of setting kern.vt.fb.default_mode: switching from efifb to GPU fb does not increase resolution.
Fun effect with Radeon GPUs: a GOP mode with the wrong aspect ratio will be stretched, but GPU native framebuffer setting the same resolution via kern.vt.fb.default_mode will instead be pillarboxed :)

Big thanks for doing that though: this (in combination with a mainboard upgrade) has caused me to play with efi_max_resolution and gop mode setting and that led me to an interesting discovery about The Radeon EFIFB Conflict Bugโ„ข (namely that it happens for me specifically with GOP mode 0, which is the "closest to native" โ€” 2560x1440 on a 4k screen)


After booting with the font applied by the loader, applying a font with vidcontrol panics with a general protection fault:

[2] --- trap 0x9, rip = 0xffffffff8048f91d, rsp = 0xfffffe0115a76fe0, rbp = 0xfffffe0115a77010 ---
[2] free() at free+0x4d/frame 0xfffffe0115a77010
[2] vt_change_font() at vt_change_font+0x171/frame 0xfffffe0115a77060
[2] vtterm_ioctl() at vtterm_ioctl+0xf30/frame 0xfffffe0115a770b0
[2] termtty_ioctl() at termtty_ioctl+0xc5/frame 0xfffffe0115a77100
[2] tty_ioctl() at tty_ioctl+0x3b/frame 0xfffffe0115a77140
[2] ttydev_ioctl() at ttydev_ioctl+0x26d/frame 0xfffffe0115a77190
[2] devfs_ioctl() at devfs_ioctl+0xc7/frame 0xfffffe0115a771e0

Can the performance be improved? There's a noticeable delay before the screen with the images pops in. (Could that actually be time spent on mounting ZFS?) Somehow rEFInd draws its graphics much much quicker.


From a quick look at the code, the drawing API is tied to the character grid? :/
Would be cool to eventually add a different menu that shows like a minimal single line below the OEM logo (BGRT), and that logo has pixel coordinates.

rewrite gfx backend to use GOP Blt-like function.

This means, for all GFX functions, we assume BGRA format color (4-bytes),
we only do translate data while reading from FB or writing to FB.

Do not set kern.vt.fb.default_mode. This can be confusing for DRM drivers.

UEFI GOP should use Blt() only when there is no access to framebuffer.
Apparently Blt() on Lenovo x220 does not draw, so we should only use Blt()
in case when there is no memory mapped framebuffer.

This revision was not accepted when it landed; it landed in state Needs Review.Jan 2 2021, 8:09 PM
This revision was automatically updated to reflect the committed changes.

This made the only amd64 FreeBSD system that I have access to display a blank
screen in the loader. It is a ThreadRipper 1950X system.

The camera recorded a \ with an underscore under it before the screen turned
completely blank. For the time with \, it did not seem to be changing.

Then there was a blank screen until . . .

The first image after the bank screen as captured by the
camera was the "Welcome to FreeBSD" display with selections 1.
to 5. and options 6. and 7. shown, where it also said:

  Autoboot in 0 seconds, hit [Enter] to boot or any other key [edge of picture]

Loading kernel...
/boot/kernel/kernel text= *** I OMIT DETAILS ON THIS LINE ***
*** I OMIT DETAILS ON THIS LINE ***
Loading configured modules...
/boot/entropy size=0x1000
/etc/hostid size=0x25
/

That last may just be timing of the imaging. (I used fast repeat
instead of video.)

The system is not configured to EFI boot FreeBSD. The FreeBSD boot media
has just:

# gpart show -p /dev/nvd2
=>        40  1875384928    nvd2  GPT  (894G)
          40        1024  nvd2p1  freebsd-boot  (512K)
        1064  1468006400  nvd2p2  freebsd-ufs  (700G)
  1468007464   402653184  nvd2p3  freebsd-swap  (192G)
  1870660648     4724320          - free -  (2.3G)

Adding:

hw.vga.textmode="1"

to /boot/loader.conf made no difference.