中秋假期已过,回来继续该博文主题。今天讲解第二种方法,将Logo图片的数据写入到Nand Flash中,在启动初始化LCD的时候,从固定的地址将数据读出并填充到显示缓存中。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
       实验平台:WinCE6.0+Android6410 +4.3寸CLD。
       以下内容参考自CSDN论坛的一个帖子,不过里面的描述不是特别清楚,该主题博文进行了整理。为尊重原创,给出链接http://topic.csdn.net/u/20100126/14/ef1fc7c4-d8db-426b-b6bf-b74d74cdd05a.html。
      
       将Logo图片写Flash的思路继续细分,又可以分为几种不同的实现方法,今天先描述实现方法一,这是其中比较简单的一种方法,不需要修改bib文件等配置性文件,只需要修改代码即可。
       首先提几个问题:
       1、在什么时候将Logo数据写入Nand Flash?
       2、在什么时候读Nand Flash数据到显示缓存?
       3、要写的Logo的数据是什么?
       4、写入Flash的什么位置,又从什么位置读数据?
       5、写Flash的函数和读Flash的函数如何实现?
       上面几个问题弄清楚了,方法一基本就出来了。给出上面几个问题的解决方法:
       1、答:为了增加后期更加方便的升级开机启动Logo,在启动Eboot的主菜单中添加下载Logo的选项,如下图所示,选项G)便是通过USB下载Logo数据,同时将Logo数据写入到Nand Flash的某一位置上。
 
      
        2、答:在Eboot的初始化InitializeDisplay中,可以找到关于填充显示缓存的代码,改为从Flash的某一位置读取即可。
      3、答:关于写Logo的数据,可以是bin格式的,也可以是原始的bmp格式。其实bin格式的内容也都是通过读取bmp文件的位图阵列而生成的。两者的差别就在于一个在Eboot里面实现读取bmp的位图阵列,一个是在独立的应用程序中读取的。
      4、答:关于操作Nand Flash的位置问题,需要查看loader.h文件的相关代码,有关于Block的使用情况,如下所示。在这里为Logo数据分配一定的Block。
// NAND Boot (loads into SteppingStone) @ Block 0
#define NBOOT_BLOCK                                 0
#define NBOOT_BLOCK_SIZE                        1
#define NBOOT_SECTOR                                BLOCK_TO_SECTOR(NBOOT_BLOCK)

// TOC @ Block 1
#define TOC_BLOCK                                     1
#define TOC_BLOCK_SIZE                            1
#define TOC_SECTOR                                    BLOCK_TO_SECTOR(TOC_BLOCK)

// Eboot @ Block 2
#define EBOOT_BLOCK                                 2
#define EBOOT_SECTOR_SIZE                     FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE)
#define EBOOT_BLOCK_SIZE                        SECTOR_TO_BLOCK(EBOOT_SECTOR_SIZE)
#define EBOOT_SECTOR                                BLOCK_TO_SECTOR(EBOOT_BLOCK)

       5、答:Flash的读写操作函数实现主要在nand.cpp文件中,具体实现可以参考函数ReadOSImageFromBootMedia和WriteOSImageToBootMedia。
      下面给出详细的修改步骤:
      1、首先修改loader.h文件,为Logo数据分配一定的Block空间。添加如下代码:
// Eboot @ Block 2
#define EBOOT_BLOCK                                 2
#define EBOOT_SECTOR_SIZE                     FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE)
#define EBOOT_BLOCK_SIZE                        SECTOR_TO_BLOCK(EBOOT_SECTOR_SIZE)
#define EBOOT_SECTOR                                BLOCK_TO_SECTOR(EBOOT_BLOCK)

//-----------------------add by jazka 2011.09.04-------------------------
//-----------------------------start--------------------------------------
// Logo @ Block 6~
#define LOGO_BLOCK                    6
#define LOGO_BLOCK_SIZE                20
#define LOGO_SECTOR                            BLOCK_TO_SECTOR(LOGO_BLOCK)
//----------------------------- end ---------------------------------------

