linux 显示logo的过程

Posted 摩斯电码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 显示logo的过程相关的知识,希望对你有一定的参考价值。

 

Linux显示开机logo的函数调用:

 1 register_framebuffer
 2     ---> do_register_framebuffer
 3             ---> fb_notifier_call_chain,传递参数FB_EVENT_FB_REGISTERED和还有fb_info的event结构
 4                     ---> blocking_notifier_call_chain
 5                             ---> __blocking_notifier_call_chain
 6                                     ---> notifier_call_chain
 7                                     
 8 --> fbcon_event_notify
 9         ---> fbcon_fb_registered
10                 ---> do_fbcon_takeover
11                         ---> do_take_over_console
12                                 ---> do_bind_con_driver
13                                         ---> visual_init
14                                                 ---> fbcon_init
15                                                         ---> fbcon_prepare_logo
16                                                                 ---> fb_prepare_logo
17                                                                         ---> fb_find_logo
18                                         ---> update_screen
19                                                 ---> redraw_screen
20                                                         ---> fbcon_switch
21                                                                 ---> fb_show_logo
22                                                                         ---> fb_show_logo_line
23                                                                                 ---> fb_do_show_logo

 

获取logo:

其中获取logo数据是在fb_find_logo中完成的:

/* logo\'s are marked __initdata. Use __ref to tell
 * modpost that it is intended that this function uses data
 * marked __initdata.
 */
const struct linux_logo * __ref fb_find_logo(int depth)
{
    const struct linux_logo *logo = NULL;

    if (nologo || logos_freed)
        return NULL;

    if (depth >= 1) {
#ifdef CONFIG_LOGO_LINUX_MONO
        /* Generic Linux logo */
        logo = &logo_linux_mono;
#endif
#ifdef CONFIG_LOGO_SUPERH_MONO
        /* SuperH Linux logo */
        logo = &logo_superh_mono;
#endif
    }
    
    if (depth >= 4) {
#ifdef CONFIG_LOGO_LINUX_VGA16
        /* Generic Linux logo */
        logo = &logo_linux_vga16;
#endif
#ifdef CONFIG_LOGO_BLACKFIN_VGA16
        /* Blackfin processor logo */
        logo = &logo_blackfin_vga16;
#endif
#ifdef CONFIG_LOGO_SUPERH_VGA16
        /* SuperH Linux logo */
        logo = &logo_superh_vga16;
#endif
    }
    
    if (depth >= 8) {
#ifdef CONFIG_LOGO_LINUX_CLUT224
        /* Generic Linux logo */
        logo = &logo_linux_clut224;
#endif
#ifdef CONFIG_LOGO_BLACKFIN_CLUT224
        /* Blackfin Linux logo */
        logo = &logo_blackfin_clut224;
#endif
#ifdef CONFIG_LOGO_DEC_CLUT224
        /* DEC Linux logo on MIPS/MIPS64 or ALPHA */
        logo = &logo_dec_clut224;
#endif
#ifdef CONFIG_LOGO_MAC_CLUT224
        /* Macintosh Linux logo on m68k */
        if (MACH_IS_MAC)
            logo = &logo_mac_clut224;
#endif
#ifdef CONFIG_LOGO_PARISC_CLUT224
        /* PA-RISC Linux logo */
        logo = &logo_parisc_clut224;
#endif
#ifdef CONFIG_LOGO_SGI_CLUT224
        /* SGI Linux logo on MIPS/MIPS64 */
        logo = &logo_sgi_clut224;
#endif
#ifdef CONFIG_LOGO_SUN_CLUT224
        /* Sun Linux logo */
        logo = &logo_sun_clut224;
#endif
#ifdef CONFIG_LOGO_SUPERH_CLUT224
        /* SuperH Linux logo */
        logo = &logo_superh_clut224;
#endif
#ifdef CONFIG_LOGO_M32R_CLUT224
        /* M32R Linux logo */
        logo = &logo_m32r_clut224;
#endif
    }
    return logo;
}

以logo_linux_clut224为例,它是内核根据drivers/video/logo/logo_linux_clut224.ppm生成的(具体参考drivers/video/logo/Makefile),首先内核使用scripts/pnmtologo对logo_linux_clut224.ppm进行处理,生成名为logo_linux_clut224.c,其中含有上面的结构:

/*
 *  DO NOT EDIT THIS FILE!
 *
 *  It was automatically generated from drivers/video/logo/logo_linux_clut224.ppm
 *
 *  Linux logo logo_linux_clut224
 */

#include <linux/linux_logo.h>

static unsigned char logo_linux_clut224_data[] __initdata = {
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        ... ...
};

const struct linux_logo logo_linux_clut224 __initconst = {
        .type           = LINUX_LOGO_CLUT224,
        .width          = 80,
        .height         = 80,
        .clutsize       = 187,
        .clut           = logo_linux_clut224_clut,
        .data           = logo_linux_clut224_data
};

 

显示logo是在fb_show_logo_line中完成的:

int fb_show_logo(struct fb_info *info, int rotate)
{
    int y;

    y = fb_show_logo_line(info, rotate, fb_logo.logo, 0,
                  num_online_cpus());
    y = fb_show_extra_logos(info, y, rotate);

    return y;
}

上面在调用fb_show_logo_line时传入的最后一个参数表示连续输出几份logo,可以看到这里传入的是num_online_cpus(),即获取当前处于online的cpu的个数,所以如果是4核的cpu,那么开机会显示四只可爱的小企鹅:

 完。

以上是关于linux 显示logo的过程的主要内容,如果未能解决你的问题,请参考以下文章

linux显示启动logo源码分析以及修改显示logo

Android开机logo简单修改方法

Linux修改开机启动logo

修改u-boot的开机logo及显示过程

ARM开发板 嵌入式Linux 修改开机启动LOGO

修改linux内核开机logo并居中全屏显示