recovery 升级界面顶部花屏问题分析
说明:
实际解决问题的过程有点曲折,后面找到原因,分析清楚问题后,总结下正确的分析方法,大致分析流程如下。
问题描述:
在进入recovery的时候,第一次上电进入recovery时,顶部会有一长条花屏,如下图所示。
问题分析:
通过出现花屏的时间点,我们判断,出现花屏的时候,已经进入了recovery系统,那么出现花屏的分析点,定位在recovery中。
通过在recovery中定位,我们发现是,在gr_init初始化的过程出现的花屏,具体是函数get_framebuffer这个函数,通过一步步的跟踪,发现如下规律:
在ioctl(fd, FBIOPUT_VSCREENINFO, &vi)调用之后,整个屏幕花了,在第一次memset(fb->data, 0, vi.yres * fi.line_length);调用之后,屏幕又全部黑了。
我们大致可以猜测,在启动过程中,屏幕开始是黑屏的,中间花屏了一次,后来又黑屏,在花屏 -> 黑屏的过程,时间太长了,那么我们就看到了顶部的一长条的花屏现象,为了验证这个问题,我们在memset(fb->data, 0, vi.yres * fi.line_length);之前,尝试增加延时时间,看能不能看到跟明显的花屏现象。在我们尝试增加不同的延时时间,当延时usleep(5*1000)时,我们看到了如下现象:
这跟我们的预期一样,就是在初始化的过程,中间有一次花屏,然后清除屏幕(memset),在这个花屏到黑屏的过程,时间差很短暂,这样我们就看到了顶部的一长条花屏现象。
让我们疑惑的是,ioctl(fd, FBIOPUT_VSCREENINFO, &vi)这个过程,怎么会花屏,这个是设置屏幕可变参数的ioctl,可能是由于我们修改了屏幕的可变参数,使得屏幕刷新了下,把framebuffer缓冲区的数据显示在了屏幕上面,这样导致了花屏,那么就是framebuffer缓冲区的数据没有清空,带着这个疑惑,我们在启动过程,查看下对应内存地址的数据。
我们从dts中,查看到framebuffer的内存地址是0x3c000000,
fb_reserved:linux,meson-fb {
compatible = "amlogic, fb-memory";
//size = <0x0 0x1900000>;
reg = <0x0 0x3c000000 0x0 0x2000000>;
no-map;
};
在uboot下面md
我们对比下,正常不花屏的时候的内存数据:
显然问题明白了,framebuffer中的数据没有被清除,这样起来进入recovery初始化的时候,ioctl(fd, FBIOPUT_VSCREENINFO, &vi)设置可变参数的时候,把缓冲区的数据显示到屏幕上面,这样导致了花屏的产生。
问题总结:
主要的花屏原因,是因为framebuffer对于的内存中的数据未被清空,导致的ioctl跟memset过程时间差,导致了花屏现象,在这之前,清除framebuffer缓冲区的数据即可。