经过几天的分析和搜索,终于实现了S3C2416+WinCE平台下的SD卡下载升级功能。实现烧写文件分别为block0img.nb0、EBOOT.bin、nk.bin。
简单记录一下实现过程,以免以后忘记了。
要实现这个功能首先得知道S3C2416+WinCE平台的Bootloader流程,之前转载的一篇文章叫做《Samsung的ARM处理器iROM启动模式介绍》,文中介绍了S3C6410使用IROM启动的流程。
block0img.nb0中包含有两个loader,他们的加载顺序如下图:
进入EBOOT之后,首先运行的是Main函数,Main函数的实现非常的简单:
void main(void) { //MemoryTest_Function(); BootloaderMain(); // Should never get here. SpinForever(); }
|
所以实际的下载和启动等过程都是在BootloaderMain中完成,这个函数微软已经为我们写好了,当然我们也可以拷贝出来自己更改,在WINCE600\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG\BLCOMMON\blcommon.c目录下有实现源码,在WINCE600\PLATFORM\COMMON\SRC\COMMON\BOOT\BLCOMMON\blcommon.c目录下也有一份相同的代码,在Eboot中具体使用的哪个就要看Sources文件了。
因此跟踪BootloaderMain函数看下去:
BootloaderMain
=>KernelRelocate:把镜像中的全局变量Copy到Ram中,该过程完成之后,其他模块才能正常访问保存的全局数据
=>OEMDebugInit:OEM需要实现的函数,一般来讲是串口调试信息等初始化
=>OEMPlatformInit:这个函数就是我们非常熟悉的OEM平台初始化了, EBoot的菜单选项就在这个里面实现的。
=>OEMPreDownload:根据用户在菜单中的选择,判断是下载还是直接启动。
=>DownloadImage:这里就是主要的下载过程,首先会判断下载的文件类型,并解析bin格式的文件
=>GetImageType => OEMReadData读取前面7个字节做比较,具体可以参考blcommon.c文件。
这个里面的OEMReadData就是实际的读取我们下载到的数据的操作。后面有我的实现代码。
=>OEMLaunch:这里面实现了flash的写入
BOOL OEMReadData(DWORD dwData, PUCHAR pData) { BOOL ret; OALMSG(OAL_FUNC, (TEXT("+OEMReadData.\r\n"))); if ( g_dwDownloadDevice == DOWNLOAD_DEVICE_NONE ) { ret = EbootEtherReadData(dwData, pData); } else if ( g_dwDownloadDevice == DOWNLOAD_DEVICE_USB ) { ret = USBReadData(dwData, pData); } else if ( g_dwDownloadDevice == DOWNLOAD_DEVICE_SD ) { ret = SDReadData(dwData, pData); } return(ret); }
|
在实际操作过程当中,实际已经将SD卡的文件读取到内存的BUFFER当中,可以在OEMPreDownload中实现,调用SDReadData实际是读取内存当中的数据。经过实现,如果不将数据读取到内存当中会出现校验出错,原因还有待分析。
总结一下,要实现SD卡文件下载,只需要在原有boot代码的基础上实现SD卡文件读取到BUFFER的函数(ReadFileFromSD),和OEMReadData即可,下面一段代码是我从SD卡读取文件到BUF的代码:
BOOL ReadFileFromSD( const char *sFileName, UINT32 dwImageType, BYTE *Buffer ) { ULONG nFileNumber; ULONG i; BYTE * ptxBuf; unsigned int nCheckSum = 0; ULONG fileSize; FILEINFO hFile = {0};
if (!FATOpenFile(&hFile, sFileName)) return FALSE;
EdbgOutputDebugString("Reading '%s' from SD Card, Waitting\r\n", sFileName); EdbgOutputDebugString("Please don't remove Card\r\n");
if ( dwImageType == UBIIMAGE || dwImageType == BINIMAGE ) { fileSize = FATGetFileSize (&hFile); if ( !fileSize ) { EdbgOutputDebugString("%s file Get size Error\n", sFileName); return FALSE; } FATReadFile(&hFile, Buffer, fileSize);
g_pDownPt += fileSize;
EdbgOutputDebugString("Read from Card OK\r\n"); } else if ( dwImageType == NB0IMAGE || dwImageType == DIOIMAGE ) { nFileNumber = 1;
memset((void *)Buffer, 0, 7+4+4+4+4+MAX_PATH);
ptxBuf = Buffer; *(ptxBuf++)=0x4E;//N000FF\x0A
*(ptxBuf++)=0x30; *(ptxBuf++)=0x30; *(ptxBuf++)=0x30; *(ptxBuf++)=0x46; *(ptxBuf++)=0x46; *(ptxBuf++)=0xa;
fileSize = FATGetFileSize (&hFile); //nb0 filesize
// Read nb0 file
if (!FATReadFile(&hFile, (BYTE *)(Buffer+7+4+4+4+4+MAX_PATH + 1), fileSize)) { RETAILMSG(1,(TEXT("#### File READ ERROR\r\n"))); while(1); } // 缓冲区字节对齐读取后,数据被后移一个字节,拷贝回来
memcpy(Buffer+7+4+4+4+4+MAX_PATH, Buffer+7+4+4+4+4+MAX_PATH + 1, fileSize);
ptxBuf = Buffer + 7 + 4 + 4;
*(ptxBuf+0) = 0; //nb0 start address == 0
*(ptxBuf+1) = 0; //nb0 start address == 0
*(ptxBuf+2) = 0; //nb0 start address == 0
*(ptxBuf+3) = 0; //nb0 start address == 0
*(ptxBuf+4) = (BYTE)((fileSize >> 0) & 0xff); *(ptxBuf+5) = (BYTE)((fileSize >> 8) & 0xff); *(ptxBuf+6) = (BYTE)((fileSize >> 16) & 0xff); *(ptxBuf+7) = (BYTE)((fileSize >> 24) & 0xff);
strcpy((char *)(ptxBuf+8), sFileName);
nCheckSum = 0; for ( i = 0; i < 4+4+MAX_PATH; i++ ) { nCheckSum += (unsigned char)(*(ptxBuf+i)); }
ptxBuf = Buffer+7;
*(ptxBuf+0) = (BYTE)((nCheckSum >> 0) & 0xff); *(ptxBuf+1) = (BYTE)((nCheckSum >> 8) & 0xff); *(ptxBuf+2) = (BYTE)((nCheckSum >> 16) & 0xff); *(ptxBuf+3) = (BYTE)((nCheckSum >> 24) & 0xff); *(ptxBuf+4) = (BYTE)((nFileNumber >> 0) & 0xff); *(ptxBuf+5) = (BYTE)((nFileNumber >> 8) & 0xff); *(ptxBuf+6) = (BYTE)((nFileNumber >> 16) & 0xff); *(ptxBuf+7) = (BYTE)((nFileNumber >> 24) & 0xff);
g_pDownPt += (7+4+4+4+4+MAX_PATH); g_pDownPt += FATGetFileSize (&hFile); } else { EdbgOutputDebugString("SDInterface Parsing param error!!!\r\n"); }
FATCloseFile(&hFile); return TRUE; }
|
其实大部分的功能实现都是仿照USB下载来完成的,如果EBOOT中没有USB下载可以仿照,也可以仿照网络下载,实现方式都是大同小异。只是FAT文件系统和SD读写需要自己实现。
阅读(4002) | 评论(2) | 转发(0) |