欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

2410loader.c

2410 boot loader,usb ftp
C
第 1 页 / 共 2 页
字号:
/************************************************
 * NAME    : 2410loader.C			            *
 * DESC    : 					                *
 * History : 2002.02.25 ver 0.0			        *
************************************************/

#include <stdlib.h>
#include <string.h>
#include "option.h"
#include "def.h"
#include "2410addr.h"
#include "2410slib.h"
#include "2410addr.h"
#include "k9s1208.h"
#include "mmu.h"
#include "2410loader.h"
#include "tftpnaive/tftpnaive.h"
#include "tftpnaive/net.h"

extern char Image$$RO$$Base[];

#define BOOTLOADER_RAM_ADDRESS (U32)Image$$RO$$Base
#define LED_ON	0xa
#define LED_OFF	0x0
#define OS_IMAGE_SIZE (2048)


void (*run)(void);
void Port_Init(void);
void Led_Display(int);
void Delay(int);
void ResetSystem(void);
void DefaultConfig(void);
void ShowConfig(void);
int  DownloadImage(U32 addr);

volatile unsigned char *downPt;
volatile U32 downloadAddress;
volatile U32 downloadStartBlock;

void LoadAndRunImage(void);
void DownloadAndRunImage(void);
char *hex2char(int val);
char str2hex(char *str);
void dispmac(char *mac);
int  setmac(void);
int  setip(unsigned int *ipaddr, char *message);
void disphex(long val);
void hexdump(char *buf, long len);
void Loader_Menu(void);
void  call_linux(long a0, long a1, long a2);

void ShowLinuxPartition(void);
void ModifyLinuxMTDName(void);
void UpdateLinuxPartition(void);
void ModifyLinuxPartition(void);
void DefaultLinuxPartition(void);
void LinuxPartitionString(char *str);

static LOADER_CONFIG	lcf;


void Main(void)
{
    register i,j;

    
    MMU_EnableICache();
#if ADS10   
    __rt_lib_init(); //for ADS 1.0
#endif
    
    ChangeClockDivider(1,1);	      // 1:2:4
    //ChangeMPllValue(0x5c,0x4,0x0);  //Fin=12MHz FCLK=200MHz
    ChangeMPllValue(0x5c,0x1,0x1);    // FCLK=200MHz
    //ChangeMPllValue(82,1,1);        //FCLK=180.0Mhz  
        
    Port_Init();

    Uart_Init(PCLK, 115200);
    //Uart_Init2(0, 115200);

    // Configuration load    
    CFG_READ(&lcf);
    if(lcf.magic!=SYS_MAGIC)
     DefaultConfig();

    Uart_Printf("\n\n\nS3C2410 Loader Build Date: %s [%d]\n\n", __DATE__, __ARMCC_VERSION);
	Uart_SendString("Hold any key before this message to enter menu mode!!\n\n");
    Uart_SendString("Bootloader Start 0x");
    disphex(BOOTLOADER_RAM_ADDRESS);
    Uart_SendString("\n");
    
    // Sense keyin
    if(Uart_GetAnyKey())
     Loader_Menu();
    else
    {
     if(lcf.bootdown&SYS_BOOT_MENU)
      Loader_Menu();
     else if(lcf.bootdown&SYS_BOOT_FLASH)	
      LoadAndRunImage();
     else if(lcf.bootdown&SYS_BOOT_DOWNLOAD)
      DownloadAndRunImage();
     else
     {
      Uart_Printf("Please clear setting, configuration is invalid!!!!\n");
      while(1);	
     }
    }    	       	
  
}

char dischar[]="*|/-";

