且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WinCE6.0 修改开机Logo方法集锦(三)

更新时间:2022-09-19 23:14:30

    接上一回,今天看实现方法二:将Logo.bin做成和Eboot.bin一样的格式,这样不需要可以共用Eboot.binNK.bin的代码。
       实验平台:WinCE6.0+Android6410 +4.3CLD
       实现该方法的首要任务就是生成特定格式的Logo.bin,关于WinCEbin文件的格式这里就不再细说了,可以参考李大为的《Windows CE工程实践完全解析》,里面有较为详细的阐述,另外可以参看博客http://blog.csdn.net/Veabol/article/details/4157647,本人有直接将24BMP图片转换为特定格式bin文件的代码,不过没有完善的很好,需要的朋友可以留言。
       下面从格式角度说说Logo.bin生成的主要步骤:
       1、首先像前面的方法一样,获得24BMP图片数据,转换成二进制码写入到bin文件;
       2、在bin文件开始处,添加7字节的标识("B000FF/x0A");
       3、在7字节标识后面,是4字节的Logo.bin在内存中存储的起始地址dwImageStart,这里设置为显示缓冲的地址EBOOT_FRAMEBUFFER_UA_START(当然也可以为其开辟单独的内存空间,不过需要配置bib文件,较为麻烦,本人没有尝试,有兴趣的朋友可以试试)。
       4、再接着是4字节的Logo.bin需要在内存中存储的数据大小dwImageLength,这个值可以设置为显示缓冲空间的大小EBOOT_FRAMEBUFFER_SIZE(本人是0x00100000 = 1M的空间),这里也就限制了BMP图片数据的大小,不可以超过1M,如果确实超过1M了,那就必须修改EBOOT_FRAMEBUFFER_SIZE的值以满足你的要求;
       5、在往后应该就是映像的一条一条的记录Record,每条Record包括4部分:4字节的记录存储起始地址dwRecAddr4字节的记录长度dwRecLen4字节的校验和dwRecChk,最后是记录的真实数据。这里为了简单,把所有的BMP图片数据当做一条记录,那么dwRecAddr=dwImageStartdwRecLen=dwImageLength,校验和则是所有图片数据的和,记录的真实数据指的就是前面提到的BMP图片的数据。
       6、这一部很重要,容易被忽视。就是在Logo.bin最后还得加一条结束记录,即dwRecAddr=0dwRecLen=0dwRecChk=0,这条记录必须有,否则程序不知道什么时候结束。
       在生成了Logo.bin后,看看代码的修改情况:
       1、首先修改Loader.h文件,为Logo.bin分配内存和Flash空间。
#define EBOOT_STORE_OFFSET                    (0) 
#define EBOOT_STORE_ADDRESS                 (EBOOT_RAM_IMAGE_BASE + EBOOT_STORE_OFFSET) 
#define EBOOT_STORE_MAX_LENGTH            (EBOOT_RAM_IMAGE_SIZE) 

