要了解uboot logo与kernel logo的绘制,先了解lk和kernel的启动。要了解系统的启动步骤,最好的方式就打印uart log。
在启动uboot之前,我们先了解下preloader的启动。
大家可以看这篇文章《mtk preloader流程简介》https://blog.csdn.net/MrDongShiYi/article/details/85243751?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.compare&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.compare
这里简单说一下,
preloader流程简介
1、启动流程 (1)设备上电起来后,跳转到Boot ROM(不是flash)中的bootcode中执行把pre-loader加载起到ISRAM, 因为当前DRAM(RAM分SRAM跟DRAM,简单来说SRAM就是cache,DRAM就是普通内存)还没有准备好,所以要先把pre-loaderload到芯片内部的ISRAM(Internal SRAM)中。
(2)preloder的主要工作是初始化环境,包括c环境,timer,gpio,pmic,uart,i2c等以及装载LK镜像至DRAM中。
(3)如果实现了ATF,preloader加载完lk分区后,还会加载tee分区,在设置好环境后,会先跳转到EL3。
(4)EL3回到lk,执行lk流程,preloader流程结束
接下来讲讲LK的启动:
LK 的启动流程
lk的入口是在以下文件vendor\mediatek\proprietary\bootable\bootloader\lk\kernel\main.c kmain{}。
kmain函数中执行平台的初始化。
platform_early_init{
platform_init_interrupts();--中断初始化
platform_early_init_timer();--时钟初始化
uart_init_early();--串口初始化
platform_k64_check();
i2c_hw_init();--i2c初始化
leds_init();--点亮背光
}
platform_init{
mt_disp_init---启动lcd
mt_disp_show_boot_logo--显示第一个logo,uboot logo
}
mt_disp_show_boot_logo就是显示uboot logo的地方。
void mt_disp_show_boot_logo(void)
{
dprintf(0, "[lk logo: %s %d]\n",__FUNCTION__,__LINE__);
mt_logo_get_custom_if();
if(logo_cust_if->show_boot_logo)
{
logo_cust_if->show_boot_logo();
}
else
{
//从 log中打印可知,logo 绘制走这里
///show_logo(0);
init_fb_screen();
fill_animation_logo(BOOT_LOGO_INDEX, mt_get_fb_addr(), (void *)mt_get_tempfb_addr(), logo_addr, phical_screen);
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);
}
return;
}
BOOT_LOGO_INDEX指的是logo 资源所在地址的索引。
我们在看看logo是怎么编译进去的。在logo目录的update文件中可以看到。
uboot_logo index是0,kernel_logo index为38
这样就可以跟代码对应起来了。如果需要添加多张logo,进行切换,只要切换index就可以显示不同的logo了。同时logo目录的update文件也需要对应的修改。
下面看看kernel logo绘制的地方。从logo打印,可以找到是走show_kernel_logo函数。
void show_kernel_logo()
{
if (MTK_LOG_ENABLE == 1) {
SLOGD("[libshowlogo: %s %d]show kernel logo, index = 38 \n",__FUNCTION__,__LINE__);
}
if (error_flag == 0) {
#if defined(MTK_CARRIEREXPRESS_PACK)
anim_show_logo(get_logo_index(false));
#else
anim_show_logo(kernel_logo_position);//绘制kernel logo,kernel_logo_position=38
#endif
}
这个函数是在boot_logo_updater.c main函数调用的。
当启动完lk后,就会启动boot_logo_updater.rc进程服务。
# Update the second boot logo
service bootlogoupdater /system/bin/boot_logo_updater
class core
oneshot
uboot logo与kernel logo绘制就是这两个地方。大家看了就知道怎么添加多logo了。