在BSP包中,有两个bootloader文件夹,一个命名为bootloader,另一个命名为bootloader_update。Bootloader文件夹用于USB下载,调试用,bootloader_update用于生产,自动升级用。下面重点介绍bootloader_update文件夹。
Bootloader_update文件夹下有四个文件夹,分别是BLCOMMON,Eboot_boot,FAT_LIB以及IROM_SD_TOOL。BLCOMMON文件夹编译后生成oal_blcommon.lib文件,供Eboot_boot调用。FAT_LIB文件夹里面包含三个静态库文件FAT_LIB.lib,HSMMCEBOOT_LIB.lib以及SDREAD_UPDATE.lib。这些静态库封装了一些用于升级的函数。Eboot_boot文件夹编译后将会产生生产用的Eboot.bin文件,该文件即能够启动系统,也能够通过硬件平台的按键控制,实现自动升级。IROM_SD_TOOL文件夹编译后,会将前面的Eboot.bin文件封装成SD卡识别的程序,最终生成IROM_SD_EBOOT.nb0。通过三星提供的IROM_Fusing_Tool工具,将该文件烧到SD卡后,2450平台就能够实现从SD卡启动了。当然前提是硬件本身要设置跳线成SD卡启动。
主程序中(Eboot_boot文件夹)定义了三个重要的变量:AUTO_UPDATE_FROM_SD;
ERASE_ALL_FLASH_BLOCKS;
SHOW_UPDATE_LOGO。
当AUTO_UPDATE_FROM_SD为真时,Eboot将会进入升级程序,为假时将引导flash中的NK,启动系统。
当ERASE_ALL_FLASH_BLOCKS为真时,Eboot将会格式化flash,然后依次升级block0.nb0,eboot.bin,nk.bin,随后启动系统。
当SHOW_UPDATE_LOGO为真时,LCD上将会出现升级文件的提示,否则显示开机LOGO。
其中AUTO_UPDATE_FROM_SD标志位通过硬件平台的按键判断,当拨动电源键后在两秒之内回拨到LOCK位置,Eboot将识别到该LOCK标志,这时将AUTO_UPDATE_FROM_SD置高,程序进入升级状态。
ERASE_ALL_FLASH_BLOCKS标志位通过从SD卡中的update.txt文件中读取。
AUTO_UPDATE_FROM_SD的相关代码如下:
- if(1 == UPDATA_ALL_IMAGE)
- {
- AUTO_UPDATE_FROM_SD =TRUE;
- ERASE_ALL_FLASH_BLOCKS =TRUE;
- SHOW_UPDATE_LOGO = TRUE;
- }
- else if( _FAT_Boot_ReadFile(_BOOT_TYPE_SD_BIN, _UPDATE_FILE_DETECT) ||auto_updatekey_isPressed() )
- {
- //自动升级健按下进行自动升级
- AUTO_UPDATE_FROM_SD=TRUE;
- }
- else
- {
- AUTO_UPDATE_FROM_SD = FALSE;
- }
其中_FAT_Boot_ReadFile()函数用于从SD卡中读取_UPDATE_FILE_DETECT文件,该字符串在最前面有如下定义:
#define _UPDATE_FILE_DETECT "DETECT BIN"
auto_updatekey_isPressed()函数用于检测拍照键是否按下,从这里可以看出,如果SD卡中存在detect.bin文件,则升级时不用再按住拍照键了。如果没有则必须按住拍照键。
Flash格式化的程序如下:
- if(1)// format flash.
- {
- //ADDED BY ZHOUPENG FOR TEST
- ReadDeviceSerialNumber(Serial_Block_Number,pBuf8);
- ReadDeviceSerialNumber(Smit_Device_Serial_Block_Number,pBuf9);
- OALMSG(TRUE, (TEXT(" ++Format FIL (Erase All Blocks)/r/n")));
- if (VFL_Close() != VFL_SUCCESS)
- {
- OALMSG(TRUE, (TEXT("[ERR] VFL_Close() Failure/r/n")));
- }
- if (WMR_Format_FIL() == FALSE32)
- {
- OALMSG(TRUE, (TEXT("[ERR] WMR_Format_FIL() Failure/r/n")));
- }
- if (WMR_Format_VFL() == FALSE32)
- {
- OALMSG(TRUE, (TEXT("[ERR] WMR_Format_VFL() Failure/r/n")));
- }
- if (WMR_Format_FTL() == FALSE32)
- {
- OALMSG(TRUE, (TEXT("[ERR] WMR_Format_FTL() Failure/r/n")));
- }
- OALMSG(TRUE, (TEXT("[INF] You can not use VFL before Format VFL/r/n")));
- OALMSG(TRUE, (TEXT(" --Format FIL (Erase All Blocks)/r/n")));
- WriteDeviceSerialNumber(Serial_Block_Number,pBuf8);
- WriteDeviceSerialNumber(Smit_Device_Serial_Block_Number,pBuf9);
- }
- static BOOL DownloadImage (LPDWORD pdwImageStart, LPDWORD pdwImageLength, LPDWORD pdwLaunchAddr)
- {
- BYTE hdr[BL_HDRSIG_SIZE];
- DWORD dwRecLen, dwRecChk, dwRecAddr;
- BOOL fIsFlash = FALSE;
- LPBYTE lpDest = NULL;
- int nPkgNum = 0;
- BYTE nNumDownloadFiles = 1;
- DWORD dwImageStart = 0;
- DWORD dwImageLength = 0;
- RegionInfo *pCurDownloadFile;
- int i;
- *pdwImageStart = *pdwImageLength = *pdwLaunchAddr = 0;
- g_DownloadManifest.dwNumRegions = 0 ;
- for( i = 0 ; i < BL_MAX_BIN_REGIONS ; i++)
- {
- g_DownloadManifest.Region[i].dwRegionStart = 0;
- g_DownloadManifest.Region[i].dwRegionLength = 0;
- g_DownloadManifest.Region[i].szFileName[0] = '/0';
- }
- do
- {
- // 将*.bin文件的前7个字节数据读入hdr(header)数组
- if (!OEMReadData (BL_HDRSIG_SIZE, hdr))
- {
- EdbgOutputDebugString ("/r/nUnable to read image signature./r/n");
- HALT (BLERR_MAGIC);
- return (FALSE);
- }
- // An N000FF packet is manufactured by Platform Builder when we're
- // downloading multiple files or when we're downloading a .nb0 file.
- if (!memcmp (hdr, "N000FF/x0A", BL_HDRSIG_SIZE))//比较数据相等时memcmp返回0
- {
- // read the packet checksum.
- //
- if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))
- {
- EdbgOutputDebugString("/r/nUnable to read download manifest checksum./r/n");
- HALT (BLERR_MAGIC);
- return (FALSE);
- }
- // read BIN region descriptions (start address and length).
- //
- if (!OEMReadData (sizeof (DWORD), (LPBYTE) &g_DownloadManifest.dwNumRegions) ||
- !OEMReadData ((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0]))
- {
- EdbgOutputDebugString("/r/nUnable to read download manifest information./r/n");
- HALT (BLERR_MAGIC);
- return (FALSE);
- }
- // verify the packet checksum.
- if (!VerifyChecksum((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0], dwRecChk))
- {
- EdbgOutputDebugString ("/r/nDownload manifest packet failed checksum verification./r/n");
- HALT (BLERR_CHECKSUM);
- return (FALSE);
- }
- if (g_pOEMMultiBINNotify)
- {
- g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);
- }
- // look for next download...
- nNumDownloadFiles = (BYTE)(g_DownloadManifest.dwNumRegions + 1); // +1 to account for this packet.
- continue;
- }
- // Is this an old X000FF multi-bin packet header? It's no longer supported.
- else if (!memcmp (hdr, "X000FF/x0A", BL_HDRSIG_SIZE))
- {
- EdbgOutputDebugString ("ERROR: The X000FF packet is an old-style multi-bin download manifest and it's no longer supported. /r/nPlease update your Platform Builder installation in you want to download multiple files./r/n");
- HALT (BLERR_MAGIC);
- return (FALSE);
- }
- // Is this a standard bin image? Check for the usual bin file signature.
- else if (!memcmp (hdr, "B000FF/x0A", BL_HDRSIG_SIZE))//lqm:下载xip.bin,nk.bin,eboot.bin时在这里执行
- {
- g_bBINDownload = TRUE;
- if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)//读取*.bin前7个头字节后的一个DWORD到dwImageStart。*.bin记录了其映像起始地址
- || !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))//读取上面接着的一个DWORD到dwImageLength。*.bin记录了其映像长度
- {
- EdbgOutputDebugString ("Unable to read image start/length/r/n");
- HALT (BLERR_MAGIC);
- return (FALSE);
- }
- }
- // If the header signature isn't recognized, we'll assume the
- // download file is a raw .nb0 file.
- //
- else
- {
- g_bBINDownload = FALSE;
- }
- if (!g_DownloadManifest.dwNumRegions)
- {
- g_DownloadManifest.dwNumRegions = 1; //声明*.bin有一条记录
- g_DownloadManifest.Region[0].dwRegionStart = dwImageStart; //声明这条记录的起始地址
- g_DownloadManifest.Region[0].dwRegionLength = dwImageLength;//声明这条记录的映像长度
- // Provide the download manifest to the OEM.
- if (g_pOEMMultiBINNotify)
- {
- g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);
- }
- }
- // Locate the current download manifest entry (current download file).
- pCurDownloadFile = &g_DownloadManifest.Region[g_DownloadManifest.dwNumRegions - nNumDownloadFiles];//当前下载文件指向*.bin开始
- // give the OEM a chance to verify memory.内存校验
- if (g_pOEMVerifyMemory && !g_pOEMVerifyMemory (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
- {
- EdbgOutputDebugString ("!OEMVERIFYMEMORY: Invalid image/r/n");//lqm:很多情况下都会执行到这里!映像不能获得?
- HALT (BLERR_OEMVERIFY);
- return (FALSE);
- }
- // check for flash image. Start erasing if it is.
- if ( (fIsFlash = OEMIsFlashAddr(pCurDownloadFile->dwRegionStart))//lqm:校验起始地址是否在Flash相应地址区域,如果是则擦除相应下载区域
- && !OEMStartEraseFlash (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
- {
- EdbgOutputDebugString ("Invalid Flash Address/Length/r/n");
- HALT (BLERR_FLASHADDR);
- return (FALSE);
- }
- // if we're downloading a binary file, we've already downloaded part of the image when searching
- // for a file header. copy what we've read so far to the destination buffer, then finish downloading.
- if (!g_bBINDownload)
- {
- lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart);
- memcpy(lpDest, hdr, BL_HDRSIG_SIZE);
- // complete the file download...
- // read data block
- if (!OEMReadData ((pCurDownloadFile->dwRegionLength - BL_HDRSIG_SIZE), (lpDest + BL_HDRSIG_SIZE)))
- {
- EdbgOutputDebugString ("ERROR: failed when reading raw binary file./r/n");
- HALT (BLERR_CORRUPTED_DATA);
- return (FALSE);
- }
- }
- // we're downloading a .bin file - download each .bin record in turn...
- else//开始下载*.bin文件到DRAM中。
- {
- while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) && //读取*.bin的第n条记录的地址.
- OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen) && //读取*.bin的第n条记录的长度.
- OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk)) //读取*.bin的第n条记录的校验和.
- {
- // last record of .bin file uses sentinel values for address and checksum.
- // 最后一条记录表示结束.其地址和校验和均为0.
- if (!dwRecAddr && !dwRecChk)
- {
- break;//读到最后一条记录时跳出循环
- }
- // map the record address (FLASH data is cached, for example)
- // 将存入的记录地址映射到指针地址lpDest
- lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, dwRecAddr);
- // read data block
- if (!OEMReadData (dwRecLen, lpDest))//读取*.bin的第n条记录的内容到lpDest.这里先把*.bin的数据读到DRAM中。
- {
- EdbgOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******/r/n", nPkgNum);
- HALT (BLERR_CORRUPTED_DATA);
- return (FALSE);
- }
- if (!VerifyChecksum (dwRecLen, lpDest, dwRecChk))//每读取一条记录则校验一次数据
- {
- EdbgOutputDebugString ("****** Checksum failure on record %d, ABORT!!! ******/r/n", nPkgNum);
- HALT (BLERR_CHECKSUM);
- return (FALSE);
- }
- // Look for ROMHDR to compute ROM offset. NOTE: romimage guarantees that the record containing
- // the TOC signature and pointer will always come before the record that contains the ROMHDR contents.
- //
- if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))
- {
- DWORD dwTempOffset = (dwRecAddr - *(LPDWORD)OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG)));
- ROMHDR *pROMHdr = (ROMHDR *)lpDest;
- // Check to make sure this record really contains the ROMHDR.
- //
- if ((pROMHdr->physfirst == (pCurDownloadFile->dwRegionStart - dwTempOffset)) &&
- (pROMHdr->physlast == (pCurDownloadFile->dwRegionStart - dwTempOffset + pCurDownloadFile->dwRegionLength)) &&
- (DWORD)(HIWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast) &&
- (DWORD)(LOWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast))
- {
- g_dwROMOffset = dwTempOffset;
- EdbgOutputDebugString("rom_offset=0x%x./r/n", g_dwROMOffset);
- }
- }
- // verify partial checksum
- OEMShowProgress (nPkgNum ++);
- // lqm added Progress in LCD.10-01-22
- while( nPkgNum>=8 )
- {
- nPkgNum = 0;
- LcdDrawString(">");
- }
- // end added.
- }
- }
- if (g_bBINDownload)
- {
- // Does this .bin file contain a TOC?
- if (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE) //+ ksk 20051219
- {
- // Contain the kernel?
- if (IsKernelRegion(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
- {
- *pdwImageStart = pCurDownloadFile->dwRegionStart;
- *pdwImageLength = pCurDownloadFile->dwRegionLength;
- *pdwLaunchAddr = dwRecLen;
- }
- }
- // No TOC - not made by romimage. However, if we're downloading more than one
- // .bin file, it's probably chain.bin which doesn't have a TOC (and which isn't
- // going to be downloaded on its own) and we should ignore it.
- //
- else if (g_DownloadManifest.dwNumRegions == 1)
- {
- *pdwImageStart = pCurDownloadFile->dwRegionStart;
- *pdwImageLength = pCurDownloadFile->dwRegionLength;
- *pdwLaunchAddr = dwRecLen;
- }
- }
- else // Raw binary file.
- {
- *pdwImageStart = pCurDownloadFile->dwRegionStart;
- *pdwLaunchAddr = pCurDownloadFile->dwRegionStart;
- *pdwImageLength = pCurDownloadFile->dwRegionLength;
- }
- // write to flash if it's flash image
- if (fIsFlash)
- {
- // finish the flash erase
- if (!OEMFinishEraseFlash ())
- {
- HALT (BLERR_FLASH_ERASE);
- return (FALSE);
- }
- // Before writing the image to flash, optionally check the image signature.
- if (g_bBINDownload && g_pOEMCheckSignature)
- {
- if (!g_pOEMCheckSignature(pCurDownloadFile->dwRegionStart, g_dwROMOffset, *pdwLaunchAddr, TRUE))
- HALT(BLERR_CAT_SIGNATURE);
- }
- }
- }
- while (--nNumDownloadFiles);
- if (fIsFlash)
- {
- nNumDownloadFiles = (BYTE)g_DownloadManifest.dwNumRegions;
- while (nNumDownloadFiles--)
- {
- if (!OEMWriteFlash (g_DownloadManifest.Region[nNumDownloadFiles].dwRegionStart, g_DownloadManifest.Region[nNumDownloadFiles].dwRegionLength))
- {
- HALT (BLERR_FLASH_WRITE);
- return (FALSE);
- }
- }
- }
- return (TRUE);
- }
上面程序中有如下代码:
OEMShowProgress (nPkgNum ++);
while( nPkgNum>=8 )
{
nPkgNum = 0;
LcdDrawString(">");
}
该程序放在反复从SD卡中读取xip.bin的一条条记录的while循环中,这里是为了在升级界面上显示升级的进度。LcdDrawString(“>”)函数是调用了LcdDraw.c中的函数,用于在LCD上绘图。
这里一定要了解xip.bin的文件格式,否则很难理解整个数据流的流程。
Xip.bin以及NK.bin的组成:
组成:标记(7)+Image开始地址(1)+Image长度(1)
记录0地址+记录0长+记录0校验和+记录0内容(文件内容)
记录1地址+记录1长+记录1校验和+记录1内容(文件内容)
......
结束符号
从上面的程序可以看出,
if (!OEMReadData (BL_HDRSIG_SIZE, hdr))
{
EdbgOutputDebugString ("/r/nUnable to read image signature./r/n");
HALT (BLERR_MAGIC);
return (FALSE);
}
即是将xip.bin的前7个字节的数据读到数组hdr,供后面分析所读的文件的类型。
if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)//读取*.bin前7个头字节后的一个DWORD到dwImageStart。*.bin记录了其映像起始地址
|| !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))//读取上面接着的一个DWORD到dwImageLength。*.bin记录了其映像长度
{
EdbgOutputDebugString ("Unable to read image start/length/r/n");
HALT (BLERR_MAGIC);
return (FALSE);
}
则是将紧接着前7个字节的两个WORD数据读到dwImageStart和dwImageLength。随后的
while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) &&
//读取*.bin的第n条记录的地址.
OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen) &&
//读取*.bin的第n条记录的长度.
OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))
//读取*.bin的第n条记录的校验和.
则开始一条条的解析xip.bin的记录。
if (!OEMReadData (dwRecLen, lpDest))
{
EdbgOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******/r/n", nPkgNum);
HALT (BLERR_CORRUPTED_DATA);
return (FALSE);
}
用于将读取到的第N条记录存放到lpDest.
分析要下载的文件并写入flash的代码如下:
- void OEMLaunch( DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr )
- {
- DWORD dwPhysLaunchAddr;
- OALMSG(1, (TEXT("+OEMLaunch./r/n")));
- // If the user requested that a disk image (stored in RAM now) be written to the SmartMedia card, so it now.
- if (g_bDownloadImage) // && (g_pBootCfg->ConfigFlags & TARGET_TYPE_NAND))
- {
- // Since this platform only supports RAM images, the image cache address is the same as the image RAM address.
- switch (g_ImageType)
- {
- case IMAGE_TYPE_STEPLDR://stepldr.bin
- if (!WriteRawImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
- {
- OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
- goto CleanUp;
- }
- OALMSG(TRUE, (TEXT("INFO: Step loader image stored to Smart Media. Please Reboot. Halting.../r/n")));
- if (g_bAutoDownload == TRUE)
- {
- return ;
- }
- while(1);
- break;
- case IMAGE_TYPE_LOADER://eboot.bin
- g_pTOC->id[0].dwLoadAddress = dwImageStart;
- g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
- if (!WriteRawImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
- {
- OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
- goto CleanUp;
- }
- if (dwLaunchAddr && (g_pTOC->id[0].dwJumpAddress != dwLaunchAddr))
- {
- g_pTOC->id[0].dwJumpAddress = dwLaunchAddr;
- #if 0 // don't write TOC after download Eboot
- if ( !TOC_Write() ) {
- EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** /r/n");
- }
- TOC_Print();
- #endif // by hmseo - 061123
- }
- OALMSG(TRUE, (TEXT("INFO: Eboot image stored to Smart Media. Please Reboot. Halting.../r/n")));
- if (g_bAutoDownload == TRUE)
- {
- return ;
- }
- while(1);
- break;
- case IMAGE_TYPE_RAMIMAGE://NK.bin
- OALMSG(1, (TEXT("+IMAGE_TYPE_RAMIMAGE dwImageStart:%08x.,dwLaunchAddr : %08x/r/n"),dwImageStart,dwLaunchAddr));
- g_pTOC->id[g_dwTocEntry].dwLoadAddress = dwImageStart;
- g_pTOC->id[g_dwTocEntry].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
- // 将NK.bin写到flash.
- if (!WriteOSImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
- {
- OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
- goto CleanUp;
- }
- EdbgOutputDebugString("INFO1:dwLaunchAdd : %08x g_pTOC->id[0].dwJumpAddress :%08x, g_pTOC->id[1].dwJumpAddress :%08x/r /r/n", dwLaunchAddr, g_pTOC->id[0].dwJumpAddress,g_pTOC->id[1].dwJumpAddress);
- if (dwLaunchAddr && (g_pTOC->id[g_dwTocEntry].dwJumpAddress != dwLaunchAddr))
- {
- g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;
- if ( !TOC_Write() ) //写TOC文件
- {
- EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** /r/n");
- }
- //masked by denis_wei for test 2009-02-05 TOC_Print();
- }
- else
- {
- dwLaunchAddr= g_pTOC->id[g_dwTocEntry].dwJumpAddress;
- EdbgOutputDebugString("INFO2: using TOC[%d] dwJumpAddress: 0x%x/r/n", g_dwTocEntry, dwLaunchAddr);
- }
- break;
- }
- if(ERASE_ALL_FLASH_BLOCKS)//lqm added.10-01-22
- {
- LcdSetStringPosition(1,15);// lqm added.10-01-22
- LcdDrawString("Starting WINCE,Please Wait......");// lqm added.10-01-22
- //LcdSetStringPosition(1,16);// lqm added.10-01-22
- }
- if ( !ReadOSImageFromBootMedia( ) )//从FLASH读取映像到DRAM.
- {
- OALMSG(OAL_ERROR, (TEXT("OEMPlatformInit ERROR: Failed to load kernel region into RAM./r/n")));
- SpinForever();
- }
- }
- OALMSG(1, (TEXT("waitforconnect/r/n")));
- if (dwLaunchAddr && (g_pTOC->id[g_dwTocEntry].dwJumpAddress != dwLaunchAddr))
- {
- g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;
- }
- else
- {
- dwLaunchAddr= g_pTOC->id[g_dwTocEntry].dwJumpAddress;
- OALMSG(OAL_INFO, (TEXT("INFO: using TOC[%d] dwJumpAddress: 0x%x/r/n"), g_dwTocEntry, dwLaunchAddr));
- }
- // Jump to downloaded image (use the physical address since we'll be turning the MMU off)...
- //
- dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);
- OALMSG(TRUE, (TEXT("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh (Virtual Address 0x%Xh).../r/n/r/n/r/n"), dwPhysLaunchAddr, dwLaunchAddr));
- // Jump...
- if( g_bAutoDownload == TRUE )
- {
- OALMSG(TRUE, (TEXT("INFO: auto update (BLOCK0IMAGE EBOOT NK) SUCCESS!/r/n")));}
- Launch(dwPhysLaunchAddr);//跳到指定物理地址运行程序.
- CleanUp:
- OALMSG(TRUE, (TEXT("ERROR: OEMLaunch: Halting.../r/n")));
- SpinForever();
- }
- 在上面代码中,如下代码用于将已经读入DRAM的数据烧写到flash.
- if (!WriteOSImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
- {
- OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
- goto CleanUp;
- }