efi-framebuffer device的注册和显示参数的传递

来源:互联网 发布:计算机算法与设计 编辑:程序博客网 时间:2024/06/06 00:44
在drivers/firmware/efi/linstub/arm-stub.c 中efi_entry 中会调用setup_graphics
static struct screen_info *setup_graphics(efi_system_table_t *sys_table_arg)
{
    efi_guid_t gop_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
    efi_status_t status;
    unsigned long size;
    void **gop_handle = NULL;
    struct screen_info *si = NULL;

    size = 0;
    status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL,
                &gop_proto, NULL, &size, gop_handle);
    if (status == EFI_BUFFER_TOO_SMALL) {
        si = alloc_screen_info(sys_table_arg);
        if (!si)
            return NULL;
        efi_setup_gop(sys_table_arg, si, &gop_proto, size);
    }
    return si;
}
在setup_graphics 中会parse bios 中传递过来的参数,并保存到si中。
然后在init_screen_info 中让screen_info指向si,这样screen_info中就保持从bios中传递过来的framebuffer的参数
static void __init init_screen_info(void)
{
    struct screen_info *si;

    if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
        si = early_memremap_ro(screen_info_table, sizeof(*si));
        if (!si) {
            pr_err("Could not map screen_info config table\n");
            return;
        }
        screen_info = *si;
        early_memunmap(si, sizeof(*si));

        /* dummycon on ARM needs non-zero values for columns/lines */
        screen_info.orig_video_cols = 80;
        screen_info.orig_video_lines = 25;
    }

    if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI &&
        memblock_is_map_memory(screen_info.lfb_base))
        memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size);
}
最后会调用register_gop_device 来注册platform_device
static int __init register_gop_device(void)
{
    void *pd;

    if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
        return 0;

    pd = platform_device_register_data(NULL, "efi-framebuffer", 0,
                       &screen_info, sizeof(screen_info));
    return PTR_ERR_OR_ZERO(pd);
}
subsys_initcall(register_gop_device);

这样当用户打开CONFIG_FB_EFI的时候,就会生成/dev/fbn device。通过对这个device的read和read 就可以将画面显示到fbcon上。

static struct platform_driver efifb_driver = {
    .driver = {
        .name = "efi-framebuffer",
    },
    .probe = efifb_probe,
    .remove = efifb_remove,
};

builtin_platform_driver(efifb_driver);
efi-framebuffer 对应的driver是在/drivers/video/fbdev/efifb.c中。
其通过在efifb_probe中调用register_framebuffer来得到对console的控制权。




0 0
原创粉丝点击