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

📄 2410loader.c

📁 2410 boot loader,usb ftp
💻 C
📖 第 1 页 / 共 2 页
字号:
   	             u241test_easy(DOWN_KERNEL);
   	             CFG_WRITE(&lcf); // Write configuration 
   	            }
   	            else if(key!='n' && key!='N')
   	             goto ask_kernel_again;
   	      }
   	      else
   	        CFG_WRITE(&lcf); // Write configuration 
   	             
   	          break;

   	case '5': ShowConfig();
   			  goto again;
   			  break;
   	          
   	case '6': DefaultConfig();
   			  goto again;
   			  break;
   			  
   	case '7': ResetSystem();
   	          while(1);
   	          	          
   }      	

   goto again;	
}

#define WATCHDOG_TIME	(128)	// [usec], Max=65535*128us.

void ResetSystem(void)
{	
  rWTCON = (1<<8) | (1<<5) | (1<<0);	
//	rWTCON = ((PCLK/1000000-1)<<8) | (3<<3) | 1<<2 | 1<<0;  //Prescaler=0x31(49),Clock division 128,Reset enable
//	rWTDAT = WATCHDOG_TIME/128;
//	rWTCNT = WATCHDOG_TIME/128; // (xsec/128us)
//	rWTCON = rWTCON | (1<<5);   //Watch-dog timer enable   
}

int DownloadImage(U32 addr)
{
  if(lcf.bootdown&SYS_DOWNLOAD_USB)
   return u241mon_easy(addr);
  else
  {
   TFTPDownload tftp;
   tftp.mode = (lcf.bootdown >> 6) & 0x3;
   tftp.local_ip = lcf.loip;
   tftp.remote_ip = lcf.rmip;
   tftp.downaddr = addr;
   memcpy(tftp.mac, lcf.mac, 6);
   strcpy(tftp.file, lcf.file);
   return tftpnaive(&tftp);
  }		 
}

void DefaultConfig(void)
{
      memset(&lcf, 0, sizeof(LOADER_CONFIG));
      lcf.magic = SYS_MAGIC;
      lcf.bootdown = SYS_BOOT_FLASH | SYS_DOWNLOAD_USB;
      memcpy(lcf.mac, SYS_MAC_ADDR, 6);
      lcf.loip = SYS_DFT_LOIP;
      lcf.rmip = SYS_DFT_RMIP;
      strcpy(lcf.file, SYS_BOOT_FILE);
      memcpy(lcf.cmd, CMD_LINUX, strlen(CMD_LINUX)+1);
      DefaultLinuxPartition();
      CFG_WRITE(&lcf);
}

void hexdump(char *buf, long len)
{
  long idx, val;
  
  for(idx=0; idx<len; idx++)	
  {
  	if(idx%16==0)
  	{
  	 Uart_SendString("\n");
  	 disphex(idx);
  	 Uart_SendString(": ");
  	}

    Uart_SendString(hex2char((buf[idx]&0xf0)>>4));
    Uart_SendString(hex2char((buf[idx]&0x0f)>>0));    
    Uart_SendString(" ");	  	  	
  }
  
}

void dispmac(char *mac)
{
	Uart_Printf("%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], 
												 mac[3], mac[4], mac[5]);	
}

int setmac(void)
{
  char cmd[COMMAND_LINE_SIZE+1]; 	
  	
	Uart_Printf("\nCurrent MAC: ");
	dispmac((char *)lcf.mac);
    Uart_Printf("\nExample: 001122334455\n");
    Uart_Printf("Input: ");
    Uart_RecvString(cmd, COMMAND_LINE_SIZE);
   	if(strlen(cmd)==12)
    {
     lcf.mac[0] = str2hex(&cmd[0]);
     lcf.mac[1] = str2hex(&cmd[2]);
     lcf.mac[2] = str2hex(&cmd[4]);
     lcf.mac[3] = str2hex(&cmd[6]);
     lcf.mac[4] = str2hex(&cmd[8]);
     lcf.mac[5] = str2hex(&cmd[10]);
     return 0;
    }   		  	
  return -1;	
}