void LoadAndRunImage(void)
{
    register i,j;
    int jumpPt;
	struct param_struct *pa;

    
    MMU_EnableICache();
    
#if ADS10   
    __rt_lib_init(); //for ADS 1.0
#endif
    
    if(lcf.systype==SYS_LINUX)
    {
     // Setup configuration
     pa = (struct param_struct *)lcf.cfgaddr;	
     memset(pa, 0, sizeof(struct param_struct));
     pa->u1.s.page_size = 0x00001000;
     pa->u1.s.nr_pages = (0x04000000>>12);
     memcpy(pa->commandline, lcf.cmd, strlen(lcf.cmd)+1);
     LinuxPartitionString(pa->commandline+strlen(lcf.cmd));        	   	
    }
    else if(lcf.systype==SYS_WINCE)
    {
     run = (void (*)(void))(lcf.ramaddr);
    }
    else
    {
     Uart_SendString("\nUnknown kernel image, please update kernel!!\n");
     while(1);	
    }

    
    downPt=(unsigned char *)(lcf.ramaddr);
    jumpPt = (int)downPt;

    NF_Init();
    
       	       	
    Uart_Printf("Loading %s to 0x", (lcf.systype==SYS_LINUX)?"Linux kernel":"WinCE image"); 
    disphex((int)downPt);
    Uart_SendString("... "); 
      	       	
       	
    j=DOWN_KERNEL_START_BLOCK-1;
    Uart_Printf("%c", dischar[j%4]);
     
    while(j<(lcf.imgblk+DOWN_KERNEL_START_BLOCK))	    // Read 1~807 block(13635072B) for WinCE image
    {
	j++;
	Led_Display(j%16);
	Uart_Printf("\b%c", dischar[j%4]);
	for(i=0;i<32;i++)   // Read 32 page
	{		
	    if(!NF_ReadPage(j, i, (U8 *)downPt))  //(U32 block,U32 page,U8 *buffer)
	    {
		if(i!=0)
		{
		    Led_Display(0x8);   // real ECC Error
		    while(1);
		}
		break;		    // ECC error is considered as a bad block.
	    }
  	    downPt += 512;	    // Next page
	}
    }

    Uart_SendString("\n"); 
    
    
    if(lcf.systype==SYS_LINUX)
     call_linux(0, SYS_LINUX, jumpPt);
    else
     run();
		
}

void DownloadAndRunImage(void)
{
    register i,j;
    int jumpPt;
	struct param_struct *pa;
	int retry=5;

    
    MMU_EnableICache();
    
#if ADS10   
    __rt_lib_init(); //for ADS 1.0
#endif
    
    
    if(lcf.systype==SYS_LINUX)
    {
     // Setup configuration
     pa = (struct param_struct *)lcf.cfgaddr;	
     memset(pa, 0, sizeof(struct param_struct));
     pa->u1.s.page_size = 0x00001000;
     pa->u1.s.nr_pages = (0x04000000>>12);
     memcpy(pa->commandline, lcf.cmd, strlen(lcf.cmd)+1);
     LinuxPartitionString(pa->commandline+strlen(lcf.cmd)-1);	   	
    }
    else if(lcf.systype==SYS_WINCE)
    {
     run = (void (*)(void))(lcf.ramaddr);
    }
    else
    {
     Uart_SendString("\nUnknown kernel image, please update kernel!!\n");
     while(1);	
    }

    
    downPt=(unsigned char *)(lcf.ramaddr);
    jumpPt = (int)downPt;

down_retry:    
    if(DownloadImage(lcf.ramaddr))
    {
      if(retry)
      {
      	Uart_Printf("Download failed, retry...\n");
      	retry--;
      	goto down_retry;
      }
      else
      {
      	Uart_Printf("Unable to download image....\n");
      	while(1);
      }
    }
    
    Uart_Printf("\n");
    
    if(lcf.systype==SYS_LINUX)
     call_linux(0, SYS_LINUX, jumpPt);
    else
     run();
		
}



void  call_linux(long a0, long a1, long a2){	//cache_clean_invalidate();	//tlb_invalidate();__asm {	 mov	r0, a0	 mov	r1, a1	 mov	r2, a2	 mov	ip, #0	 mcr	p15, 0, ip, c13, c0, 0	/* zero PID */	 mcr	p15, 0, ip, c7, c7, 0	/* invalidate I,D caches */	 mcr	p15, 0, ip, c7, c10, 4	/* drain write buffer */	 mcr	p15, 0, ip, c8, c7, 0	/* invalidate I,D TLBs */	 mrc	p15, 0, ip, c1, c0, 0	/* get control register */	 bic	ip, ip, #0x0001			/* disable MMU */	 mcr	p15, 0, ip, c1, c0, 0	/* write control register */	 //mov	pc, r2	 nop	 nop    }
    run=(void (*)(void))(a2);
    run();}


