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 。

 

1 case 0xFF44:   
2 BP_Init(…);   
3 BP_LowLevelFormat(…);   
4 BP_OpenPartition(…);   
5 BP_OpenPartition(…);   
6 break;   
7 

  BINFS 从第20 开始的,但友善烧NK 却从第39 块开始,想不明白?
  第2 块写TOC ,可查看NBOOT 相关代码

代码
 1 TOC *pToc = NULL;   
 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()

  关键代码:

 

代码
 1 DWORD ReadSize = 30*1024;   //每次读取30K文件   
 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

 

 

 

posted @ 2010-08-14 12:32  mike_fei  阅读(942)  评论(0编辑  收藏  举报