void dispip(unsigned int ipaddr)
{
	Uart_Printf("%d.%d.%d.%d",
						(ipaddr&0xff000000) >> 24,
						(ipaddr&0x00ff0000) >> 16,
						(ipaddr&0x0000ff00) >> 8,
						(ipaddr&0x000000ff));		
}

unsigned char
_atoi(char *str)
{
  unsigned char val=0, len, idx, round;

  len = strlen(str);
  for(idx=0; idx<len; idx++)
  {
   switch(idx)
   {
   	case 0: val += (str[len-idx-1]-'0')*1;   break;
   	case 1: val += (str[len-idx-1]-'0')*10;  break;
   	case 2: val += (str[len-idx-1]-'0')*100; break;
   	default: return 0;
   }  	
  }
 return val; 	
}

int str2ip( char *szIp, unsigned char *ucIp)
{
	int i=0, j=0, nIpIdx=0;
	char temp[4];
	int err=FALSE;
	U32 *coIP = (U32 *)ucIp;

	memset( ucIp, 0, 4);
	memset( temp, 0, 4);
	while( szIp[i] && !err)
	{
		if( szIp[i]=='.')
		{
			if( nIpIdx<4)
				ucIp[nIpIdx++]=(unsigned char)(_atoi(temp));
			else
				err=TRUE;
			memset( temp, 0, 4);
			j=0;
			i++;
		}
		else
			if(j<3)
				temp[j++]= szIp[i++];
			else
				err=TRUE;
	}
	if(!err)
		if(nIpIdx<4)
			ucIp[nIpIdx++]= (unsigned char)(_atoi(temp));

 *coIP = hton4(*coIP); 
	
 return err;
}

int setip(unsigned int *ipaddr, char *message)
{
  char cmd[COMMAND_LINE_SIZE+1];
  U32 myip; 	
  	
	Uart_Printf("\nCurrent %sIP: ", message);
	dispip(*ipaddr);
    Uart_Printf("\nExample: 192.168.0.3\n");
    Uart_Printf("Input: ");
    Uart_RecvString(cmd, COMMAND_LINE_SIZE);
   	if(strlen(cmd)>=7 && strlen(cmd)<=15)
   	{
   	  if(!str2ip(cmd, (unsigned char *)&myip))
   	  {
   	   *ipaddr = myip;
   	   return 0;
   	  }
   	}	
  return -1;	
}

void disphex(long val)
{
    int cnt;
    
    cnt = (val>>16);
    Uart_SendString(hex2char((cnt&0xf000)>>12));
    Uart_SendString(hex2char((cnt&0x0f00)>>8));
    Uart_SendString(hex2char((cnt&0x00f0)>>4));
    Uart_SendString(hex2char((cnt&0x000f)>>0));	
	
	cnt = (val&0xffff);
    Uart_SendString(hex2char((cnt&0xf000)>>12));
    Uart_SendString(hex2char((cnt&0x0f00)>>8));
    Uart_SendString(hex2char((cnt&0x00f0)>>4));
    Uart_SendString(hex2char((cnt&0x000f)>>0));	
}

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;
}

char str2hex(char *str)
{
   char ret;
   
   if(str[0]>='A')
    ret = (str[0]-'A'+10)<<4;
   else if(str[0]>='a')
    ret = (str[0]-'a'+10)<<4;
   else
    ret = (str[0]-'0')<<4;
    
   if(str[1]>='A')
    ret |= (str[1]-'A'+10);
   else if(str[1]>='a')
    ret |= (str[1]-'a'+10);
   else
    ret |= (str[1]-'0');
    
  return ret;	
}