//-----------------------modify by jazka 2011.09.04-----------------------
//-----------------------------start---------------------------------------
//#define RESERVED_BOOT_BLOCKS                (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)
#define RESERVED_BOOT_BLOCKS                (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE + LOGO_BLOCK_SIZE)

从上面可以看出从Block6开始,为Logo分配了20个Block的Flash空间,这样可以存放64KB*20=1280KB大小的Logo数据,即<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1M以内的图片数据。由于Logo占用了一定的Block空间,所以后面Nk的起始位置RESERVED_BOOT_BLOCKS需要向后移动。
       2、在Eboot启动主菜单中增加下载Logo数据的相应的选项。修改的代码如下:
EdbgOutputDebugString ( "F) Low-level format the Smart Media card\r\n");
    //add by jazka 2011.09.05
    //-----------------------------start---------------------------------
    EdbgOutputDebugString ( "G) DOWNLOAD Logo now(USB)\r\n");
    //----------------------------- end ---------------------------------
                EdbgOutputDebugString ( "L) LAUNCH existing Boot Media p_w_picpath\r\n");
                EdbgOutputDebugString ( "R) Read Configuration \r\n");
                EdbgOutputDebugString ( "U) DOWNLOAD p_w_picpath now(USB)\r\n");
                EdbgOutputDebugString ( "W) Write Configuration Right Now\r\n");
                EdbgOutputDebugString ( "\r\nEnter your selection: ");

while (! ( ( (KeySelect >= '0') && (KeySelect <= '9') ) ||
                                     ( (KeySelect == 'A') || (KeySelect == 'a') ) ||
                                     ( (KeySelect == 'B') || (KeySelect == 'b') ) ||
                                     ( (KeySelect == 'C') || (KeySelect == 'c') ) ||
                                     ( (KeySelect == 'D') || (KeySelect == 'd') ) ||
                                     ( (KeySelect == 'E') || (KeySelect == 'e') ) ||
                                     ( (KeySelect == 'F') || (KeySelect == 'f') ) ||
             ( (KeySelect == 'G') || (KeySelect == 'g') ) ||                 //add by jazak 2011.09.05
                                     ( (KeySelect == 'L') || (KeySelect == 'l') ) ||
                                     ( (KeySelect == 'R') || (KeySelect == 'r') ) ||
                                     ( (KeySelect == 'U') || (KeySelect == 'u') ) ||
                                     ( (KeySelect == 'W') || (KeySelect == 'w') ) ))
                {
                        KeySelect = OEMReadDebugByte();
                }

//add by jazka 2011.09.05
    //--------------------------start-----------------------------
    case 'G':
    case 'g':
      {
        OALMSG(TRUE, (TEXT("Please send the Logo through USB.\r\n")));
        g_bUSBDownload = TRUE;

{
          DWORD dwStartAddr = 0;
          LPBYTE lpDes = NULL;        
          lpDes = (LPBYTE)(FILE_CACHE_START);

if (!OEMReadData(LCD_WIDTH*LCD_HEIGHT*2, lpDes))
          {
            OALMSG(TRUE, (TEXT("Error when sending the Logo through USB.\r\n")));
            SpinForever();
          }

dwStartAddr = (DWORD)lpDes;

if (!WriteLogoToBootMedia(dwStartAddr, (DWORD)(LCD_WIDTH*LCD_HEIGHT*2), dwStartAddr))
          {
            OALMSG(TRUE, (TEXT("Error when WriteLogoToBootMedia.\r\n")));
            SpinForever();
          }
        }
      }
      break;
    //-------------------------- end -----------------------------

