分析 kernel/drivers/video/msm/logo.c 文件
1. int load_565rle_image(char *filename) 加载图像文件“logo.rle”, 该文件位于手机根目录下
info = registered_fb[0]; //会把frame buffer 的第一个buffer 的信息获取
info->screen_base //直接指向第一个iframe_buffer
读取的的图像文件RGB565数据转化成ABRG数据
2. static void __init draw_logo(void) 把图像显示到LCD
fb_info->fbops->fb_open(fb_info, 0);
fb_info->fbops->fb_pan_display(&fb_info->var, fb_info); //把该fb_info的缓冲区的内容送到前台显示
3. module_init(logo_init);表示驱动模块加载的时候显示该图像
int __init logo_init(void)
{
if (!load_565rle_image(INIT_IMAGE_FILE))
draw_logo();
return 0;
}
4. 有个问题,需要尽快的显示该logo 图像,所以要把module_init的执行顺序提前。这就需要在编译的时候把该模块的编译尽量提前
@kernel/dirvers/Makefile
obj-y += pinctrl/
obj-y += gpio/
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/
obj-$(CONFIG_RAPIDIO) += rapidio/
obj-y += video/
obj-y += leds/
@kernel/derives/video/Makefile
obj-$(CONFIG_VGASTATE) += vgastate.o
obj-y += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
modedb.o fbcvt.o
fb-objs := $(fb-y)
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/ 必须运行在fb-y之后,因为需要frame buffer 准备好了才能画图显示
obj-y += backlight/
由此可见,任何一个makefile 中编译链接文件的顺序是相当有讲究的
5. 通过分析log的显示是相当滞后的了
1)start_kernel()->rest_init()->do_basic_setup()->do_initcalls() 然后才会执行到module_init
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
继续看:
#define device_initcall(fn) __define_initcall("6",fn,6)
文件linux/arch/arm/kernel/vmlinux.lds.S 中
__initcall_start = .;
49 *(.initcall1.init)
50 *(.initcall2.init)
51 *(.initcall3.init)
52 *(.initcall4.init)
53 *(.initcall5.init)
54 *(.initcall6.init) //module_init在这才开始执行
55 *(.initcall7.init)
56 __initcall_end = .;
在kernel中显示始终是慢的,由此我们需要在little kernel或boot中显示logo
6. 通过以上分析,给出了我们如何在kernel 打开文件画图的思路
利用sys_open,sys_lseek,sys_read,sys_close从内核打开文件系统中的文件
利用registered_fb[0] 直接从kernel操作frame buffer.