void ShowConfig(void)
{
  Uart_SendString("\n\n###### System Configuration ######\n");	
  Uart_Printf("Boot Mode\t: %s\n", (lcf.bootdown&SYS_BOOT_FLASH)?"Flash":(lcf.bootdown&SYS_BOOT_DOWNLOAD)?"Download":"Menu");	
  Uart_Printf("Download Mode\t: %s\n", (lcf.bootdown&SYS_DOWNLOAD_USB)?"USB":(lcf.bootdown&SYS_DOWNLOAD_ETH_BOOTP)?"NET [BOOTP+TFTP]":"NET [TFTP]");
   if(lcf.bootdown & SYS_DOWNLOAD_ETH) { Uart_Printf("MAC Address\t: "); 	dispmac((char *)lcf.mac); Uart_Printf("\n"); }
   if(lcf.bootdown & SYS_DOWNLOAD_ETH_TFTP)
    {
      Uart_Printf("Local IP\t: ");
      dispip(lcf.loip);
      Uart_Printf("\nServer IP\t: ");
      dispip(lcf.rmip);
      Uart_Printf("\nFilename\t: %s\n", lcf.file);
    } 
   Uart_Printf("System\t\t: %s\n", (lcf.systype==SYS_LINUX?"Linux":(lcf.systype==SYS_WINCE?"WinCE":"None")));
   if(lcf.systype==SYS_LINUX) 
   {
    Uart_Printf("Kernel Command\t: %s\n", lcf.cmd);
    Uart_Printf("Linux Partition :\n");
    ShowLinuxPartition();
   }
  
  
  Uart_Printf("\nPress any key to continue...\n");
  Uart_Getch();
}

void ShowLinuxPartition(void)
{
  int nr_part;
    
  if(lcf.systype==SYS_LINUX)
  for(nr_part=0; nr_part<PARTITION_TOTAL; nr_part++)
  {
   if(lcf.part[nr_part].mask&PARTITION_VALID)
   {
    if(lcf.part[nr_part].size==PARTITION_RESTSIZE)
    Uart_Printf("[%d] %10s: %08x-REST (%s)\n", nr_part+1,      lcf.part[nr_part].name, 
    							       lcf.part[nr_part].offset, 
    							      (lcf.part[nr_part].mask&PARTITION_FIXED)?"FIXED":
    							      (lcf.part[nr_part].mask&PARTITION_RO)?"RO":
    							      (lcf.part[nr_part].mask&PARTITION_RW)?"RW":"NONE");
    else	   	
    Uart_Printf("[%d] %10s: %08x-%08x (%d) (%s)\n", nr_part+1, lcf.part[nr_part].name, 
    							     lcf.part[nr_part].offset, 
    							     lcf.part[nr_part].offset+lcf.part[nr_part].size, 
    							     lcf.part[nr_part].size,
    							    (lcf.part[nr_part].mask&PARTITION_FIXED)?"FIXED":
    							    (lcf.part[nr_part].mask&PARTITION_RO)?"RO":
    							    (lcf.part[nr_part].mask&PARTITION_RW)?"RW":"NONE");
   }
   //else
   // Uart_Printf("[%d] Invalid Partition\n", nr_part); 								
  }
		
}

void ModifyLinuxMTDName(void)
{
  char str[PARTITION_NAMESIZE+1];	
  Uart_Printf("Current MTD Name: %s\n", lcf.mtdname);
  Uart_Printf("New MTD Name: ");
  Uart_RecvString(str, PARTITION_NAMESIZE);   
   if(strlen(str)>0)
    strcpy(lcf.mtdname, str);
}