这里把g_bUSBDownload设置为TRUE,以便后面选择USB进行下载。由于USB下载的速度和写Flash速度不匹配,所以先下载到内存中,然后在一下子写入Flash中(这部分详解见博客http://jazka.blog.51cto.com/809003/605776)。WriteLogoToBootMedia便是Flash的写函数,后面给出实现。
       3、修改LCD初始化函数InitializeDisplay,修改代码如下:
// Fill Framebuffer
#if(SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD35A)
        memcpy((void *)EBOOT_FRAMEBUFFER_UA_START, (void *)InitialImage_rgb16_320x240, 320*240*2);
#elif        (LCD_BPP == 16)
        {
    //delete by jazka 2011.08.31    修改开机启动界面
             /* int i;
                unsigned short *pFB;
                pFB = (unsigned short *)EBOOT_FRAMEBUFFER_UA_START;

for (i=0; i<LCD_WIDTH*LCD_HEIGHT; i++)
    {
                        //*pFB++ = 0x0000;//0x001F;                // Blue
      //*pFB++ = 0x001F;                                             //modify by jazka 2011.07.22
      *pFB++ = InitialImage_rgb16_480x272[i];
    }
    */

//add by jazka 2011.08.31
    //memcpy((void *)EBOOT_FRAMEBUFFER_UA_START, (void *)InitialImage_rgb16_480x272, 480*272*2);

//modify by jazka 2011.09.07
    DWORD dwReadAddr = (DWORD)EBOOT_FRAMEBUFFER_UA_START;
    if (!DisplayLogoFromBootMedia(dwReadAddr, (DWORD)LCD_WIDTH*LCD_HEIGHT*2, dwReadAddr))
    {
      int i;
      unsigned short *pFB;
      pFB = (unsigned short *)EBOOT_FRAMEBUFFER_UA_START;

for (i=0; i<LCD_WIDTH*LCD_HEIGHT; i++)
        *pFB++ = 0x0000;//0x001F;                // Blue
    }

DisplayLogoFromBootMedia函数便是Flash的度函数,这里将读出的数据写入到显示缓存EBOOT_FRAMEBUFFER_US_START中,该函数的实现后面给出。
      4、修改nand.cpp文件,添加WriteLogoToBootMedia和DisplayLogoFromBootMedia两个函数的实现。
/*
  Write the Logo data to Nand Flash
  add by jazka 2011.09.05
*/
BOOL WriteLogoToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
  DWORD dwBlock,dwNumBlocks;
  LPBYTE pbBuffer;
  SectorInfo si;

OALMSG(TRUE, (TEXT("+WriteLogoToBootMedia\r\n")));

dwBlock = LOGO_BLOCK;
  pbBuffer = (LPBYTE)dwImageStart;

OALMSG(TRUE, (TEXT("^^^^^^^^ 0x%x ^^^^^^^^\r\n"), (unsigned short *)pbBuffer));

dwNumBlocks = (dwImageLength/(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) +    
                                                 (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0);

OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength));
  OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks));

while (dwNumBlocks--)
  {
    OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
    OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
    OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));

FMD_ReadSector(dwBlock*g_FlashInfo.wSectorsPerBlock, NULL, &si, 1);

// Stepldr & Eboot p_w_picpath in nand flash
    // block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
    if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 ))
    {
      ++dwBlock;
      ++dwNumBlocks;                // Compensate for fact that we didn't write any blocks.
      continue;
    }

if (!ReadBlock(dwBlock, NULL, g_pSectorInfoBuf))
    {
      OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
      return(FALSE);
    }

if (!FMD_EraseBlock(dwBlock))
    {
      OALMSG(OAL_ERROR, (TEXT("WriteData: failed to erase block (0x%x).\r\n"), dwBlock));
      return FALSE;
    }

if (!WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf))
    {
      OALMSG(OAL_ERROR, (TEXT("WriteData: failed to write block (0x%x).\r\n"), dwBlock));
      return(FALSE);
    }

++dwBlock;
    pbBuffer += g_FlashInfo.dwBytesPerBlock;
    OALMSG(TRUE, (TEXT("dwBytesPerBlock : %d\r\n"), g_FlashInfo.dwBytesPerBlock));
  }