void Loader_Menu(void)
{
  extern U32 downloadFileSize;
  char cmd[COMMAND_LINE_SIZE+1]; 	
  U8 key;
  static U8 first=1;
 
again:
        Uart_Printf("\n\n########## Select Menu ###########\n");
        Uart_Printf(" [1] Boot Mode [%s]\n", (lcf.bootdown&SYS_BOOT_FLASH)?"Flash":(lcf.bootdown&SYS_BOOT_DOWNLOAD)?"Download":"Menu");
        Uart_Printf(" [2] Download Mode [%s]\n", (lcf.bootdown&SYS_DOWNLOAD_USB)?"USB":"NET");
        Uart_Printf(" [3] Update Bootloader\n");
        Uart_Printf(" [4] Update Kernel/Partition [%s]\n", (lcf.systype==SYS_LINUX?"Linux":(lcf.systype==SYS_WINCE?"WinCE":"None")));
        Uart_Printf(" [5] Show Setting\n");
        Uart_Printf(" [6] Default Setting\n");
        Uart_Printf(" [7] Reset\n");

   // suck user's keys
   if(first)
   {
     Uart_RecvUntilNoKey();
     first = 0;
   }
    
   key = Uart_Getch();
   
   switch(key)
   {
   			  
   	case '1': //Uart_Printf("Current Boot From %s\n", (lcf.bootdown&SYS_BOOT_FLASH)?"Flash":"Download"); 
bootmode_again: 	      
   	      Uart_SendString("\n\n###### Select Menu ######\n");
              Uart_SendString(" [1] Flash\n");
              Uart_SendString(" [2] Download\n");
              Uart_SendString(" [3] Menu\n");
              Uart_SendString(" [4] Exit\n");
   			  key = Uart_Getch();
   			   switch(key)
   			   {
   	
   			   	case '1': lcf.bootdown &= ~(SYS_BOOT_FLASH|SYS_BOOT_DOWNLOAD|SYS_BOOT_MENU);
   			   	          lcf.bootdown |=  (SYS_BOOT_FLASH);
   			   	          CFG_WRITE(&lcf); // Write configuration
   			   	          break;
   			   	case '2': lcf.bootdown &= ~(SYS_BOOT_FLASH|SYS_BOOT_DOWNLOAD|SYS_BOOT_MENU);
   			   	          lcf.bootdown |=  (SYS_BOOT_DOWNLOAD);
   			   	          CFG_WRITE(&lcf); // Write configuration    
   			   	          break;
   			   	case '3': lcf.bootdown &= ~(SYS_BOOT_FLASH|SYS_BOOT_DOWNLOAD|SYS_BOOT_MENU);
   			   	          lcf.bootdown |=  (SYS_BOOT_MENU);
   			   	          CFG_WRITE(&lcf); // Write configuration       			   	          
   			   	          break;
   			   	case '4': break;
   			   	default: goto bootmode_again;
   			   }             			   	                   			   		      
   		      break;

   	case '2': //Uart_Printf("Current Download Through %s\n", (lcf.bootdown&SYS_DOWNLOAD_USB)?"USB":"NET"); 
downmode_again: 	      
   		      Uart_SendString("\n\n###### Select Menu ######\n");
              Uart_SendString(" [1] USB\n");
              Uart_SendString(" [2] NET\n");
              Uart_SendString(" [3] Exit\n");
   			  key = Uart_Getch();
   			   switch(key)
   			   {
   	
   			   	case '1': lcf.bootdown &= ~(SYS_DOWNLOAD_USB|SYS_DOWNLOAD_ETH);
   			   	          lcf.bootdown |=  (SYS_DOWNLOAD_USB);
   			   	          CFG_WRITE(&lcf); // Write configuration
   			   	          break;
   			   	case '2': 
tftp_again:   			   		
   		                  Uart_SendString("\n\n###### Select Menu ######\n");
                          Uart_SendString(" [1] BOOTP + TFTP\n");
                          Uart_SendString(" [2] TFTP\n");
                          Uart_SendString(" [3] Exit\n");   			   		
   			   			  key = Uart_Getch();
  			   				switch(key)
   			   				{
   			   			      case '1': setmac();	   			      			
   			   			      			lcf.bootdown |= SYS_DOWNLOAD_ETH_BOOTP;
   			   			      			break;
   			   			      			
   			   			      case '2': setmac();
   			   			      			setip(&lcf.rmip, "TFTP Server ");
   			   			      			setip(&lcf.loip, "Local ");
   			                            Uart_Printf("Current filename %s\n", lcf.file);
   			  							Uart_Printf("Input: ");
   			  							Uart_RecvString(cmd, COMMAND_LINE_SIZE);
   			  							if(strlen(cmd))
   			   							 memcpy(lcf.file, cmd, strlen(cmd)+1);
   			   			      			lcf.bootdown |= SYS_DOWNLOAD_ETH_TFTP;
   			   							break;	      			
   			   			      case '3': goto again;
   			   			      default: goto tftp_again;
   			   			    }
   			   			  lcf.bootdown &= ~(SYS_DOWNLOAD_USB|SYS_DOWNLOAD_ETH);
   			   	          lcf.bootdown |=  (SYS_DOWNLOAD_ETH);
   			   	          CFG_WRITE(&lcf); // Write configuration    
   			   	          break;
   			   	case '3': break;
   			   	default: goto downmode_again;
   			   }             			   	                   			   		      
   		      break;
   		      		  
   	case '3': DownloadImage(DOWN_RAM_ADDR); 
   			  if((downloadFileSize/BLOCK_SIZE)>=DOWN_KERNEL_START_BLOCK)
   			   Uart_SendString("\nWarning!!! Image too big, write image will overwrite kernel...\n");
ask_loader_again:
   	          Uart_SendString("\nDownload finish, write to flash? [Y/N] ");
   	          key = Uart_Getch();
   	          if(key=='y' || key=='Y')
   	           u241test_easy(DOWN_LOADER); 
   	          else if(key!='n' && key!='N')
   	           goto ask_loader_again; 
   	          break;
   	case '4': 
kernel_again: 	      
   	      Uart_SendString("\n\n######### Select Menu #########\n");
              Uart_SendString(" [1] WinCE Image\n");
              Uart_SendString(" [2] Linux Kernel\n");
              Uart_SendString(" [3] Linux Command Line\n");
              Uart_SendString(" [4] Linux Partition Configure\n");
              Uart_SendString(" [5] Linux Partition Update\n");
              Uart_SendString(" [6] Exit\n");
   			  key = Uart_Getch();
   			   
   			   switch(key)
   			   {
  
     			   	case '1': memcpy(lcf.cmd, CMD_WINCE, strlen(cmd)+1);
    			   		  lcf.systype = SYS_WINCE;
   			   		      lcf.ramaddr = RAM_WINCE;
   			   		      lcf.cfgaddr = CFG_WINCE;  			   				
   			   		      break;
   			   		       	
   			   	case '2': 
   			   	#if 0	
   			   		  Uart_Printf("Linux %s kernel command: [Press Enter to use this command]\n", (strlen(lcf.cmd)>0)?"current":"default");
   			   	          Uart_Printf("%s\n", (strlen(lcf.cmd)>0)?lcf.cmd:CMD_LINUX);
   			   	          Uart_Printf("Input: ");
   			   	          Uart_RecvString(cmd, COMMAND_LINE_SIZE);
   			   	          if(strlen(cmd))
   			   	           memcpy(lcf.cmd, cmd, strlen(cmd)+1);
   			   		  else if(strlen(lcf.cmd)==0)
   			   		   memcpy(lcf.cmd, CMD_LINUX, strlen(CMD_LINUX)+1);
   			   	#endif	   
   			   		  lcf.systype = SYS_LINUX;
   			   		  lcf.ramaddr = RAM_LINUX;
   			   		  lcf.cfgaddr = CFG_LINUX;
   			   		  CFG_WRITE(&lcf); // Write configuration
   			   		  goto again;
   			   		       

   			   		
   			   	case '3':
				     if(lcf.systype!=SYS_LINUX)
   			             {
   			                    Uart_Printf("\n\nCurrent configuration is not for Linux kernel!!\n");
   			                    goto again;
   			             }   			   		 
   			   	      Uart_SendString("\nCurrent Linux kernel command: [Press Enter to use current command]\n");
   			              Uart_Printf("%s\n", lcf.cmd);
   			              Uart_Printf("Input: ");
   			              Uart_RecvString(cmd, COMMAND_LINE_SIZE);
   			              if(strlen(cmd))
   			              {
   			               memcpy(lcf.cmd, cmd, strlen(cmd)+1);
   			               CFG_WRITE(&lcf); // Write configuration
   			              }   			  
   			              goto again;  
   			              
   			        case '4': if(lcf.systype!=SYS_LINUX)
   			                  {
   			                    Uart_Printf("\n\nCurrent configuration is not for Linux kernel!!\n");
   			                    goto again;
   			                  }
   			                  else
   			                    Uart_SendString("\n");
   			        	  ModifyLinuxMTDName();
   			        	  Uart_Printf("\n");
   			                  ModifyLinuxPartition();
   			                  CFG_WRITE(&lcf); // Write configuration
   			                  goto again;
   			       
   			        case '5': if(lcf.systype!=SYS_LINUX)
   			                  {
   			                    Uart_Printf("\n\nCurrent configuration is not for Linux kernel!!\n");
   			                    goto again;
   			                  }
   			                  else
   			                    Uart_SendString("\n");
   			        	  ShowLinuxPartition();
   			        	  Uart_Printf("\n");
   			        	  UpdateLinuxPartition();
   			        	  goto again;           
   			              			 		
   			        case '6': goto again;
   			    default: goto kernel_again;
			   }

              if(lcf.bootdown&SYS_BOOT_FLASH)
              {
   			    DownloadImage(DOWN_RAM_ADDR);
   			    lcf.imgblk = (((downloadFileSize/(0x4000))*(0x4000))+((downloadFileSize%(0x4000))?(0x4000):0))/BLOCK_SIZE; 
ask_kernel_again:
   	            Uart_SendString("\nDownload finish, write to flash? [Y/N] ");
   	            key = Uart_Getch();
   	            if(key=='y' || key=='Y')
   	            {

⌨️ 快捷键说明

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