Linux simple-framebuffer is not detected by kernel

165 Views Asked by At

I'm trying to get the simple-framebuffer working in Linux, so that I can use a region in System RAM as a framebuffer. I'm running Linux kernel v5.10.7 on a RISC-V system.

So far, I have enabled framebuffer support and the necessary driver in Linux:

CONFIG_FB=y
CONFIG_FB_SIMPLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y 

Add added these lines to the device tree

chosen {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;
    framebuffer {
        compatible = "simple-framebuffer";
        memory-region = <&framebuffer_reserved>;
        width = <640>;
        height = <480>;
        stride = <(640 * 2)>;
        format = "r5g6b5";
    };
};

reserved-memory {

    #address-cells = <2>;
    #size-cells = <2>;
    ranges;
    framebuffer_reserved: framebuffer@A0000000 {
        compatible = "framebuffer";
        reg = <0x0 0xA0000000 0x0 (640 * 480 * 2)>;
        no-map;
    };
};

Neither the reserved memory nor the framebuffer appear in Linux. When doing a

cat /proc/iomem
...
80200000-bfffffff : System RAM
...

even though in theory there should be a split at A0000000 and no /dev/fb0 device exists.

2

There are 2 best solutions below

0
Mr._Potato On BEST ANSWER

I got it working using the following entries in my device tree

chosen {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;
    framebuffer {
        compatible = "simple-framebuffer";
        reg = <0x0 0xA0000000 0x0 (640 * 480 * 2)>;
        width = <640>;
        height = <480>;
        stride = <(640 * 2)>;
        format = "r5g6b5";
    };
};

Turns out, the reserved-memory block was preventing simple-framebuffer from attaching to the memory region. I'm not sure whether this poses any risk to the framebuffer being overwritten, once RAM starts to fill up.

0
Rufwoof On

These are all of the FB settings I have in my Linux kernel v6.6.10 .config. I suspect you may have missed out on setting a FB driver

CONFIG_SYSFB=y
CONFIG_SYSFB_SIMPLEFB=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_FB=y
CONFIG_FB_VESA=y
CONFIG_FB_CORE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB_DEVICE=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_IOMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
CONFIG_FB_MODE_HELPERS=y

When I boot I add vga=ask to the bootloader and select 1920x1080x16 as, in my case, option "w" from the presented VESA listed options, that drops me into a CLI where cat /dev/random >/dev/fb0 fill the screen with random colored dots.

My kernel is specific to using the framebuffer, and with integral initramfs the vmlinuz is just 16MB, which includes all firmware/modules for my laptop. Boots to framebuffer CLI, where I also have OpenSSH/SSL installed, along with framebuffer vnc. So I can wifi (and/or ethernet) net connect and ssh/vnc into other boxes where the graphical desktop is presented on the framebuffer. vnc is common, so my GUI desktop can be sourced/served from a phone, local PC, remote PC and be Android, Windows, Linux, mac, etc... Boot in a second, can vnc connect quickly, all from a simple 16MB (xz compressed, around 50MB of ram when booted) system.

Could use a local kvm/qemu boot that serves out to vnc and vnc into that, however locally I overlayfs a squashed file system of a full Linux desktop (X) that is 'headless' but runs vncserver, that I connect to using framebuffer vnc. I boot that sfs with capabilities dropped, so in effect a 'remote' X session, but where X is under the equivalent of a restricted userid, and where network speeds are at local bus speeds, so no vnc traffic lag/network bottleneck. When viewing a full screen youtube within chrome on the framebuffer for instance lo (local net) runs at 60MB/sec, but being internal is irrelevant.

Writing to the framebuffer is slow. Even when you allocate/use regular memory to prepare frames it still ultimately has to be written to the /dev/fb0 device. On my laptop with a regular Linux booted I get 60 fps (under X). If instead that writes to vnc (memory) the framerate increases to 260 fps (more than 4x faster). When I use framebuffer vnc on the same box to connect to that I get around 15 fps. Still good enough for my purposes what what strikes me is that if that 260 fps production rate (headless X) was parallel processed (framebuffer isn't locked so anything can write to it a the same time, say with 8 cores, each managing 1/8th of the framebuffer/display, then that 15fps rate could be scaled 8-fold, to 120 fps ... on a vesa framebuffer :) Just requires the vnc server to be changed to be a parallel process, and for the vnc viewer(s) coded to match with that.