//add by jazka 2011.09.14    Logo area 
//-----------------------------start--------------------------------------- 
#define LOGO_STORE_ADDRESS                     (EBOOT_FRAMEBUFFER_UA_START)            //logo.bin 
#define LOGO_STORE_MAX_LENGTH            (EBOOT_FRAMEBUFFER_SIZE) 
//----------------------------- end --------------------------------------
// 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) 
//----------------------------- end --------------------------------------
#define IMAGE_TYPE_LOADER                     0x00000001    // eboot.bin 
#define IMAGE_TYPE_RAMIMAGE                 0x00000002    // nk.bin 
#define IMAGE_TYPE_BINFS                        0x00000004 
#define IMAGE_TYPE_MXIP                         0x00000008 
#define IMAGE_TYPE_RAWBIN                        0x00000040        // raw bin .nb0 
#define IMAGE_TYPE_STEPLDR                        0x00000080        // stepldr.bin 
#define IMAGE_TYPE_MASK(dw)                (0x0000000F & (dw)) 
//add by jazka 2011.09.14 
//-----------------------------start--------------------------------------- 
#define IMAGE_TYPE_LOGO                        0x00000100            //logo.bin 
//----------------------------- end --------------------------------------
定义这些宏的目的是为了让程序的可读性更强一些,其实在代码中,你可以直接操作为EBOOT_FRAMEBUFFER_UA_START,但是这样做目的就变的模糊一些了。下面定义的IMAGE_TYPE_LOGO宏会在OEMVerifyMemory函数中使用。
       2、修改Eboot启动菜单MainMenu函数,如下:
 
                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 image\r\n"); 
                EdbgOutputDebugString ( "R) Read Configuration \r\n"); 
                EdbgOutputDebugString ( "U) DOWNLOAD image 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': 
      //modify by jazka 2011.09.14 for download logo.bin 
      //++++++++++++++++++++++start+++++++++++++++++++++++++    
      g_bUSBDownload = TRUE; 
      bDownload = TRUE; 
      goto MENU_DONE; 
      //++++++++++++++++++++++end+++++++++++++++++++++++++    
      break; 
    //-------------------------- end -----------------------------
添加下载Logo.bin的菜单选项部分和上一篇博文一样,但是下载的方式变了,以前是直接通过USB下载接收,然后写入Nand Flash中,这里为了下载NK.bin等的方式一致,直接将菜单’U’目录下的内容拷贝了过来。之所以不直接采用’U’选项,还是为了使功能更直接一些。
       3、修改OEMVerifyMemory函数,识别Logo.bin类型。
BOOL OEMVerifyMemory( DWORD dwStartAddr, DWORD dwLength ) 


        OALMSG(OAL_FUNC, (TEXT("+OEMVerifyMemory.\r\n"))); 

        // Is the image being downloaded the stepldr? 
        else if ((dwStartAddr >= STEPLDR_RAM_IMAGE_BASE) && 
                ((dwStartAddr + dwLength - 1) < (STEPLDR_RAM_IMAGE_BASE + STEPLDR_RAM_IMAGE_SIZE))) 
        { 
                OALMSG(OAL_INFO, (TEXT("Stepldr image\r\n"))); 
                g_ImageType = IMAGE_TYPE_STEPLDR;         // Stepldr image. 
                return TRUE; 
        } 

  //add by jazka 2011.09.14 for logo of system start 
  //-----------------------------start--------------------------------------- 
  if ((dwStartAddr >= LOGO_STORE_ADDRESS) && 
    ((dwStartAddr + dwLength - 1) < (LOGO_STORE_ADDRESS + LOGO_STORE_MAX_LENGTH))) 
  { 
    OALMSG(OAL_INFO, (TEXT("Logo image\r\n"))); 
    g_ImageType = IMAGE_TYPE_LOGO;         // Logo image. 
    return TRUE; 
  } 
  //----------------------------- end -------------------------------------- 

        // Is the image being downloaded the bootloader? 
        else if ((dwStartAddr >= EBOOT_STORE_ADDRESS) && 
                ((dwStartAddr + dwLength - 1) < (EBOOT_STORE_ADDRESS + EBOOT_STORE_MAX_LENGTH))) 
        { 
                OALMSG(OAL_INFO, (TEXT("Eboot image\r\n"))); 
                g_ImageType = IMAGE_TYPE_LOADER;         // Eboot image. 
                return TRUE; 
        }
这里需要强调一点的是添加的这部分代码,放置的位置,从原来的代码可以看出,依次是stepldr.bineboot.binnk.bin,他们的存放地址和大小都是依次递增的,而Logo.bin的地址是这里面最大的(可能因平台不同而不同),但是大小仅比stepldr.bin大一些,所以***放置到stepldr.bin的操作代码之后,否则会执行到其他的if语句中,这点仔细阅读代码可以发现了。
       4、修改OEMLaunch函数,添加将Logo.bin写入Nand Flash中的操作。
//add by jazka 2011.09.14 for logo.bin 
//---------------------------------------------start-------------------------------------------------------- 
case IMAGE_TYPE_LOGO: 
  if (!WriteLogoToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr)) 
  { 
    OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media.\r\n"))); 
    goto CleanUp; 
  } 
  OALMSG(TRUE, (TEXT("INFO: Logo image stored to Smart Media.    Please Reboot.    Halting...\r\n"))); 
  while(1) 
  { 
    // Wait... 
  } 
  break; 
//---------------------------------------------start--------------------------------------------------------
这里判断是Logo.bin后,调用函数WriteLogoToBootMedia将图片数据写入到Flash中。关于该函数后面介绍。
       5、修改InitDisplay函数,启动时调用函数DisplayLogoFromBootMedia读取Flash固定地址,然后将数据填充到显示缓存。这部分跟博客http://jazka.blog.51cto.com/809003/664131中的一样,就不再重新上代码了。
       6、修改nand.cpp文件,添加WriteLogoToBootMediaDisplayLogoFromBootMedia两个函数的实现,这部分和博客http://jazka.blog.51cto.com/809003/664131中的一样,也不再重新描述了。
 
       OK,到这里,WinCE6.0 修改开机Logo方法就介绍完了,当然肯定还有很多方法,毕竟高手如云啊。


本文转自jazka 51CTO博客,原文链接:http://blog.51cto.com/jazka/665721,如需转载请自行联系原作者