以下内容参考自51cto博客的一个帖子,为尊重原创,给出链接http://jazka.blog.51cto.com/809003/664131
http://topic.csdn.net/u/20100126/14/ef1fc7c4-d8db-426b-b6bf-b74d74cdd05a.html
开机后Eboot通过读取NandFlash上的logo.bin,顺利显示并引导系统。
这个过程大致如下:
周一:
1)跟踪分析bootloader源码,通过添加.h文件的方式修改启动界面,但Eboot.bin却烧不进去了。
2)从技术支持得知,是因为从新编译的Eboot.bin太大——这就有矛盾,要将logo打包在Eboot.bin中,必然增大Eboot,怎么办呢?继续分析Eboot代码。
周二:
1)从各方面了解,要将大些的logo(750K)加载在启动界面中,一般的做法是将该logo烧写在
NandFlash的某个固定位置,然后Eboot启动时从NandFlash读出并加载进显示缓冲区实现。
2)顺着这个思路,开始研究分析Eboot的NandFlash分区和文件系统。
周三:
1)通过分析源码得知:NandFlash的0block放置Nboot,1block放置TOC,2~5block放置
Eboot,而后被格式化BinFs文件系统放置NK镜像;
2)思路很清楚,如何将logo.bin烧进6~13block(1M)的位置,而将Binfs文件系统后移,继续
分析代码。
周四:
1)有两个结构体TOC、_IMAGE_DESCRIPTOR成为问题的难点,伴随整个Eboot的执行;其围
绕.bin文件的生成、烧写位置、NandFlash分区、启动加速;
2)特别是其特有的.bin文件,前几个字节不仅包含了接收地址、长度、校验和;还包括了要下载
的地址和长度。
3)通过修改PB下配置文件,成功将NandFlash分区,专门预留13~19block给logo;
4)思路很清楚,只要能将logo生成Eboot支持的.bin文件,就能实现下载,通过寻找合适的工
具、企图利用TOC、_IMAGE_DESCRIPTOR修改PB配置文件实现,但均以失败告终。
周五:
1)生成Eboot支持的.bin文件不可以,那修改Eboot来支持自己的.bin文件可以吗?答案是肯定
的——到这时候才理解了好多前辈对我的建议;
2)对Eboot修改主要有三处:1)添加自定义下载logo命令;2)修改NandFlash烧写函数;3)添
加NandFlash读函数。
3)当然还有相应修改image_cfg.h、loader.h、eboot.bin。
然后就可以………………………………………………………………………………………………………
1、为了增加后期更加方便的升级开机启动Logo,在启动Eboot的主菜单中添加下载Logo的选项,如下图所示,选项G)便是通过USB下载Logo数据,同时将Logo数据写入到Nand Flash的某一位置上。
#define NBOOT_BLOCK(0)
#define NBOOT_BLOCK_SIZE(1)
#define NBOOT_SECTORBLOCK_TO_SECTOR(NBOOT_BLOCK)
// TOC @ Block 1
#define TOC_BLOCK(1)
#define TOC_BLOCK_SIZE(1)
#define TOC_BLOCK_RESERVED(1)
#define TOC_SECTORBLOCK_TO_SECTOR(TOC_BLOCK)
// Eboot @ Block 2
#define EBOOT_BLOCK(3)
#define EBOOT_BLOCK_SIZE(5)
#define EBOOT_BLOCK_RESERVED(5)
#define EBOOT_SECTORBLOCK_TO_SECTOR(EBOOT_BLOCK)
//-----------------------add by grubly 2011.09.04-------------------------
//-----------------------------start--------------------------------------
// Logo @ Block 6~
#if 1
#define LOGO_BLOCK(13) //logo存储的起始位置
#define LOGO_BLOCK_SIZE(4) //图片预留多大空间 4*4k*128 = 2M
#define LOGO_BLOCK_RESERVED(2) //预留坏块
#define LOGO_SECTORBLOCK_TO_SECTOR(LOGO_BLOCK)
//----------------------------- end ---------------------------------------
//-----------------------modify by grubly 2011.09.04-----------------------
//-----------------------------start---------------------------------------
#define RESERVED_BOOT_BLOCKS(NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE +TOC_BLOCK_RESERVED + EBOOT_BLOCK_SIZE + EBOOT_BLOCK_RESERVED+ LOGO_BLOCK_SIZE+LOGO_BLOCK_RESERVED)
#endif
#if 0
#define RESERVED_BOOT_BLOCKS(NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE +TOC_BLOCK_RESERVED + EBOOT_BLOCK_SIZE + EBOOT_BLOCK_RESERVED)
#endif
EdbgOutputDebugString ( "G) Download Logo now\r\n");
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 grubly 2011.10.09
( (KeySelect == 'T') || (KeySelect == 't') ) ||
( (KeySelect == 'L') || (KeySelect == 'l') ) ||
( (KeySelect == 'R') || (KeySelect == 'r') ) ||
( (KeySelect == 'U') || (KeySelect == 'u') ) ||
( (KeySelect == 'W') || (KeySelect == 'w') ) ||
( (KeySelect == 'X') || (KeySelect == 'x') ) ))
{
KeySelect = OEMReadDebugByte();
}
{
#if 1
//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 -----------------------------
#endif
memcpy((void *)IMAGE_FRAMEBUFFER_UA_BASE, prayer16bpp, LCD_ARRAY_SIZE_TFT_16BIT);
}
else //if(LCD_MODULE_TYPE == LCD_MODULE_UT43A)
{
//pWORD = (unsigned short *)prayer16bpp;
//pFB = (unsigned short *)IMAGE_FRAMEBUFFER_UA_BASE;
//add by grubly 2011.10.09 图片下载到放到中.c的数组编译进eboot中
//--------------------------start-----------------------------
#if 0
PWORD pWord = (PWORD)prayer16bpp;
PWORD pFB = (PWORD)IMAGE_FRAMEBUFFER_UA_BASE;
for (i=0; i<400*240; i++)
{
pFB[4*i - 2 * (i % 400)]= pWord[i];
pFB[4*i - 2 * (i % 400)+1] = pWord[i];
pFB[4*i - 2 * (i % 400)+400*2] = pWord[i];
pFB[4*i - 2 * (i % 400)+1+400*2] = pWord[i];
}
#endif
//-------------------------- end -----------------------------
//add by grubly 2011.10.09 图片下载到nand flash中
//--------------------------start-----------------------------
#if 1
DWORD dwReadAddr = (DWORD)IMAGE_FRAMEBUFFER_UA_BASE;
if (!DisplayLogoFromBootMedia(dwReadAddr, (DWORD)LCD_WIDTH*LCD_HEIGHT*2, dwReadAddr))
{
int i;
unsigned short *pFB;
pFB = (unsigned short *)IMAGE_FRAMEBUFFER_UA_BASE;
for (i=0; i<LCD_WIDTH*LCD_HEIGHT; i++)
*pFB++ = 0x0000;//0x001F; // Blue
}
#endif
Write the Logo data to Nand Flash
add by grubly 2011.09.05
*/
#if 1
BOOL WriteLogoToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
DWORD dwBlock,dwNumBlocks;
LPBYTE pbBuffer;
LPBYTE g_pbLogeBlock;
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));
memset (g_pbLogeBlock, 0xff, g_FlashInfo.wSectorsPerBlock);
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, g_pbLogeBlock, &si, 1);
//ReadBlock (dwBlockNum, g_pbBlock, NULL);
// Stepldr & Eboot image in nand flash
// block mark as BLOCK_STATUS_RESERVED & BLOCK_STATUS_READONLY & BLOCK_STATUS_BAD
if ((si.bBadBlock == 0x0) && (si.bOEMReserved !=3 ))
{
OALMSG(TRUE, (TEXT("si.bBadBlock \r\n)")));
++dwBlock;
++dwNumBlocks; // Compensate for fact that we didn't write any blocks.
continue;
}
OALMSG(TRUE, (TEXT("dwBlock(0x%x) X "), dwBlock));
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 *)IMAGE_FRAMEBUFFER_UA_BASE;
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;
}
#endif
BOOL WriteLogoToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) ;
BOOL DisplayLogoFromBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr) ;
#endif