[SPRD] Q 版本开机 logo 显示原理

简介: [SPRD] Q 版本开机 logo 显示原理

基础知识


开机 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;
}


目录
相关文章
|
存储 缓存 安全
U-BOOT小全(五):BootLoader源码(SPL-UBoot 2)
U-BOOT小全(五):BootLoader源码(SPL-UBoot 2)
546 0
|
运维 Ubuntu Linux
【树莓派4B安装18.04桌面+远程SSH】
【树莓派4B安装18.04桌面+远程SSH】
803 0
|
算法 Unix BI
操作系统(5.2)--请求分页储存管理模式
在请求分页系统中所需要的主要数据结构是页表。为支持请求分页,须在页表中再增加若干项,供程序(数据)在换进、换出时参考。
686 0
|
机器学习/深度学习 人工智能 监控
人工智能的伦理挑战与社会责任
【8月更文挑战第11天】在人工智能技术迅速发展的今天,我们面临着前所未有的伦理和社会责任问题。本文将探讨AI技术可能带来的负面影响,包括隐私侵犯、自动化失业、偏见增强以及决策透明度的缺失。同时,我们将讨论如何通过制定合理的政策、加强国际合作、提高公众意识和培养专业人才来应对这些挑战,确保AI技术的健康发展和社会的和谐进步。
382 1
HOSTAPD ht_capab设置
HOSTAPD ht_capab设置
511 1
|
Android开发 芯片
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
745 3
|
测试技术 Android开发 开发者
RK3568 Android系统客制化动态替换ro任意属性
RK3568 Android系统客制化动态替换ro任意属性
765 1
|
编解码 Linux API
【Camera基础(一)】Camera摄像头工作原理及整机架构
【Camera基础(一)】Camera摄像头工作原理及整机架构
|
安全 Java
掌握 Java IO 流:常见问题与解决方案
【4月更文挑战第4天】Java IO 流问题详解:文件读写失败(检查路径与权限)、字符编码错误(指定正确编码)、缓冲区使用不当(优化性能)、异常处理缺失(捕获并处理异常)、资源未释放(及时关闭流或用try-with-resources)、并发访问冲突(使用同步机制)和文件锁定(处理锁文件异常)。解决这些问题可提升程序稳定性与性能。
325 1
OTA升级常见错误码汇总-CSDN博客
OTA升级常见错误码汇总-CSDN博客
1017 0