MINI2440从SD卡更新NK及nboot(二)
在上一篇文章中,实现应用程序操作FLASH及更新Nboot。这篇讨论应用程序更新NK,这个比更新Nboot要复杂一些。由于MINI2440不使用EBOOT,系统从SD卡系统后,Flash是没有分区的,理论上NK.nb0不一定需要BINFS,但如果不使用BINFS,系统是启动不了的,这让我百思不得其解。。。
分区可使用BP_OpenPartition(),这个只能在驱动中使用,因此在FMD_OEMIoControl()加多一个Case, BP_OpenPartition()需要指定超始地址,长度,分区类型等。MINI2440第2块写TOC,第3块到第19块是BootLogo,第20块开始才是BINFS。SuperVivi烧入NK时可看到分区的一些信息,如下:
Enter your selection: w
Clear the free memory
Please send the Image through USB.
Download Address=0x80200000 Length=0x1a338e0
........................Done.
Low Level Format: Start = 0x1300(19 块), Num = 0x7ed00(2029 块)
.............................................................................................................................................................................................................Done.
Create Partition: Start = 0x1400(20 块), Num = 0xd200(210 块).
................................................Done.
Create Partition: Start = 0xe600(230 块), Num = 0x6fd00(1789 块).
...Done.
Start Windows CE...;
从上面得知,分了两个区,第一个区为BINFS ,第二区为FAT 。
在调用BP_OpenPartition() 之前需调用BP_LowLevelFormat(),因为BP_OpenPartition 会检测MBR 。
2 BP_Init(…);
3 BP_LowLevelFormat(…);
4 BP_OpenPartition(…);
5 BP_OpenPartition(…);
6 break;
7
BINFS 从第20 开始的,但友善烧NK 却从第39 块开始,想不明白?
第2 块写TOC ,可查看NBOOT 相关代码
2 pToc=(TOC *)malloc(512);//512字节
3 volatile unsigned int dwSector, dwLength; // Start Sector & Length
4 void (*run)(void)=(void (*)(void))(DOWNLOAD_ADDRESS);
5 int dwEntry = 1;
6 pToc->id[dwEntry].dwTtlSectors = dwSectorsNeeded; //这个根据NK.NB0大小,计算出需要多少块
7 pToc->id[dwEntry].dwImageType = 0x2;
8 dwRAM = 0x30200000;
9 pToc->id[dwEntry].dwLoadAddress = 0x80200000;
10 dwSector = 39*256;//NK从第块开始写
11 dwLength = dwSectorsNeeded;
12 pToc->id[dwEntry].sgList[0].dwSector = dwSector;
13 pToc->id[dwEntry].sgList[0].dwLength = dwLength;
14 pToc->dwSignature = TOC_SIGNATURE;
15 pToc->id[dwEntry].dwJumpAddress = 0x8
将TOC 写在第2 块,接下来就把NK.nb0 从第39 块开始写,NK文件太大,不能一次性将其读入内存,可参考如何实现从SD卡更新NK ? 提到的分段读写NK 。
在写NK 时,若遇到坏块,需跳过,检测是否为坏块可调用驱动中的IsBlockBad()
关键代码:
2 DWORD startSectorAdd = 39*256; //起始页
3 LONG lFileToMove=0;
4 for (int j=0; j<FileSize/ReadSize; j++)
5 {
6 DWORD actlen = 0;
7 PCHAR pBuff=NULL;
8 pBuff=(char *)malloc(ReadSize);
9 memset(pBuff,0xFF,ReadSize);
10 SetFilePointer(hFile, lFileToMove, NULL, FILE_BEGIN); //移动文件指针
11 iRet = ReadFile(hFile, pBuff, ReadSize, &actlen, NULL);
12 if (iRet == FALSE)
13 {
14 RETAILMSG(1,(TEXT("Read NB0 File Failed.")));
15 return;
16 }
17 //将数据写入FLash中,每页写512字节
18 int i = 0;
19 while (i < ReadSize/512)
20 {
21 if (startSectorAdd % PAGES_PER_BLOCK == 0)
22 {
23 if (IsBadBlock(hFirm,startSectorAdd/PAGES_PER_BLOCK))
24 {
25 RETAILMSG(1,(TEXT("***** Bad Block %d.\n\r"),startSectorAdd/PAGES_PER_BLOCK));
26 startSectorAdd += PAGES_PER_BLOCK;
27 continue;
28 }
29 }
30
31 iRet = WriteSector(hFirm,startSectorAdd,&pBuff[i*512]);
32 if (iRet == FALSE)
33 {
34 RETAILMSG(1,(TEXT(""Write NB0 File Failed.")));
35 return;
36 }
37 startSectorAdd++;
38 i++;
39 }
40 if(pBuff)
41 {
42 free(pBuff);
43 pBuff = NULL;
44 }
45 lFileToMove += ReadSize;//文件指纹后移
46 if (ReadSize > actlen)
47 {
48 RETAILMSG(1,(TEXT("Break! ")));
49 break;
50 }
51 }
----------------------------------------------------------
尊重他人劳动成果,转载请标明出处http://www.cnblogs.com/feishanm