zoukankan      html  css  js  c++  java
  • kernel下制作动态logo

    kernel下制作动态logo

    在uboot中实现logo的好处是反映速度快。

    在kernel中实现logo的好处是,不管是android还是什么其他平台,logo显示无需考虑上层平台。

    参照三星平台的写法,logo的显示一方面是开机时产品的标志,另一方面也是lcd驱动执行后显示屏工作正常的标志。

    所以logo的显示自然就藏于lcd驱动代码当中。

     

    static int __devinit s3cfb_probe(struct platform_device *pdev)

    {

     

        struct s3cfb_global *fbdev;

        fbdev kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL);

     

    ---------------------------------------------------------------

     

        pdata to_fb_plat(&pdev->dev);

        if (!pdata) {

            dev_err(fbdev->dev, "failed to get platform data ");

            ret -EINVAL;

            goto err_pdata;

        }

     

        if (pdata->cfg_gpio)

            pdata->cfg_gpio(pdev);

     

        if (pdata->clk_on)

            pdata->clk_on(pdev, &fbdev->clock);

     

    ---------------------------------------------------------------

     

        s3cfb_set_gamma(fbdev);

     

        s3cfb_set_vsync_interrupt(fbdev, 1);

        s3cfb_set_global_interrupt(fbdev, 1);

        s3cfb_init_global(fbdev);

     

    ---------------------------------------------------------------

     

        if (s3cfb_alloc_framebuffer(fbdev)) {

            ret -ENOMEM;

            goto err_alloc;

        }

     

        if (s3cfb_register_framebuffer(fbdev)) {

            ret -EINVAL;

            goto err_register;

        }

     

    ---------------------------------------------------------------

     

        if (pdata->backlight_on)

            pdata->backlight_on(pdev);

     

        if (!bootloaderfb && pdata->reset_lcd)

            pdata->reset_lcd(pdev);

     

        if (pdata->lcd_on)

            pdata->lcd_on(pdev);

     

    ---------------------------------------------------------------

     

        if (fb_prepare_logo( fbdev->fb[pdata->default_win], FB_ROTATE_UR)) {

            printk("Start display and show logo ");

            

            fb_set_cmap(&fbdev->fb[pdata->default_win]->cmap, fbdev->fb[pdata->default_win]);

            fb_show_logo(fbdev->fb[pdata->default_win], FB_ROTATE_UR);

        }

     

    ---------------------------------------------------------------

    }

     

    《如何显示logo》

     

    int fb_show_logo(struct fb_info *info, int rotate)

    {

        int y;

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

        fb_show_extra_logos(info, y, rotate);

     

        return y;

    }

     

    static int fb_show_logo_line(struct fb_info *info, int rotate,

                     const struct linux_logo *logo, int y,

                     unsigned int n)

    {

        fb_do_show_logo(info, &image, rotate, n);//

    }

     

    static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,

                    int rotate, unsigned int num)

    {

        unsigned int x;

     

        if (rotate == FB_ROTATE_UR) {

            for (x 0;

                 num && image->dx image->width <= info->var.xres;

                 x++) {

     

                image->dx ((info->var.xres num*(image->width))>>1);

                image->dy ((info->var.yres num*(image->height))>>1);

     

       

                info->fbops->fb_imageblit(info, image);//-->

     

                image->dx += image->width;

            }

        

    }

     

     

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     

    在s3cfb_init_fbinfo中:

        fb->fbops &s3cfb_ops;

    挂在struct fb_info上。

     

    struct  fb_ops  s3cfb_ops {

        .owner THIS_MODULE,

        .fb_fillrect cfb_fillrect,

        .fb_copyarea cfb_copyarea,

        .fb_imageblit cfb_imageblit,

        .fb_check_var s3cfb_check_var,

        .fb_set_par s3cfb_set_par,

        .fb_blank s3cfb_blank,

        .fb_pan_display s3cfb_pan_display,

        .fb_setcolreg s3cfb_setcolreg,

        .fb_ioctl s3cfb_ioctl,

        .fb_open s3cfb_open,

        .fb_release s3cfb_release,

    };

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     

     

    void cfb_imageblit(struct fb_info *p, const struct fb_image *image)

    {

        。。。 。。。    

        if (image->depth == 1) {

     

        else

            color_imageblit(image, p, dst1, start_index, pitch_index);//-->

    }


    具体画logo之处:

    static inline void color_imageblit(const struct fb_image *image,

                       struct fb_info *p, u8 __iomem *dst1,

                       u32 start_index,

                       u32 pitch_index)

    {

        

        u32 __iomem *dst, *dst2;

        u32 color 0, val, shift;

        int i, n, bpp p->var.bits_per_pixel;

        u32 null_bits 32 bpp;

        u32 *palette (u32 *) p->pseudo_palette;

        const u8 *src image->data;

        u32 bswapmask fb_compute_bswapmask(p);

     

        dst2 (u32 __iomem *) dst1;

     

        for (i image->height; i--; {//画行

            image->width;

            dst (u32 __iomem *) dst1;

            shift 0;

            val 0;

     

            if (start_index) {

                u32 start_mask ~fb_shifted_pixels_mask_u32(p,

                            start_index, bswapmask);

                val FB_READL(dst) start_mask;

                shift start_index;

            }

     

            while (n--) {

     

                if (p->fix.visual == FB_VISUAL_TRUECOLOR ||

                    p->fix.visual == FB_VISUAL_DIRECTCOLOR )

                    color palette[*src];

                else

                    color *src;

                color <<= FB_LEFT_POS(p, bpp);

                val |= FB_SHIFT_HIGH(p, color, shift bswapmask);

                if (shift >= null_bits) {

                    FB_WRITEL(val, dst++);

     

                    val (shift == null_bits) :

                        FB_SHIFT_LOW(p, color, 32 shift);

                }

                shift += bpp;

                shift &= (32 1);

                src++;

            }

     

            if (shift) {

                u32 end_mask fb_shifted_pixels_mask_u32(p, shift,

                            bswapmask);

                FB_WRITEL((FB_READL(dst) end_mask) val, dst);

            }

            dst1 += p->fix.line_length;

            if (pitch_index) {

                dst2 += p->fix.line_length;

                dst1 (u8 __iomem *)((long __force)dst2 ~(sizeof(u32) 1));

     

                start_index += pitch_index;

                start_index &= 32 1;

            }

        }

    }

     

     代码分析在此不做详述,看参见网络各路分析。

    要制作动态logo,无非是一帧一帧的画企鹅。先看这段代码:

     

        if (fb_prepare_logo( fbdev->fb[pdata->default_win], FB_ROTATE_UR)) {

            printk("Start display and show logo ");

            

            fb_set_cmap(&fbdev->fb[pdata->default_win]->cmap, fbdev->fb[pdata->default_win]);

            fb_show_logo(fbdev->fb[pdata->default_win], FB_ROTATE_UR);

        }

     其实我们无需关注函数的细节,从函数的名字上看fb_prepare_logo准备好了一个结构体,该结构体代表了一只企鹅(.ppm图片)。

    如果我要画一群不同的企鹅在屏幕上移动,那么就需要一群代表不同ppm的结构体,但内核默认情况下这样的结构体只有一个。怎么办?

    以“对内核代码尽量少改动”的原则下,以上这段代码显示一帧,然后加个循环,不断显示不同的帧:

    for (i 0; x; i++)

    {

            

    }

     即:循环一次,采集一张图,并填充这个唯一的结构体struct linux_logo,然后显示。

     问题来了,fb_find_logo(int depth)只能找到固定的一只企鹅,但在我们面前的一群企鹅,难道给fb_find_logo多加个参数?

    以“对内核代码尽量少改动”的原则下,我们发现,depth是32位,即使夸张的说,但其充其量也就用个16位,其他位不用简直是浪费啊浪费,然后,高8位可以用于企鹅编号,使fb_find_logo拥有识别不同企鹅的能力。然后,就可以达到不同的企鹅在屏幕移动的效果。

    kernel下制作动态logo

    00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    制作ppm文件

    在2.6内核中修改开机LOGO

    方法一:

              1、在Linux系统中安装所需的包netpbm。我用的Fedora 10,刚开始安装命令是yum install netpbm,安装完成后,发现系统中还是没有相关的命令。

              看来是相关的包没有安装完整,又使用命令yum install netpbm*,又安装了两个包

     

    Dependencies Resolved

    ================================================================================

     Package             Arch        Version                   Repository      Size

    ================================================================================

    Installing:

     netpbm-devel        i386        10.47.04-1.fc10           updates         96 k

     netpbm-progs        i386        10.47.04-1.fc10           updates        1.9 M

     

    再看,发现相关的命令就有了

    [root@localhost developer]# png

    pngcomp   pngcrush  pngnq     pngtopam  pngtopnm 

     

    2、logo图片改成.ppm格式。首先你要有个和自己屏幕分辨率一样或者小于屏幕分辨率的图片,如linux_iunin_logo.png

       将png图片转成pnm

         pngtopnm linux_iunin_logo.png linux_iunin_logo.pnm

       将pnm图片的颜色数限制在224色

        pnmquant 224 linux_iunin_logo.pnm logo_iunin_clut224.pnm

       将pnm图片转换成我们需要的ppm

        pnmtoplainpnm logo_iunin_clut224.pnm logo_iunin_clut224.ppm

     

    也可以使用软件,比如友善之臂的loglmaker,可以直接把图片转换成.ppm格式的。

     

    方法二:

    用RedHat9自带的图片编辑工具GIMP。

    找一个任意格式的图片(JPG,BMP之类的),在图形界面中,右键单击这个图片,选“打开方式->The GIMP”,第一次打开需要安装GIMP软件,安装完后自动运行GIMP,这是一个很强大的图像处理工具,可称为Linux下的photoshop。

        右键单击窗口中的图片选“图像->模式->索引”,把颜色数改为:224(这步很重要)。其他的都默认,OK后右键“文件->Save As”,保存为ppm格式的文件,确定后弹出一个对话框,选择Ascii,OK后,GIMP会把图片转换成ppm格式,把这个文件复制到logo文件夹中就可以

  • 相关阅读:
    luogu P3704 [SDOI2017]数字表格
    「雅礼集训 2018 Day4」Magic(分治NTT)
    「清华集训 2017」小 Y 和恐怖的奴隶主
    [WC2019]数树(树形dp+多项式exp)
    「FJWC2020Day5-zzq」lg (容斥)
    BoundedOptimization TopCoder
    MapGuessing TopCoder
    线性递推(Berlekamp-Massey 算法)
    杜教筛小记
    「余姚中学 2019 联测 Day 6」解码
  • 原文地址:https://www.cnblogs.com/songfeixiang/p/3733789.html
Copyright © 2011-2022 走看看