Nboot程序详细分析

来源:互联网 发布:淘宝店铺直播怎么开通 编辑:程序博客网 时间:2024/06/03 13:20


      主要包含以下文件:

2410init.s 2410slib.s nand_s.s 2410loader.c 2410lib.c nand.c

      其中最重要的是2410init.s和2410loader.c。

      2410init.s是汇编程序,所作的工作有:屏蔽所有中断、设置CPU的速度和时钟频率、RAM的初始化、LED的初始化等。

      2410loader.c是C语言程序,下面着重介绍。

      首先,入口程序main():

void Main(void) {        DWORD err;          DWORD dwEntry = 0;        //定义入口方式,是直接进入WinCE内核,还是启动Eboot          MMU_EnableICache();         //MMU_Cache On          Uart_Init();            //初始化串口        Uart_SendString(SIGN_ON);            //打印启动信息          NF_Init();              //初始化Nand Flash          Uart_SendString("\ndwEntry is ");        Uart_SendDWORD(dwEntry, TRUE);          err = ReadImageFromNand(dwEntry,0); //读TOC信息、将Image写入内存等         if (ERR_SUCCESS == err) {            Uart_SendString("\nDone!");            Uart_SendDWORD(JumpAddr, TRUE);             Launch(JumpAddr);      //执行指定地址的程序(RAM中,物理地址)            err = ERR_JUMP_FAILED;        }          Uart_SendString("\nBoot ERROR:");        Uart_SendDWORD(err, TRUE);       while (1);   } 
  1.     里面重要的有两个程序Uart_Init()和ReadImageFromNand()。

    先来看Uart_Init():

//***************************[ UART ]******************************   void Uart_Init(void)   {       int i;         rUFCON0 = 0x0;      // FIFO disable       rUMCON0 = 0x0;      // AFC disable         rULCON0 = 0x3;      // Normal,No parity,1 stop,8 bits       rUCON0   = 0x245;                 rUBRDIV0=( (int)(PCLK/16./BAUD_RATE) -1 );         for(i=0;i<100;i++);          }  //***************************[ UART ]****************************** void Uart_Init(void) { int i; rUFCON0 = 0x0; // FIFO disable rUMCON0 = 0x0; // AFC disable rULCON0 = 0x3; // Normal,No parity,1 stop,8 bits rUCON0 = 0x245; rUBRDIV0=( (int)(PCLK/16./BAUD_RATE) -1 ); for(i=0;i<100;i++); }

       注意其中的rUFCON0、rUMCON0等参数里的数字0,这代表初始化的是UART0端口,而所有的打印输出也是向UART0的,所以在计算机上用超级终端监控时,串口一定要接到UART0上。

      接下来是最重要的ReadImageFromNand():

DWORD ReadImageFromNand(DWORD dwEntry, DWORD dwSig)   {        DWORD dwSectorsNeeded;        DWORD dwSector, dwLength;         // Start Sector & Length        DWORD dwRAM, i;          Uart_SendString("TOC_SECTOR: \n");        Uart_SendDWORD(TOC_SECTOR,TRUE);          //读TOC内容,确定拷贝Image所需空间、拷贝的起始地址、跳转位置等信息        if ( !FMD_ReadSector(TOC_SECTOR,(LPBYTE)&toc,NULL, 1) )        {            Uart_SendString("ERR_DISK_OP_FAIL1\n");           return ERR_DISK_OP_FAIL1;        }          //验证TOC是否合法        if ( !VALID_TOC(&toc) ) {            Uart_SendString("ERR_INVALID_TOC: ");            Uart_SendDWORD(toc.dwSignature, TRUE);           return ERR_INVALID_TOC;        }          //拷贝到RAM的Image所占的Page        dwSectorsNeeded = toc.id[dwEntry].dwTtlSectors;               Uart_SendString("Sector addr on NAND: ");        Uart_SendDWORD(toc.id[dwEntry].sgList[0].dwSector, TRUE);        Uart_SendString("TotalSector: ");        Uart_SendDWORD(dwSectorsNeeded, TRUE);          //dwRAM:拷贝Image到RAM的起始地址        //JumpAddr:拷贝完成后的执行程序地址        dwRAM = VIRTUAL_TO_PHYSICAL(toc.id[dwEntry].dwLoadAddress);        JumpAddr = VIRTUAL_TO_PHYSICAL(toc.id[dwEntry].dwJumpAddress);          // 将Image拷贝到RAM中        i = 0;        while (dwSectorsNeeded && i < MAX_SG_SECTORS)        {            dwSector = toc.id[dwEntry].sgList[i].dwSector;            dwLength = toc.id[dwEntry].sgList[i].dwLength;           // read each sg segment           while (dwLength) {                 if ( !FMD_ReadSector(dwSector,                                    (LPBYTE)dwRAM,                                    NULL, 1) )                {                    Uart_SendString("ERR_DISK_OP_FAIL2: ");                    Uart_SendDWORD(dwSector, TRUE);                      dwSector++;                   continue;                }                               dwSector++;                dwLength--;                dwRAM += SECTOR_SIZE;            }              dwSectorsNeeded -= toc.id[dwEntry].sgList[i].dwLength;            i++;        }          return ERR_SUCCESS;   } 
  1.        里面有一个函数FMD_ReadSector(),它的功能是读取一个Page的内容到RAM中,里面调用的是一个汇编程序__RdPage512。

       等ReadImageFromNand()程序成功返回后,由Launch(JumpAddr)调用一个汇编程序,执行RAM指定地址的程序。

    2009-10-19                   

    注:源自原百度博客“至美心"

                                             
0 0
原创粉丝点击