Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asking for support of /dev/fb0 (or /dev/graphics/fb0) directly #110

Open
fish4terrisa-MSDSM opened this issue Oct 20, 2023 · 3 comments
Open
Labels
enhancement New feature or request

Comments

@fish4terrisa-MSDSM
Copy link
Contributor

In some embedded linux platforms, both sdl and x11 just doest exist. Maybe a support of /dev/fb0` can help to run rvvm on these platforms. We can also handle the keyboard, mouse or touchscreen events directly. Maybe this feature can also be used in some BSDs and can reduce the performance cost of SDL or X11.( And also, remove these depends, which will definitely help us in porting RVVM to SONY walkmans and some other platforms with limited gui libs)

@fish4terrisa-MSDSM fish4terrisa-MSDSM added the enhancement New feature or request label Oct 20, 2023
@LekKit
Copy link
Owner

LekKit commented Oct 21, 2023

It is already possible to run SDL/SDL2 on top of the kernel framebuffer / DRM (DRM is more modern) instead of running atop X/Wayland server. It is also possible to compile SDL manually for those platforms.

However I am willing to provide some help in implementing a lowlevel framebuffer driver. The basic principle (On Linux) is:

  • Allocate/claim a VT and switch it into a graphical mode using ioctl(KDSETMODE, KD_GRAPHICS...)
  • Open /dev/fb0
  • Query some info via ioctl() like resolution and pixel format
  • mmap() it into the process space and then attach that memory region to the VM

Now the remaining issue is to implement mouse/keyboard input, which is handled by /dev/uinput or /dev/input/, I have no idea how to work with them.

I have made a minimal framebuffer implementation (Doesn't claim the VT so it is a bit glitchy for now) - see lower comment

@LekKit
Copy link
Owner

LekKit commented Oct 21, 2023

UPD: Turns out some Linux framebuffers have non-canonical stride (I.e. bytes per row != width * bytes per pixel), so the above implementation would skew the guest framebuffer and make it unusable on such occasions.
Added non-canonical framebuffer stride support in a01b956, here is updated framebuffer driver code:

#include "fb_window.h"
#include "blk_io.h"
#include "utils.h"

#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>

#include <linux/kd.h>
#include <linux/vt.h>

bool fb_window_create(fb_window_t* window)
{
    // In future it would be preferred to support mmap
    // atop builtin blk_io/vma_ops abstractions
    int fd = open("/dev/fb0", O_RDWR);
    if (fd < 0) {
        rvvm_error("Failed to open /dev/fb0: %s", strerror(errno));
        return false;
    }

    struct fb_fix_screeninfo fix_info;
    struct fb_var_screeninfo var_info;
    if (ioctl(fd, FBIOGET_FSCREENINFO, &fix_info)
     || ioctl(fd, FBIOGET_VSCREENINFO, &var_info)) {
        rvvm_error("Failed to determine fb size");
        close(fd);
        return false;
    }
    // Determine pixel format, resolution, stride
    window->fb.format = rgb_format_from_bpp(var_info.bits_per_pixel);
    window->fb.width = var_info.xres;
    window->fb.height = var_info.yres;
    window->fb.stride = fix_info.line_length;
    window->fb.buffer = mmap(NULL, framebuffer_size(&window->fb),
                             PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    if (window->fb.buffer == MAP_FAILED) {
        rvvm_error("Failed to mmap() framebuffer: %s", strerror(errno));
        return false;
    }

    return true;
}

void fb_window_close(fb_window_t* window)
{
    munmap(window->fb.buffer, framebuffer_size(&window->fb));
}

void fb_window_update(fb_window_t* window)
{
    UNUSED(window);
}

@LekKit
Copy link
Owner

LekKit commented Oct 21, 2023

Now this complicates VM migration even more as migrating across hosts with different stride is impossible unless we manually convert framebuffers upon rendering....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants