1. Background
  2. Using wsfb
    1. Step 1: Configuring Xorg
    2. Step 2: Setting a better display mode.
  3. Limitations
  4. Extra: How to disable built-in DRM driver using kernel's userconf manager
  5. Minimal wsfb(4) config fragment /etc/X11/xorg.conf.d/wsfb.conf
  6. Minimal wsfb(4) /etc/X11/xorg.conf

Background

wsfb(4) is the Xorg graphics driver for the NetBSD wsdisplay(4) framebuffer device. wsdisplay(4), similar to Linux's /dev/fb devices, provide access to non-accelerated framebuffers, which are provided by almost all modern cards. Most, if not all, modern graphics cards provide what's called a linear framebuffer: a chunk of memory where contiguous address locations map onto adjacent (X, Y) pixels. For example, assuming a 32 bits-per-pixel colour depth display, memory location fbmem + 0 will hold the pixel at position (0,0); fbmem + 4 corresponds to the pixel at (1, 0), and so on. (We'll skip the complication known as stride or line_length here.)

wsdisplay(4) can run on top of:

  1. genfb(4), the Generic PCI VGA framebuffer device (provided by UEFI or BIOS on x86), and other simple software framebuffers provided by hardware or firmware (e.g. simplefb on ARM)
  2. the accelerated drm(4) graphics devices (in /dev/dri/card?--which wsfb will use as a plain framebuffer).

Using wsfb

Step 1: Configuring Xorg

Use this wsfb.conf Xorg config fragment:

Section "Device"
    Identifier  "Card0"
    Driver      "wsfb"
EndSection

That is all that is needed. Xorg will autoconfigure everything else. Make sure you dump the wsfb.conf file into the correct Xorg config. directory. /etc/X11/xorg.conf.d/ is the correct location for the Xorg in base. If you've installed the modular-xorg package, then the path will need change. Use this command to find your config directory:

$ fgrep directory /var/log/Xorg.0.log
[    72.697] (==) Using config directory: "/usr/local/etc/X11/xorg.conf.d"
[    72.697] (==) Using system config directory "/usr/local/share/X11/xorg.conf.d"

If your DRM kernel driver has loaded OK and is active, then it will have configured your graphics card with the best resolution for your screen and you can just run X right away (this wil be X with wsfb on drmkms, minus the DRM-provided accelerations). You don't need Step 2.

If you don't have a DRM driver, or if you can't load it, then if you start X now, you'll most probably get the bog-standard 1024x768x32 screen resolution provided by genfb, which might be OK, but, is not ideal. As the wsfb/wsdisplay/genfb combo. doesn't let you change resolutions on the fly (xrandr, for instance, doesn't work), we'll have to set a better resolution elsewhere: in the bootloader.

Step 2: Setting a better display mode.

Reboot, then at the bootloader menu, choose the option to get to the bootloader prompt. Here, on UEFI systems, we use the gop (Graphics Output Protocol) command like this:

List available video modes first:

> gop list
 0: 1366x768 BGRR pitch 1376 bpp 32
 1: 640x480 BGRR pitch 640 bpp 32
*2: 800x600 BGRR pitch 800 bpp 32
 3: 1024x768 BGRR pitch 1024 bpp 32
>

The * indicates the (safe) mode that the bootloader will use by default. Note that on my laptop, mode 0 has a pitch (aka stride) of 1376 pixels. This means that on my graphics card (Asus X202E laptop), the framebuffer is linear, but, not fully contiguous. The 10 unusable pixels at the end of each row have to taken into account, or else, you'll be treated to a characteristic jagged, streaky display.

Choose the best mode, which is generally mode 0:

> gop 0
>

The screen resolution will switch immediately. (And hopefully, your display won't go blank, which, these days, usually indicates a graphics card/BIOS/UEFI/whatever that doesn't implement the published standards correctly.)

If you have/use BIOS instead of UEFI, you can try the vesa command instead of gop:

> vesa list
...
> vesa 0xhhh
>

If the mode you've chosen works, then you can add that gop 0 or vesa mode command to boot.cfg so that it is activated automatically.

This is what dmesg will show, if you've disabled DRM (see below), or don't have it:

$ dmesg | fgrep genfb
[     1.015430] genfb0 at pci0 dev 2 function 0: vendor 8086 product 0166 (rev. 0x09)
[     1.015430] genfb0: framebuffer at 0xe0000000, size 1366x768, depth 32, stride 5504
[     1.015430] genfb0: shadow framebuffer enabled, size 4128 KB
[     1.015430] wsdisplay0 at genfb0 kbdmux 1: console (default, vt100 emulation), using wskbd0
[     1.015430] drm at genfb0 not configured

The resolution, depth and stride are all OK. And inside the Xorg server:

$ xdpyinfo | fgrep -B1 -A1 resolution
  dimensions:    1366x768 pixels (310x174 millimeters)
  resolution:    112x112 dots per inch
  depths (7):    24, 1, 4, 8, 15, 16, 32
$ xrandr
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 1366 x 768, current 1366 x 768, maximum 1366 x 768
default connected 1366x768+0+0 0mm x 0mm
   1366x768       0.00* 
$

Limitations

  1. No OpenGL hardware acceleration - on x86 and aarch64, llvmpipe (a parallel CPU-based just-in-time renderer) will be used instead
  2. No X Display Power Management Signaling
  3. No X video extension (used for accelerated video playback)
  4. No DRI

Extra: How to disable built-in DRM driver using kernel's userconf manager

For testing, or if running wsfb on top of the DRM graphics driver does not work--it mostly should, actually).

At the bootloader prompt, pass the -c flag to the kernel:

> boot -c

The kernel will display a few lines, then immediately drop into the userconf prompt:

uc> list                        # list all devs; look for your drmkms entry
uc> disable i915drmkms          # disable Intel DRM
uc> quit

Once you've determined the device name using userconf, or, by trawling through the GENERIC kernel config file, you can disable the device using the bootloader like this:

> userconf disable i915drmkms

You can of course, add userconf commands also to boot.conf

Minimal wsfb(4) config fragment /etc/X11/xorg.conf.d/wsfb.conf

Section "Device"
    Identifier  "Card0"
    Driver      "wsfb"
EndSection

Minimal wsfb(4) /etc/X11/xorg.conf

Created using X -configure, and then changing the graphics device driver (Section "Device") from intel to wsfb

Section "ServerLayout"
    Identifier     "X.org Configured"
    Screen      0  "Screen0" 0 0
    InputDevice    "Mouse0" "CorePointer"
    InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "Files"
    ModulePath   "/usr/X11R7/lib/modules"
    FontPath     "/usr/X11R7/lib/X11/fonts/misc/"
    FontPath     "/usr/X11R7/lib/X11/fonts/TTF/"
    FontPath     "/usr/X11R7/lib/X11/fonts/Type1/"
    FontPath     "/usr/X11R7/lib/X11/fonts/75dpi/"
    FontPath     "/usr/X11R7/lib/X11/fonts/100dpi/"
EndSection

Section "Module"
    Load  "dri"
    Load  "dri2"
    Load  "glx"
    Load  "shadow"
EndSection

Section "InputDevice"
    Identifier  "Keyboard0"
    Driver      "kbd"
EndSection

Section "InputDevice"
    Identifier  "Mouse0"
    Driver      "mouse"
    Option      "Protocol" "wsmouse"
    Option      "Device" "/dev/wsmouse"
    Option      "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
    Identifier   "Monitor0"
    VendorName   "Monitor Vendor"
    ModelName    "Monitor Model"
EndSection

Section "Device"
    Identifier  "Card0"
    Driver      "wsfb"
EndSection

Section "Screen"
    Identifier "Screen0"
    Device     "Card0"
    Monitor    "Monitor0"
    SubSection "Display"
        Viewport   0 0
        Depth     1
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     4
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     8
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     15
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     16
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     24
    EndSubSection
EndSection