×
单片机 > 单片机程序设计 > 详情

NBOOT分析-NBOOT.c(2)

发布时间:2020-06-16 发布时间:
|

/*
---------------------------------------------------------------
文件名称:NBOOT.c
说    明:进行Nand Bootloader操作
---------------------------------------------------------------
*/
#include "S3C244x.h"
#include "UART.h"
#include "Global.h"
#include "TOC.h"
#include "Nand.h"
#include "MMU.h"


#define TOC_BLOCK                   (2)  //TOC占用2块

#define SECTOR_SIZE                    512  //页大小:512字节
#define SECTOR_PER_BLOCK            256  //每块含有多少页

/******************************************************
*文件名称:ReadNandImageToRam
*输    入:unEntry 进入点
*输    出:WINCE镜像跳转地址
         0为无效
*功能说明:从NAND FLASH加载WINCE镜像到SDRAM
*******************************************************/
UINT32 ReadNandImageToRam(UINT32 unEntry)
{
   UINT32 unSectorsNeeded;
   UINT32 unSector,unLength;
   UINT32 unRam,i;

   
   PTOC   pTOC=(PTOC)0x33F00000;//若用TOC类型定义,不需要自行赋给地址
                                //若用PTOC类型定义,编译器给予pTOC变量地址是未知的
                                //因此要强制赋给其地址
   NandReadSector(TOC_BLOCK*SECTOR_PER_BLOCK,(UINT8 *)pTOC);//读取第512扇区内容,并赋给TOC
   
   if(!TOCIsValid(pTOC))
   {
      DEBUGMSG("\r\nTOC is not valid\r\n");
      return 0;
   }
   DEBUGMSG("\r\nTOC is valid\r\n");
   //参数dwEntry 定义入口方式,是直接进入WinCE内核,还是启动Eboot
   if(!(pTOC->id[unEntry].dwImageType &IMAGE_TYPE_RAMIMAGE))
   {
      return 0;
   }
   
   DEBUGMSG("\r\nImage is RamImage\r\n");
   
   unSectorsNeeded= pTOC->id[unEntry].dwTtlSectors;           //镜像占用的扇区总数
   unRam=VIRTUAL_TO_PHYSICAL(pTOC->id[unEntry].dwLoadAddress);//虚拟地址转变为物理地址
   
   DEBUGMSGEx("\r\nSectors Total=",pTOC->id[unEntry].dwTtlSectors ,10);
   DEBUGMSGEx("\r\nVirtual  Load Address =",pTOC->id[unEntry].dwLoadAddress,16);
   DEBUGMSGEx("\r\nPhysical Load Address =",unRam,16);
   
   i=0;
   
   while(unSectorsNeeded && i    {
       unSector = pTOC->id[unEntry].sgList[i].dwSector;
       unLength = pTOC->id[unEntry].sgList[i].dwLength;  
       
       while(unLength)
       {
         if(unSector % SECTOR_PER_BLOCK == 0)//256页检查一次坏块
         {
           if(!NandCheckBadBlock(unSector/SECTOR_PER_BLOCK))
           {
              unSector+=SECTOR_PER_BLOCK;//存在坏块
             
              continue;//不进行下面的操作
           }
           
           DEBUGMSG(".");
         }
         
         if(!NandReadSector(unSector,(UINT8 *)unRam))
         {
            DEBUGMSG("\r\nCan't Load WINCE Image\r\n");
            while(1);
         }
         
         unSector++;
         unLength--;
         
         unRam+=SECTOR_SIZE;
       }  
       
       unSectorsNeeded-=pTOC->id[unEntry].sgList[i].dwLength;    
       i++;

   }
 
   return (pTOC->id[unEntry].dwJumpAddress?VIRTUAL_TO_PHYSICAL(pTOC->id[unEntry].dwJumpAddress) ://获取加载镜像完成后的跳转地址
                                           VIRTUAL_TO_PHYSICAL(pTOC->id[unEntry].dwLoadAddress));
}

void PORTInit(void)
{

   rGPACON = 0x7fffff;
   rGPDCON = 0xaaaaaaaa;      
   rGPDUP  = 0xffff;     // The pull up function is disabled GPD[15:0]
   rGPECON = 0xaaaaaaaa;      
   rGPEUP  = 0xffff;    

   rGPFUP  = 0xff;    

   rGPGCON = 0xFD000000;
   rGPGUP  = 0xffff;  

   rGPHCON = 0x02faaa;

   rGPHUP  = 0x7ff;  
   
   rEXTINT0 = 0x22222222;    // EINT[7:0]
   rEXTINT1 = 0x22222222;    // EINT[15:8]
   rEXTINT2 = 0x22222222;    // EINT[23:16]
   
}
#define BSP_ARGS_ADDR               0x30020800
#define BSP_ARGS_SIZE               0x800

/*
ARGS内存空间的注解
在WINCE的EBOOT中
ARGS  80028000 00000800 RESERVED
自0x80028000处,大小为0x00000800的空间被命名为ARGS,这个空间类型为
RESERVED,用于保存Bootloader和操作系统之间的共享数据

总之在0x30020800地址处必须要对其进行初始化为0,否则WINCE不能够正常激活
以下选自2440的BSP上的代码。

在BSP中,boot loader和OAL之间有一些数据可以共享
这段数据被存放在(BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START这块内存里。
#define IMAGE_SHARE_ARGS_UA_START      0xA0020000
#define IMAGE_SHARE_ARGS_CA_START      0x80020800
#define IMAGE_SHARE_ARGS_SIZE          0x00000800
可以看出来,IMAGE_SHARE_ARGS_UA_START指向的是虚拟内存中的Uncached段,而IMAGE_SHARE_ARGS_CA_START指向虚拟内存中的Cached段。
我的g_oalAddressTable中这样定义:
DCD    0x80000000, 0x30000000, 64      ; 32 MB DRAM BANK 6
因此,它们分别是指向物理地址0x30020000和0x30020800。

然后看config.bib中,可以看到有这段定义:
; Common RAM areas
   AUD_DMA            80002000  00000800  RESERVED
   SDIO_DMA           80010000  00010000  RESERVED
   ARGS               80020800  00000800  RESERVED
   DBGSER_DMA         80022000  00002000  RESERVED
   SER_DMA            80024000  00002000  RESERVED
   IR_DMA             80026000  00002000  RESERVED
   SLEEP              80028000  00002000  RESERVED
   EDBG               80030000  00020000  RESERVED
   DISPLAY            80100000  00100000  RESERVED  

其中ARGS对应的物理地址的0x30020800是为IMAGE_SHARE_ARGS_CA_START保留的吧。
*/



int Main(void)
{
 void (*RunWINCE)(void)=0;
 
 MMUEnableICache();
 MMUEnableDCache();
 PORTInit(); //IO口一定要初始化,否则串口不能正常工作
 UARTInit(S3C2440PCLK,115200);
 NandInit();
 DEBUGMSGEx("\r\n\r\nPhysical BSPArgs Address = ",BSP_ARGS_ADDR,16);
 DEBUGMSGEx("\r\nBSPArgs Size = ",BSP_ARGS_SIZE,16);
 DEBUGMSG("\r\nClearing BSPArgs Memory\r\n");
 BufClr((char*)BSP_ARGS_ADDR, BSP_ARGS_SIZE);//关于pBSPArgs的地址与长度需要根据BSP包进行确定的
 DEBUGMSG("\r\nLoading WINCE\r\n");
 RunWINCE=(void(*)(void))ReadNandImageToRam(1);
 DEBUGMSGEx("\r\nPhysical Jump Address =",(UINT32)RunWINCE,16);
 DEBUGMSGEx("\r\n Virtual Jump Address =",PHYSICAL_TO_VIRTUAL((UINT32)RunWINCE),16);
 
 if(RunWINCE)
 {
    DEBUGMSG("\r\nLoad WINCE Successfully\r\n");
    RunWINCE();
 }
 
 while(1);

 return 0;
}

关键字:NBOOT分析  NBOOT.c 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈msp430f5529入门(2)----时钟配置.例程分析