#include #include #include #include #include static struct driver *vesa_driver = NULL; static struct framebuffer_device *vesafb = NULL; static kern_status_t set_varinfo(struct device *dev, const struct framebuffer_varinfo *info) { return KERN_UNSUPPORTED; } static struct framebuffer_device_ops vesa_ops = { .set_varinfo = set_varinfo, }; static void init_vesa(struct framebuffer_device *dev) { struct framebuffer_varinfo *varinfo = &dev->fb_varinfo; struct framebuffer_fixedinfo *fixedinfo = &dev->fb_fixedinfo; memcpy(varinfo, bootfb_varinfo(), sizeof *varinfo); memcpy(fixedinfo, bootfb_fixedinfo(), sizeof *fixedinfo); } static kern_status_t online(struct kext *self) { const struct framebuffer_fixedinfo *fixedinfo = bootfb_fixedinfo(); if (!fixedinfo->fb_baseptr) { /* No VESA information avaiable, cannot create device. */ return KERN_OK; } vesa_driver = driver_create(self, "vesafb"); if (!vesa_driver) { return KERN_NO_MEMORY; } driver_register(vesa_driver); struct framebuffer_device *fb = framebuffer_device_create(); fb->fb_ops = &vesa_ops; init_vesa(fb); struct device *fb_base = framebuffer_device_base(fb); snprintf(fb_base->dev_name, sizeof fb_base->dev_name, "vesafb"); kern_status_t status = device_register(fb_base, vesa_driver, misc_device()); if (status != KERN_OK) { driver_unregister(vesa_driver); driver_destroy(vesa_driver); return status; } vesafb = fb; return KERN_OK; } DEFINE_KEXT("net.doorstuck.socks.vesafb", online, NULL, KEXT_NO_DEPENDENCIES);