void ModifyLinuxPartition(void)
{
  int nr_part;
  char str[PARTITION_NAMESIZE+1];
 
  for(nr_part=0; nr_part<PARTITION_TOTAL; nr_part++)
  {
    if(lcf.part[nr_part].size==PARTITION_RESTSIZE)
    Uart_Printf("\n[%d] %10s: %08x-REST (%s)\n", nr_part+1,    lcf.part[nr_part].name, 
    							       lcf.part[nr_part].offset, 
    							      (lcf.part[nr_part].mask&PARTITION_FIXED)?"FIXED":
    							      (lcf.part[nr_part].mask&PARTITION_RO)?"RO":
    							      (lcf.part[nr_part].mask&PARTITION_RW)?"RW":"NONE");
    else	
    Uart_Printf("\n[%d] %10s: %08x-%08x (%d) (%s)\n", nr_part+1, lcf.part[nr_part].name, 
    							       lcf.part[nr_part].offset, 
    							       lcf.part[nr_part].offset+lcf.part[nr_part].size, 
    							       lcf.part[nr_part].size,
    							      (lcf.part[nr_part].mask&PARTITION_FIXED)?"FIXED":
    							      (lcf.part[nr_part].mask&PARTITION_RO)?"RO":
    							      (lcf.part[nr_part].mask&PARTITION_RW)?"RW":"NONE");
  	
   if(lcf.part[nr_part].mask&PARTITION_FIXED)
    Uart_Printf("Partition can't be modified!!\n");
   else
   {
    if(nr_part==1)
     Uart_Printf("Notice: The second partition will be taken as kernel!!\n");	
    Uart_Printf("Name: ");
    Uart_RecvString(str, PARTITION_NAMESIZE);
    if(strlen(str)>0)
     strcpy(lcf.part[nr_part].name, str);
    Uart_Printf("%s\n", lcf.part[nr_part].name); 

    op_again:  
    Uart_Printf("Option [1]Read-Only [2]Read-Write: ");
    Uart_RecvString(str, PARTITION_NAMESIZE);
    if(strlen(str)!=0 && (str[0]!='1' && str[0]!='2'))
     goto op_again; 
    else if(strlen(str)!=0)
     lcf.part[nr_part].mask = (str[0]=='1')?PARTITION_RO:PARTITION_RW;
    Uart_Printf("\n"); 
     
#if PARTITION_OFFSET
    Uart_Printf("Offset[Hex]: ");
    Uart_RecvString(str, PARTITION_NAMESIZE);   
    if(strlen(str)>0)
     lcf.part[nr_part].offset = strtol(str, NULL, 16);
    Uart_Printf("\n"); 
#else
    if(nr_part>0)
     lcf.part[nr_part].offset = lcf.part[nr_part-1].offset+lcf.part[nr_part-1].size;
    else
     lcf.part[nr_part].offset = 0;
#endif
    Uart_Printf("Size [16K*n, '-' for rest]: n = "); // Linux requires PAGE(4K) aligned, but NAND takes block(16K)
    Uart_RecvString(str, PARTITION_NAMESIZE);
    Uart_Printf("\n");   
    if(strlen(str)>0)
    {
     if(str[0]=='-')
     {
      lcf.part[nr_part].size = PARTITION_RESTSIZE;
      break;	
     }
     else
      lcf.part[nr_part].size = strtol(str, NULL, 10) * 1024 * 16;
    } 
         
    Uart_Printf("Next Partition? ");
    Uart_RecvString(str, PARTITION_NAMESIZE);
    Uart_Printf("\n");
    if(str[0]!='Y' && str[0]!='y')
     break;          	   	
   }   
  }  	
}


void DefaultLinuxPartition(void)
{
  int nr_part;
  		
  memset(&lcf.part[0], 0, sizeof(PARTITION)*PARTITION_TOTAL);	
  // The first partition is used by bootloader
  strcpy(lcf.mtdname, "s3c2410-nand");
  strcpy(lcf.part[0].name, "Bootloader");
  lcf.part[0].offset = 0;
  lcf.part[0].size   = DOWN_KERNEL_START_BLOCK*BLOCK_SIZE;
  lcf.part[0].mask   = PARTITION_FIXED;
  
}

char *strcopyshift(char *str, char *dup)
{
  strcpy(str, dup);
  return (str+strlen(dup));
}

