单片机
返回首页

NBOOT分析-NBOOT.c(2)

2016-12-31 来源:eefocus

/*
---------------------------------------------------------------
文件名称: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;
}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

最新器件
精选电路图
  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 离子检测器电路分析

  • 非常简单的150W功放电路图

  • 一个简单的警笛电路图

  • 优化电路板布局的简单方法

  • 使用NE555和磁簧开关的橱柜照明电路

    相关电子头条文章