[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;
}


目录
相关文章
|
23天前
win10更换系统启动时候的图片
win10更换系统启动时候的图片
8 0
|
1月前
|
编解码 Ubuntu 虚拟化
ubuntu无法粘贴复制windows中的内容,分辨率无法自适应电脑自带系统
ubuntu无法粘贴复制windows中的内容,分辨率无法自适应电脑自带系统
|
Ubuntu
ubuntu20+window双系统启动引导项的修复
ubuntu20+window双系统启动引导项的修复
1660 1
ubuntu20+window双系统启动引导项的修复
|
区块链
Win7设置U盘启动背景方法
Win7设置U盘启动背景方法
162 0
Win7设置U盘启动背景方法
|
编解码 Linux
16.15 Linux字符界面调整分辨率
如果安装了 Linux 的图形界面,则使用图形界面修改分辨非常方便也很简单。但是如果只安装了字符界面,难道就不能修改分辨率了吗?
254 0
16.15 Linux字符界面调整分辨率
|
编解码 Ubuntu Linux
linux实用技巧:获取当前系统显示分辨率"xrandr --current"
linux实用技巧:获取当前系统显示分辨率"xrandr --current"
linux实用技巧:获取当前系统显示分辨率"xrandr --current"
|
Ubuntu Linux 索引