基础知识
开机 logo 和充电 logo 资源位置
vendor\sprd\release\bmp\unisoc_bmp
根据你的编译选项使用对应 logo bmp
vendor\sprd\release\pac_config\sl9832e_1h10_64b.ini
BootLogo=1@./vendor/sprd/release/bmp/unisoc_bmp/samsung_720_1280_24bit.bmp
Fastboot_Logo=1@./vendor/sprd/release/bmp/unisoc_bmp/samsung_720_1280_24bit.bmp
编译后开机 logo 位置 vendor\sprd\release\IDH\sl9832e_1h10_64b_Natv-user\SHARKLE_9832e_64b_halo
代码流程
正常启动模式和 fastboot 启动模式
最终都是通过 lcd_splash(LOGO_PART); 进行绘制显示 logo
bsp\bootloader\u-boot\common\loader\boot_mode.c
void normal_mode(void)
{
#ifndef CONFIG_ZEBU
vibrator_hw_init();
set_vibrator(1);
vlx_nand_boot(BOOT_PART, BACKLIGHT_ON, LCD_ON);
#else
vlx_nand_boot_zebu(BOOT_PART, BACKLIGHT_ON, LCD_ON);
#endif
return;
}
void fastboot_mode(void)
{
debugf("enter\n");
#ifdef CONFIG_SPLASH_SCREEN
extern int drv_lcd_init (void);
debug("[LCD] Drawing the logo...\n");
drv_lcd_init();
lcd_splash(LOGO_PART);
lcd_enable();
vibrator_hw_init();
set_vibrator(1);
extern void set_backlight(uint32_t value);
fastboot_lcd_printf();
set_backlight(BACKLIGHT_ON);
mdelay(400);
set_vibrator(0);
#endif
#if (defined CONFIG_X86) && (defined CONFIG_MOBILEVISOR) && (defined CONFIG_SPRD_SOC_SP9853I)
tos_start_notify();
#endif
#ifdef CONFIG_SECBOOT
if (get_lock_status() == VBOOT_STATUS_UNLOCK){
debugf("INFO: LOCK FLAG IS : UNLOCK!!!\n");
lcd_printf("\n INFO: LOCK FLAG IS : UNLOCK!!!\n");
}
get_secboot_base_from_dt();
#endif
do_fastboot();
return;
}
BOOT_PART 其实就是 logo 字符串,搜索找到定义位于
bsp\bootloader\u-boot\include\loader_common.h
#define SPL_PART "spl"
#define LOGO_PART "logo"
#define CHARGER_LOGO_PART "chargelogo"
#define BOOT_PART "boot"
#define RECOVERY_PART "recovery"
#define FACTORY_PART "prodnv"
#define PRODUCTINFO_FILE_PATITION "miscdata"
#define DT_PART "dt"
继续跟进正常启动模式下,vlx_nand_boot(BOOT_PART, BACKLIGHT_ON, LCD_ON);
bsp\bootloader\u-boot\common\loader\loader_nvm.c
uint32_t uboot_start_time;
void vlx_nand_boot(char *kernel_pname, int backlight_set, int lcd_enable)
{
boot_img_hdr *hdr = (void *)raw_header;
char *mode_ptr = NULL;
uchar *partition = NULL;
int i = 0;
int j = 0;
int ret = 0;
uchar *dt_adr = DT_ADR;
uint32_t lcd_init_time;
uint32_t backlight_on_time;
uint32_t uboot_consume_time;
#ifdef CONFIG_SOC_IWHALE2
aon_lpc_config();
#endif
wakeup_source_enable();
ap_clk_doze_enable();
#ifdef CONFIG_SPLASH_SCREEN
lcd_init_time = SCI_GetTickCount();
printf("lcd start init time:%dms\n", lcd_init_time);
if(lcd_enable) {
extern void lcd_enable(void);
debug("[LCD] Drawing the logo...\n");
drv_lcd_init();
lcd_splash(LOGO_PART);
lcd_enable();
}
........
再来看看 lcd_splash(LOGO_PART) 干了啥
bsp\bootloader\u-boot\common\splash.c
int lcd_splash(uchar *logo_part_name)
{
int x = 0, y = 0, ret;
u8 *addr;
u8 *s;
s = getenv("splashimage");
if (!s) {
debugf("%s: failed to get env from splashimage\n");
return -1;
}
addr = (u8 *) simple_strtoul(s, NULL, 16);
ret = splash_screen_prepare(logo_part_name, addr);
if (ret)
return ret;
splash_get_pos(&x, &y);
return bmp_display(addr, x, y);
}
logo_part_name 值可能是 "logo 或 "chargelogo",还有显示充电logo的时候
从指定分区中读取出 logo bmp存储地址 addr
其实就是 bmp_image
bsp\bootloader\u-boot\common\cmd_bmp.c
int bmp_display(ulong addr, int x, int y)
{
int ret;
struct bmp_image *bmp = (struct bmp_image *)addr;
void *bmp_alloc_addr = NULL;
unsigned long len;
if (!((bmp->header.signature[0]=='B') &&
(bmp->header.signature[1]=='M')))
bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr);
if (!bmp) {
printf("There is no valid bmp file at the given address\n");
return 1;
}
#if defined(CONFIG_LCD)
ret = lcd_display_bitmap((ulong)bmp, x, y);
#elif defined(CONFIG_VIDEO)
ret = video_display_bitmap((unsigned long)bmp, x, y);
#else
# error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO
#endif
if (bmp_alloc_addr)
free(bmp_alloc_addr);
return ret;
}
最终在 lcd 中绘制 logo
bsp\bootloader\u-boot\common\lcd.c
int lcd_display_bitmap(ulong bmp_image, int x, int y)
{
u8 bmp_bpix;
u16 width, height, bmp_width, fb_width, hdr_size;
u32 colors;
u8 *fb, *bmap, *bmap8;
u16 *fb16, *bmap16, *cmap_base = NULL;
u32 *fb32;
rgb24_t *bmap24;
rgb32_t *bmap32;
struct bmp_image *bmp = (struct bmp_image *)map_sysmem(bmp_image, 0);
struct bmp_color_table_entry *palette = bmp->color_table;
.....
switch (bmp_bpix) {
case 1:
case 8:
cmap_base = configuration_get_cmap();
#ifdef CONFIG_LCD_BMP_RLE8
u32 compression = get_unaligned_le32(&bmp->header.compression);
debug("compressed %d %d\n", compression, BMP_BI_RLE8);
if (compression == BMP_BI_RLE8) {
lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y);
break;
}
#endif
if (cmap_base)
BMP_TO_FB(fb16, u16, bmap8, u8, PIXEL8_TO_INT16, cmap_base);
else
BMP_TO_FB(fb16, u16, bmap8, u8, PIXEL16_TO_INT16, palette);
break;
case 16:
BMP_TO_FB(fb16, u16, bmap16, u16, RGB16_TO_INT16);
break;
case 24:
BMP_TO_FB(fb32, u32, bmap24, rgb24_t, RGB24_TO_INT32);
break;
case 32:
BMP_TO_FB(fb32, u32, bmap32, rgb32_t, RGB32_TO_INT32);
break;
default:
break;
};
lcd_sync();
return 0;
}