void UpdateLinuxPartition(void)
{
  int real_part, key;
  
 part_again:
   Uart_Printf("Which partition to update [1-%d]: ", PARTITION_TOTAL);
   real_part = Uart_Getch()-'0'-1;
   Uart_Printf("\n");
   if(real_part>=PARTITION_TOTAL || real_part<0)
    goto part_again;
   
  if(lcf.part[real_part].mask&PARTITION_RO || lcf.part[real_part].mask&PARTITION_RW)
  {	
   DownloadImage(DOWN_RAM_ADDR);
   if(real_part==1)
   {
    lcf.imgblk = (((downloadFileSize/(0x4000))*(0x4000))+((downloadFileSize%(0x4000))?(0x4000):0))/BLOCK_SIZE;
    CFG_WRITE(&lcf); // Write configuration
   }
   downloadStartBlock = lcf.part[real_part].offset/BLOCK_SIZE;
    Uart_SendString("\nDownload finish, write to flash? [Y/N] ");
    key = Uart_Getch();
    if(key=='y' || key=='Y')   
     u241test_easy(DOWN_VARIABLE);
  }
  else
   Uart_Printf("Partition is unable to update!!\n");
   
}

void LinuxPartitionString(char *str)
{ 
  int nr_part, fpart;
  char temp[PARTITION_NAMESIZE+1];
  	
  if(lcf.systype!=SYS_LINUX) return;
  	
  str = strcopyshift(str, " mtdparts=");	
  str = strcopyshift(str, lcf.mtdname);
  str = strcopyshift(str, ":");
  
  for(nr_part=0,fpart=1; nr_part<PARTITION_TOTAL; nr_part++)
  {
   if(lcf.part[nr_part].mask&PARTITION_VALID)
   {	
    if(fpart)
     fpart=0;
    else
     str = strcopyshift(str, ",");

#if PARTITION_OFFSET
    if(lcf.part[nr_part].size==PARTITION_RESTSIZE)
     sprintf(temp, "-@%d%s(%s)%s",    (lcf.part[nr_part].offset%SIZE_1M==0)?lcf.part[nr_part].offset/SIZE_1M:lcf.part[nr_part].offset/SIZE_1K,
    				      (lcf.part[nr_part].offset%SIZE_1M==0)?"M":"K",
    				       lcf.part[nr_part].name, 
    				      (lcf.part[nr_part].mask&PARTITION_RW)?"":"ro"); 
    else
     sprintf(temp, "%d%s@%d%s(%s)%s", (lcf.part[nr_part].size%SIZE_1M==0)?lcf.part[nr_part].size/SIZE_1M:lcf.part[nr_part].size/SIZE_1K,
    				      (lcf.part[nr_part].size%SIZE_1M==0)?"M":"K",
                                      (lcf.part[nr_part].offset%SIZE_1M==0)?lcf.part[nr_part].offset/SIZE_1M:lcf.part[nr_part].offset/SIZE_1K,
    				      (lcf.part[nr_part].offset%SIZE_1M==0)?"M":"K",    				      
    				       lcf.part[nr_part].name,
    				      (lcf.part[nr_part].mask&PARTITION_RW)?"":"ro"); 
#else
    if(lcf.part[nr_part].size==PARTITION_RESTSIZE)
     sprintf(temp, "-(%s)%s",     lcf.part[nr_part].name,
     				 (lcf.part[nr_part].mask&PARTITION_RW)?"":"ro"); 
    else
     sprintf(temp, "%d%s(%s)%s", (lcf.part[nr_part].size%SIZE_1M==0)?lcf.part[nr_part].size/SIZE_1M:lcf.part[nr_part].size/SIZE_1K,
    				 (lcf.part[nr_part].size%SIZE_1M==0)?"M":"K",
    				  lcf.part[nr_part].name,
    				 (lcf.part[nr_part].mask&PARTITION_RW)?"":"ro");     
#endif    
    str = strcopyshift(str, temp);
   }	
  }
 
}

⌨️ 快捷键说明

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