OALMSG(TRUE, (TEXT("_WriteLogoToBootMedia\r\n")));

return TRUE;
}

/*
  Read the Logo data from Nand Flash
  add by jazka 2011.09.05
*/
BOOL DisplayLogoFromBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
  unsigned int * pFB32 = (unsigned int *)EBOOT_FRAMEBUFFER_UA_START;
  unsigned int * dst = pFB32;        
  //unsigned int * p = NULL;
  SectorInfo si;

DWORD dwBlock,dwNumBlocks;

OALMSG(TRUE, (TEXT("+ReadLogoFromBootMedia\r\n")));

dwBlock = LOGO_BLOCK;

OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), dwImageLength));
  OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), g_FlashInfo.wDataBytesPerSector));
  OALMSG(TRUE, (TEXT("dwImageLength = 0x%x \r\n"), g_FlashInfo.wSectorsPerBlock));

if (0 == g_FlashInfo.wDataBytesPerSector || 0 == g_FlashInfo.wSectorsPerBlock)
  {
    return FALSE;
  }

dwNumBlocks = (dwImageLength / (g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock)) +
                (dwImageLength%(g_FlashInfo.wDataBytesPerSector*g_FlashInfo.wSectorsPerBlock) ? 1: 0);
  OALMSG(TRUE, (TEXT("dwNumBlocks = 0x%x \r\n"), dwNumBlocks));

while (dwNumBlocks--)
  {    
    OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
    OALMSG(TRUE, (TEXT("g_FlashInfo.wSectorsPerBlock(0x%x)"), g_FlashInfo.wSectorsPerBlock));
    OALMSG(TRUE, (TEXT(" = 0x%x \r\n"), dwBlock*g_FlashInfo.wSectorsPerBlock));

//BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable)
    if (!ReadBlock(dwBlock, (LPBYTE)dst, g_pSectorInfoBuf))
    {
      OALMSG(OAL_ERROR, (TEXT("WriteData: failed to read block (0x%x).\r\n"), dwBlock));
      return(FALSE);    
    }
    dst += g_FlashInfo.dwBytesPerBlock/4;
    ++dwBlock;
  }
  OALMSG(TRUE, (TEXT("_ReadLogoFromBootMedia\r\n")));

return TRUE;
}

       5、关于Logo数据的文件bin的生成,网上有很多工具可以实现,其实可以自己写一个应用程序完成该功能。本人编写了24位Bmp文件生成RGB565格式的bin文件的程序,这部分代码也可以在nand.app中写成一个函数,在写入Flash时调用转换为相应的RGB565数据即可,这样更新Logo时可以更直接。注意下载时的数据量是现在的3倍。
       这里就不给出源代码了,如果需要,请留言。

今天就到这里,改天上实现方法二:将Logo.bin做成和Eboot.bin一样的格式,这样下载Eboot.bin的很多代码就可以直接使用。

转载于:https://blog.51cto.com/jazka/664131

