您的位置:首页 > 其它

EBoot支持SD卡下载升级Bootloader和WinCE系统

2011-08-13 23:09 225 查看
EBoot支持SD卡下载升级Bootloader和WinCE系统

经过几天的分析和搜索,终于实现了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读写需要自己实现。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