⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2442loader-1208.c

📁 由三星的2442修改而来,正确引导eboot,请注意用三星公版的硬件配置,具体可以参考QQ2440,因为我在些平台上跑过,具体操作 1.target settings : post-linker:选
💻 C
字号:
/************************************************
 * NAME    : 2442loader.c
 * DESC    : 
 * History : 2002.02.25 ver 0.0
 * rev0.1  : 2003. 05.xx modified for 2442
 * rev0.2  : 2004. 02.xx modified for 2442A(xtal 16.9344MHz)
************************************************/

#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2442addr.h"
#include "2442slib.h"
#include "Nand.h"
//#include "mmu.h"

#define SDRAM_SIZE (64*1024*1024)
#define SDRAM_START 0x30000000
#define VERSION_BAR "\n\nMini(4k) NandBoot V2.0. [2007-09-28]\n\0"

char SDRAM_Test(unsigned int ram_start, unsigned int ram_size);

// Downfile Size, OS Start Address Offset, Core voltage, download address setting
#if 1

   #ifdef DOWNFILE_SIZE
      #define OS_IMAGE_BLOCK_SIZE ( ((DOWNFILE_SIZE/512)/32) +1 )
   #else 
      #define OS_IMAGE_BLOCK_SIZE (0x10)	// blocks
   #endif
   
   #ifndef OS_START_ADDR_OFFSET
      #define	OS_START_ADDR_OFFSET 0x00038000		// 0x3020_0000
   #endif
   //PPC2003 offset	(0x02040000)
   //WINCE	offset	(0x00040000)
   //Firmware offset	(0x00000000)
      
   #ifndef	COREVOLT_M100
   #define	COREVOLT_M100	(130)	// value = voltage(0.8V ~ 1.3V)x100. -> 100->1.0V
   #endif
   
   #define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET)
   
#else
   #define OS_IMAGE_BLOCK_SIZE (0x7b0)	// blocks
   #define	OS_START_ADDR_OFFSET (0x02040000)		// 0x3204_0000
   #define	COREVOLT_M100	(135)	// value = voltage(0.8V ~ 1.3V)x100. -> 100->1.0V
   #define DOWNLOAD_ADDRESS (_RAM_STARTADDRESS+OS_START_ADDR_OFFSET)
#endif

void (*run)(void)=(void (*)(void))(DOWNLOAD_ADDRESS);

void Port_Init(void);
void Led_Display(int);
void Delay(int);

volatile unsigned char *downPt;

void Timer4_Start(void);
void Timer4_Stop(void);
char *hex2char(int val);

void Set_Pre(void);	// for current test
/*
void loadboot(void)
{

	DWORD dwSector, dwLength;         // Start Sector & Length
   DWORD dwRAM, i;
    
	dwSector=64;//从block:2 page:0开始存放eboot
	dwLength=192;//一共6个block;block2-7;96K容量;如果eboot文件大于96K,需要修改该代码
	dwRAM=0x30038000;//eboot load Start address;把NAND FLASH内容拷贝到0X30038000
		
   while (dwLength) {
         FMD_ReadSector(dwSector,(LPBYTE)dwRAM,NULL, 1);
    		dwSector++;
    		dwLength--;
         dwRAM += SECTOR_SIZE;//该程序目前不做校验
   }
        
	Launch(0x30038000);//跳转到eboot,启动eboot,程序不会返回
}*/

void Main(void)
{
   register page, block, blockcopy_count;
   int i, j;
   unsigned short id;
   unsigned char bTemp[4];
   

   
   Port_Init();
   
#if 1
   for(j=3;j;j--) {
         Led_Display(1);
         for(i=100000;i;i--);
         Led_Display(0);
         for(i=100000;i;i--);
   }
#endif  

   Uart_Init(PCLK, 115200);
   Uart_Select(0);
   Uart_SendString(VERSION_BAR);

#if 1
   //SDRAM test...   
   if (!SDRAM_Test(SDRAM_START, SDRAM_SIZE)) {
      Uart_SendString("SDRAM FAIL!");
      for (;;){
          *((volatile unsigned int *)(0x30000000)) = 0xaaaaaaaa;
          *((volatile unsigned int *)(0x33FFFFFF)) = 0x55555555;
      }
   }      

#endif
   
   
   downPt=(unsigned char *)DOWNLOAD_ADDRESS;
  	NF_Init();
#if 0   
   NF_ReadPage(0, 0, (U8*)downPt);
   
   for (i=0; i<512; i++) {
      j = *((U8*)(downPt+i));
      if (!(i%16)) Uart_SendString("\n");
      Uart_SendString( hex2char( (j&0xf0)>>4 ) );
      Uart_SendString( hex2char( j&0x0f ) );
      Uart_SendString(" ");
   }
#endif

   
   // To calculation copy time.
  	Timer4_Start();
	
   /* block 0 放置这个mini boot 和一些参数。
      目标image放置在block1开始的地方。
    */
   block = 0;
  	blockcopy_count=0;
  	while(blockcopy_count<(OS_IMAGE_BLOCK_SIZE)) {		 // Read OS image
      block++;
   	//if(!NF_IsBadBlock(block))  continue;      // Skip bad block

   	blockcopy_count++;
   	for(page=0;page<32;page++) {  // Read 32 page
   		//if(!NF8_ReadPage(block, page, (U8 *)downPt)) {  //(U32 block,U32 page,U32 *buffer)
   		//   Uart_SendString("\nReadPage Fail!");
   		//   while(1);
   	   //}
   		NF_ReadPage(block, page, (U8 *)downPt);
   	  	downPt += 512;	
      }
	}
   Led_Display(3);
 
   Timer4_Stop();

   Set_Pre();
  
	//rCLKCON = (0x0<<16)|(0x6<<12)|(0x9<<8)|(0x2<<4);	// for test
	//Uart_SendString(" Setting CLKCON]\n");

   run();
   for (;;);
   
}