WinCE6.0 修改开机Logo方法集锦(二)相关推荐

  1. WinCE6.0 修改开机Logo方法

    中秋假期已过,回来继续该博文主题.今天讲解第二种方法,将 Logo 图片的数据写入到 Nand Flash 中,在启动初始化 LCD 的时候,从固定的地址将数据读出并填充到显示缓存中.       实 ...

  2. 修改服务器系统显示logo,Win10修改开机LOGO界面样式怎么改?教你修改win10开机LOGO界面样式的方法...

    正常情况下,Windows10系统开机界面显示"田字格"LOGO,看久了感觉很疲惫,想要将默认LOGO换成其他样式,这可以随意更改吗?答案是可以的.那么Win10修改开机LOGO界 ...

  3. 高通平台msm8916修改开机logo【原创】

    经过两天的奋战终于把开机logo给搞定了啊. 首先修改开机logo要从哪里入手呢?先分析一下源码看看. ---> 1 void display_image_on_screen() 2 { 3 s ...

  4. MT6765 + Android9.0修改开机动画

    工作中经常因客户不同需要修改开机动画.开机第一帧.不同平台修改方式也不同,为此整理此文档希望能帮助大家. 下面是3大厂商修改开机动画后对GMS.OTA升级影响列表: 可以知道MTK.高通平台如果只修改 ...

  5. [RK3588 Android12]修改开机logo和播放开机视频

    1.修改开机logo 替换kernel-5.10/logo.bmp和logo_kernel.bmp两个图片文件即可修改开机logo,替换后编译报错 error: out/target/product/ ...

  6. Android 8.0 开机动画,RK3326 android10.0(Q) 开机logo+开关机动画替换

    RK3326 android10.0(Q) 开机logo+开关机动画替换 2020年08月14日 | 萬仟网移动技术 | 我要评论 开机logouboot和kernel阶段的logo分别为开机显示的第 ...

  7. Rockchip3066 修改开机 LOGO 和开机动画

    Rockchip3066 修改开机 LOGO 和 开机动画: 一.主要使用的工具是:FirmwareTool_Release_v3.3 文件夹,RK30DevelopTool 文件夹,还有 RKFac ...

  8. 修改开机LOGO图片教程及注意事项/通过C++实现bmp图位深度从32位转换为8位

    修改开机LOGO图片教程及注意事项/通过C++实现bmp图位深度从32位转换为8位 文章目录 修改开机LOGO图片教程及注意事项/通过C++实现bmp图位深度从32位转换为8位 修改开机LOGO图片教 ...

  9. Android修改开机Logo和开机动画

    做车机一般都会修改开机Logo和开机动画,下面只是记录我项目中修改开机Logo和开机动画的方法,仅供参考: 关于开机logo的修改,是将一张分辨率合适的名字必须为boot_logo.bmp格式的位深是 ...

最新文章

  1. FPGA之道(74)Verilog生成语句
  2. Sublime配置C和C++编译运行环境
  3. qconbeijing2014
  4. [HDU] 1181 变形课-简单建模后广搜
  5. python理论知识选择题_python基础知识练习题(一)
  6. 传奇服务端各文件用途说明
  7. machine id linux,linux – 机器ID是uuid吗?
  8. Ubuntu(Debian) 18.04 安装后开启ssh和防火墙传输文件
  9. Springboot项目结构浅析
  10. hibernate数据库连接池
  11. python如何设置画布开始位置_如何设置亚马逊站内广告?亚马逊自动广告手动广告都在什么位置?...
  12. LINUX下查看CPU使用率的命令[Z]
  13. 6. access_token
  14. [洛谷P3444] [POI2006]ORK-Ploughing
  15. ios 越狱后 重启springboard 命令
  16. php企鹅号_腾讯内容开放平台
  17. 怎么给pdf文件插入页码,有什么简单的方法?
  18. cyberduck 源代码学习记录一,编译源代码 build for window
  19. Loan Repayment//二分//排位3
  20. Windows通用克隆系统入门基础知识简介

热门文章

  1. php多选框怎么传值,tp3.2如何处理多选框传参和判断状态
  2. Java项目:抽奖点名神器(HTML+可自定义抽选)
  3. java clob内存溢出_java - java.sql.SQLException:ORA-01704:字符串文字太长时插入或更新 - 堆栈内存溢出...
  4. 河科大c语言上机实验答案,2016年河南科技学院信息工程学院C语言上机编程考研复试题库...
  5. event对象(触发机制)
  6. for循环动态的给select标签添加option内容
  7. 掌握 MySQL 这 19 个骚操作,效率至少提高3倍
  8. 运维开发笔记整理-前后端分离
  9. GDI+ Bitmap与WPF BitmapImage的相互转换
  10. [转]web打印实现方案 Lodop6.034 使用方法总结