![如何为帧缓冲区可加载内核模块分配内存(linux)](https://linux22.com/image/170921/%E5%A6%82%E4%BD%95%E4%B8%BA%E5%B8%A7%E7%BC%93%E5%86%B2%E5%8C%BA%E5%8F%AF%E5%8A%A0%E8%BD%BD%E5%86%85%E6%A0%B8%E6%A8%A1%E5%9D%97%E5%88%86%E9%85%8D%E5%86%85%E5%AD%98%EF%BC%88linux%EF%BC%89.png)
我正在编写一个“假”帧缓冲区设备,这样我就可以使用我的电子阅读器作为我的树莓派的外部屏幕。电子阅读器部分工作正常(https://github.com/lllandsmeer/inkvt),但现在我想让它显示为 Linux 的外部屏幕。
我虽然虚拟 Linux 帧缓冲区是“最简单的”,但也许还有其他选项可以向 Linux 添加假屏幕(显示在 xrandr 中)?
无论如何,这是当前的内核模块。它创建了一个/dev/fbX
设备,在查询后fbset
似乎配置正确。但是,当我尝试使用它时,它失败了并且我从fbcat: Corrupted page table at address 7fd7d5c90000
dmesg.
我认为这是因为我错误配置了内存区域(char mem[]
)。我尝试过使用kalloc
instread,但这也不起作用。我应该如何做事?
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fb.h>
#define WIDTH 256
#define HEIGHT 256
static char mem[WIDTH*HEIGHT*3];
static void op_fillrect(struct fb_info * info, const struct fb_fillrect * rect) {
printk(KERN_ALERT "fillrect\n");
}
static void op_copyarea(struct fb_info * info, const struct fb_copyarea * area) {
printk(KERN_ALERT "copyarea\n");
}
static void op_imageblit(struct fb_info * info, const struct fb_image * image) {
printk(KERN_ALERT "imageblit\n");
}
static struct fb_info * info;
static struct fb_ops ops = {
.owner = THIS_MODULE,
.fb_fillrect = op_fillrect,
.fb_copyarea = op_copyarea,
.fb_imageblit = op_imageblit,
};
static const struct fb_fix_screeninfo fix = {
.id = "LennartFB",
.smem_start = (unsigned long)mem,
.smem_len = sizeof(mem),
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
.line_length = 256,
};
static const struct fb_var_screeninfo var = {
.xres = WIDTH,
.yres = HEIGHT,
.xres_virtual = WIDTH,
.yres_virtual = HEIGHT,
.bits_per_pixel = 24,
.height = 256,
.width = 256,
.vmode = FB_VMODE_NONINTERLACED,
.red = { .length = 8, .offset = 16, },
.green = { .length = 8, .offset = 8, },
.blue = { .length = 8, .offset = 0, }
};
static int mod_init(void) {
int err;
info = framebuffer_alloc(0, 0);
if (!info) return -1;
info->fbops = &ops;
info->fix = fix;
info->var = var;
info->screen_base = mem;
err = fb_alloc_cmap(&info->cmap, 2, 0);
if (err < 0) return -2;
err = register_framebuffer(info);
if (err < 0) return -3;
return 0;
}
static void mod_exit(void) {
return;
}
module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL v3");
消息:
[ 4984.929380] fbcat: Corrupted page table at address 7fd7d5c90000
[ 4984.929385] PGD 8000000277709067 P4D 8000000277709067 PUD 3eb108067 PMD 2c732e067 PTE 800fffffc0f5d235
[ 4984.929391] Bad pagetable: 000d [#1] SMP PTI
[ 4984.929396] CPU: 11 PID: 8076 Comm: fbcat Tainted: P OE 5.3.0-46-generic #38~18.04.1-Ubuntu
[ 4984.929398] Hardware name: Acer Aspire A715-72G/Charmeleon_CFS, BIOS V1.19 07/13/2018
[ 4984.929403] RIP: 0033:0x55fa6cb22e98