#define TIMER_IINIT_VAL	(0xffff)

void Timer4_Start(void)
{
    Uart_SendString("\n\nNAND Boot Start\n");
    
    rTCFG0=0xff00;		// Prescaler 0xff+1(256)
    rTCFG1=(0x3<<16);	//T4=PCLK period*256*16 = 
    rTCNTB4=TIMER_IINIT_VAL;
    rTCON=(1<<22)|(1<<21);  //Manual update, to validate TCNTB4 value.
    rTCON=(1<<22)|(1<<20);  //Start T4
}

void Timer4_Stop(void)
{
    int cnt;
	
	rTCON=(1<<22)|(0<<20);  //Stop T4
    cnt=TIMER_IINIT_VAL-rTCNTO4;	// actual count number

    Uart_SendString("NAND Boot End\n");
    Uart_SendString("Boot time=nTCNT*82uS. nTCNT=0x");
    Uart_SendString(hex2char((cnt&0xf000)>>12));
    Uart_SendString(hex2char((cnt&0x0f00)>>8));
    Uart_SendString(hex2char((cnt&0x00f0)>>4));
    Uart_SendString(hex2char((cnt&0x000f)>>0));
	Uart_SendString(". \n");
	
}


char *hex2char(int val)
{
    static char str[2];
	
    str[1]='\0';
    if(val<=9)str[0]='0'+val;
    else str[0]=('a'+val-10);
	
    return str;
}

void Set_Pre(void)
{

	int i;

	i = rGPDCON; 

	rGPDCON = (rGPFCON & ~(3<<4)) | (0<<4);
	if((rGPFDAT&(1<<2))==0) {    // If EINT2 key is pressed.
		Uart_SendString("I/O Strength Min\n");
		// Set I/O strength control.
		rDSC0 = (0<<31)|(3<<8)|(3<<0);
		// nEN_DSC  [31]    : 0:I/O drive strength enable, 1:Disable
		// DSC_ADR  [9:8]   : Addr drive strength, 0:10mA, 1:8mA, 2:6mA, 3:4mA
		// DSC_DATA [7:0]   : DATA drive strength, 0:12mA, 1:10mA, 2:8mA, 3:6mA
		
		rDSC1 = (3<<28)|(3<<26)|(0xffffff<<0);
		// DSC_SCK1 [29:28] : SCLK1, 0:16mA, 1:12mA, 2:8mA, 3:6mA 
		// DSC_SCK0 [27:26] : SCLK0, 0:16mA, 1:12mA, 2:8mA, 3:6mA 
		// DSC_SCKE [25:24] : SCLKE, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_SDR  [23:22] : nRAS/nCAS, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_NFC  [21:20] : Nand flash(nFCE,nFRE,nFWE,CLE,ALE), 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_BE   [19:18] : nBE[3:0], 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_WOE  [17:16] : nBE[3:0], 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS7  [15:14] : nGCS7, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS6  [13:12] : nGCS6, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS5  [11:10] : nGCS5, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS4  [9:8]   : nGCS4, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS3  [7:6]   : nGCS3, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS2  [5:4]   : nGCS2, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS1  [3:2]   : nGCS1, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
		// DSC_CS0  [1:0]   : nGCS0, 0:10mA, 1:8mA, 2:6mA, 3:4mA 
	} else {

		Uart_SendString("I/O Strength Max\n");
		// Set I/O strength control.
		rDSC0 = (0<<31)|(0<<8)|(0<<0);
		rDSC1 = (0<<28)|(0<<26)|(0x000000<<0);
	}
	rGPDCON = i;
}

char SDRAM_Test(unsigned int ram_start, unsigned int ram_size)
{
   unsigned int i;
   
   // step 1.
   for (i=0; i<ram_size; i+=0x1000) {
       *( (volatile unsigned int *)(ram_start+i) ) = 0xaaaaaaaa;
   }
   //memset((char*)ram_start, 0xaa, ram_size);
   
   for (i=0; i<ram_size; i+=0x1000) {
      if ( *( (volatile unsigned int *)(ram_start+i) ) != 0xaaaaaaaa ) {
         return 0;
      }
   }
   
   // step 2.
   for (i=0; i<ram_size; i+=0x1000) {
       *( (volatile unsigned int *)(ram_start+i) ) = 0x55555555;
   }
   //memset((char*)ram_start, 0x55, ram_size);
   
   for (i=0; i<ram_size; i+=0x1000) {
      if ( *( (volatile unsigned int *)(ram_start+i) ) != 0x55555555 ) {
         return 0;
      }
   }
   
   memset((char*)ram_start, 0x00, ram_size);
   
   return 1;   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -