RK平台SDK,实现logo可变的方式有很多种

内核启动读取文件

这个方式最简单,写一个splash(开机精灵),启动的时候直接加载文件系统的图片。但是uboot的logo显示不了,开机显示logo有点慢。

修改boot.img中的资源

这个比较困难,而且要整个FIT文件烧录,烧录坏了还会导致内核无法启动。

flash加一个logo分区

这个最好,修改也方便,上位机直接从固定的地址烧录bmp图片进去就好了

流程:
  1. 修改.BoardConfig.mk文件

    export RK_PARTITION_CMD_IN_ENV="256K(env),1M@256K(idblock),1M(uboot),8M(boot),32M(rootfs),48M(oem),32M(userdata),1M(logo)"
    export RK_INCLUDE_LOGO_IMAGE=${RK_INCLUDE_LOGO_IMAGE:-y}
    export RK_LOGO_IMAGE_SOURCE=${RK_LOGO_IMAGE_SOURCE:-sysdrv/source/kernel/logo.bmp}
    export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ubifs,oem@/oem@ubifs,userdata@/userdata@ubifs
    

    RK_INCLUDE_LOGO_IMAGE 控制完整 update.img 是否携带默认 logo.img。

    RK_INCLUDE_LOGO_IMAGE=n:不包含 Logo,升级时保留用户当前 Logo。用在升级的时候不更新logo

    RK_LOGO_IMAGE_SOURCE:指定默认 Logo 的源文件。

    RK_PARTITION_FS_TYPE_CFG: 指定分区的类型。

    rootfs@IGNORE@ubifs
    
    • IGNORE不是不使用。
    • 表示不由启动脚本重复挂载。
    • 内核已经根据启动参数将它挂载为 /。
    • 当前启动参数包含:
    oem@/oem@ubifs
    
    • mtd5经过UBI管理。
    • 挂载到 /oem。
    userdata@/userdata@ubifs
    
    • mtd6经过UBI管理。
    • 挂载到 /userdata。
  2. build.sh新增build_logo_img()生成logo.img

    参考:build.sh脚本修改示例

    build_logo_img() 负责:

    1. 检查 BoardConfig是否包含 (logo)。上面的RK_INCLUDE_LOGO_IMAGE=y/n
    2. 检查现有 env.img 是否包含 (logo)。env.img生成时有可能没有根据RK_PARTITION_CMD_IN_ENV生成相应的分区信息。
    3. 检查 RK_INCLUDE_LOGO_IMAGE。
    4. 校验源 BMP格式。
    5. 生成230454字节的 output/image/logo.img。
  3. mk-update_pack.sh

    这一步将logo.img添加到update.img中,不需要改动这个脚本。这个脚本直接就支持自动打包任意同名分区镜像。

    BoardConfig
      │
      │ export RK_INCLUDE_LOGO_IMAGE=y/n
      ▼
    project/build.sh
      │
      ▼
    build_logo_img()
      │
      ├── y:生成output/image/logo.img
      └── n:删除已有logo.img,不生成
      │
      ▼
    mk-update_pack.sh
      │
      ├── 找到logo.img:加入update.img
      └── 找不到logo.img:跳过logo分区内容
    
  4. 修改 mkimg 打包

    mkimg 是正式 Kernel/FIT镜像打包脚本,负责:

    生成resource.img
    准备Kernel
    准备DTB
    调用mkimage
    生成boot.img
    
    • Kernel构建系统将 scripts/resource_tool.c 编译成主机工具 scripts/resource_tool,mkimg 调用该工具生成 resource.img。

      ./resource_tool ${DTB_PATH} ${LOGO} ${LOGO_KERNEL} ${BATTERY_BMPS}
      
    • 去掉${LOGO} ${LOGO_KERNEL},删除LOGO和LOGO_KERNEL对应的变量

    • scripts/bmpconvert 这个用于logo转换,不需要了

    • cp logo.bmp ${objtree}/ 删除logo复制相关内容

    • 将DTB,kernel,resource.img合并成boot.img(原来就有的功能)

  5. 修改uboot源码

    这一步是让uboot原本加载从boot.img中加载logo改成读logo分区加载logo

    具体包括:

    1. 增加 load_logo_partition()。
    2. 使用 part_get_info_by_name(..., "logo", ...) 查找分区。
    3. 使用 blk_dread() 读取 BMP。
    4. 校验240×±320、24bpp、BI_RGB、230454字节。
    5. 处理正高度和负高度 BMP行序。
    6. 解码到 framebuffer。
    7. 修改 rockchip_show_logo(),使用 load_logo_partition()。
    8. 修改 rockchip_display_fixup(),复用同一个分区 Logo。
    9. 删除 logo,uboot 和 logo,kernel 文件名解析。
    10. 保留 load_bmp_logo() 给充电动画使用。
  6. 修改kernel源码

    原始流程中

    U-Boot根据 logo,kernel 从 boot.img/resource.img 准备 Kernel Logo framebuffer,Linux DRM驱动接管这块保留 framebuffer;Kernel本身不直接解析 resource.img。

    修改后的流程:

    Linux DRM驱动主动读取同一个 logo MTD分区,并把图片应用到 U-Boot保留的 framebuffer。

    具体修改:

    1. 使用 get_mtd_device_nm("logo") 查找 MTD。
    2. 跳过 SPI NAND坏块。
    3. 读取并校验 BMP。
    4. 转换到 framebuffer格式。
    5. 与 U-Boot已有像素执行 memcmp()。
    6. 相同时不重复复制,减少接管撕裂。
    7. 不同时更新 framebuffer并做 DMA同步。
    8. 读取失败时保留 U-Boot已经显示的图片。
    9. Logo错误不阻止 Kernel启动。
  7. 修改设备树

    基础 rv1106.dtsi 中原来存在:

    logo,uboot = "logo.bmp";
    logo,kernel = "logo_kernel.bmp";
    

    板级设备树必须显式删除:

    /delete-property/ logo,uboot;
    /delete-property/ logo,kernel;
    

    保留:

    logo,mode = "center";
    charge_logo,mode = "center";
    

    不能只是不重新配置,因为它们会从基础设备树继承下来。