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

📄 utility.c

📁 QT2410的BOOTLOADER 特点 1.支援NAND FLASH读写 2.TFTP firmware upgrade 3.USB firmware upgrade 4.Fdisk
💻 C
字号:
#include "sys.h"

//Linux image could be packed to multi-file object
#define IH_MAGIC	0x27051956	/* Image Magic Number		*/
typedef struct _ImageHeader
 {
	u_int	ih_magic;	/* Image Header Magic Number	*/
	u_int	ih_hcrc;	/* Image Header CRC Checksum	*/
	u_int	ih_time;	/* Image Creation Timestamp	*/
	u_int	ih_size;	/* Image Data Size		*/
	u_int	ih_load;	/* Data	 Load  Address		*/
	u_int	ih_ep;		/* Entry Point Address		*/
	u_int	ih_dcrc;	/* Image Data CRC Checksum	*/
	u_char		ih_os;		/* Operating System		*/
	u_char		ih_arch;	/* CPU architecture		*/
	u_char		ih_type;	/* Image Type			*/
	u_char		ih_comp;	/* Compression Type		*/
	u_char		ih_name[32];	/* Image Name		*/
} ImageHeader;    
ImageHeader *ih;

extern char CS8900IP[20];
extern u_char CS8900Amac[6];
extern systemInfo *globalSysInfo;
//delay for 1 milli second = 0.001 sec
void Delay(unsigned int ms)
{
	rTCFG0|=0xFF00;  //Prescaler1=255
	rTCFG1|=0x300; //Select MUX input for PWM Timer2:divider=16
	// I just compute this value by using my watch timing
	rTCNTB2=750; //50000000/16/(255+1)=81.92*10^-6 seconds
	rTCMPB2=0;   //81.92*750=0.06 but actually it runs a 1 milli seconds interval
	rTCON|=1<<13;//timer2 manual updata on
	rTCON&=~(1<<13);//timer2 manual updata off
	rTCON|=0x9<<12;//start timer2 with auto reload on and invert off
	while(ms!=0) {
		while(rTCNTO2>0);
		--ms;
	}
	rTCON&=~(0x9<<20);
} 

unsigned short ntohs(unsigned short s)
{
	return (s >> 8) | (s << 8);
}

unsigned long ntohl(unsigned long l)
{
	return  ((l >> 24) & 0x000000ff) |
		((l >>  8) & 0x0000ff00) |
		((l <<  8) & 0x00ff0000) |
		((l << 24) & 0xff000000);
}

unsigned short htons(unsigned short s)
{
	return (s >> 8) | (s << 8);
}

unsigned long htonl(unsigned long l)
{
	return ntohl(l);
}

u_int str_to_addr(const char *addr)
{
	u_int split[4];
	u_int ip;

	sscanf(addr, "%d.%d.%d.%d", &split[0], &split[1], &split[2], &split[3]);

	/* assuming sscanf worked */
	ip = (split[0] << 24) |(split[1] << 16) | (split[2] << 8) | (split[3]);

	return htonl(ip);
}

void addr_fprint(u_int x)
{
	u_char split[4];
	u_int ip;
	char temp[20];
	
	//memset(CS8900IP,0x0,20);
	ip = ntohl(x);
	split[0] = (ip & 0xff000000) >> 24;
	split[1] = (ip & 0x00ff0000) >> 16;
	split[2] = (ip & 0x0000ff00) >> 8;
	split[3] = (ip & 0x000000ff);
	sprintf(temp,"%d.%d.%d.%d", split[0], split[1], split[2], split[3]);
	strcpy(CS8900IP,temp,20);
}

char hextochar(unsigned char in) {
	if(in < 16)
		return (in<10)?in+48 : in+55;
}


unsigned char chartohex(unsigned char in) {
	in = toupper(in);
	if((in >= 'A') && (in <= 'F'))
		in = in - 'A' + 10;
	else if((in >= '0') && (in <= '9'))
		in = in - '0';
	return in;
}


unsigned char* strtohex(const char *in, int *len) {
	unsigned char *out;
	int out_size = 0;
	int i, j;

	out_size = strlen(in) / 2;
	if(out_size == 0)
		return NULL;

	out =(unsigned char *)malloc(sizeof(unsigned char) * out_size + 1);
	memset(out, 0, out_size + 1);

	for(i=0; i<out_size; i++) {
		j = 2 * i;
		out[i] = chartohex(in[j]);
		out[i] = out[i] << 4;
		out[i] = out[i] + chartohex(in[j+1]);
	}
	*len = out_size;

	return out;
}


char *hextostr(unsigned char *in, int in_size) {
	unsigned char low = 0x0F, c;
	char *out;
	int i, size;

	if(!in_size)
		return NULL;

	size = in_size * 2 + 1;
	out = (char*)malloc(sizeof(char) * size);
	memset(out, 0, size);

	for(i=0; i<in_size; i++) {
		c = in[i] >> 4;
 		*(out + 2*i) = hextochar(c);

		c = in[i] & low;
		*(out + 2*i + 1) = hextochar(c);
	}
	return out;
}

static __inline void CacheCleanInvalidateAll(void)
{
	__asm{
		mov	r1, #0		
		mov	r1, #7 << 5			  	/* 8 segments */
cache_clean_loop1:		
		orr	r3, r1, #63UL << 26	  	/* 64 entries */
cache_clean_loop2:	
		mcr	p15, 0, r3, c7, c14, 2	/* clean & invalidate D index */
		subs	r3, r3, #1 << 26
		bcs	cache_clean_loop2		/* entries 64 to 0 */
		subs	r1, r1, #1 << 5
		bcs	cache_clean_loop1		/* segments 7 to 0 */
		mcr	p15, 0, r1, c7, c5, 0	/* invalidate I cache */
		mcr	p15, 0, r1, c7, c10, 4	/* drain WB */
	}
}

static __inline void TLBInvalidateAll(void)
{
	__asm{
		mov	r0, #0
		mcr	p15, 0, r0, c7, c10, 4	/* drain WB */
		mcr	p15, 0, r0, c8, c7, 0	/* invalidate I & D TLBs */
	}
}


#define LINUX_PAGE_SHIFT	12
#define LINUX_PAGE_SIZE		(1<<LINUX_PAGE_SHIFT)
#define COMMAND_LINE_SIZE 	1024

struct param_struct {
    union {
	struct {
	    unsigned long page_size;			/*  0 */
	    unsigned long nr_pages;				/*  4 */
	    unsigned long ramdisk_size;			/*  8 */
	    unsigned long flags;				/* 12 */
#define FLAG_READONLY	1
#define FLAG_RDLOAD		4
#define FLAG_RDPROMPT	8
	    unsigned long rootdev;				/* 16 */
	    unsigned long video_num_cols;		/* 20 */
	    unsigned long video_num_rows;		/* 24 */
	    unsigned long video_x;				/* 28 */
	    unsigned long video_y;				/* 32 */
	    unsigned long memc_control_reg;		/* 36 */
	    unsigned char sounddefault;			/* 40 */
	    unsigned char adfsdrives;			/* 41 */
	    unsigned char bytes_per_char_h;		/* 42 */
	    unsigned char bytes_per_char_v;		/* 43 */
	    unsigned long pages_in_bank[4];		/* 44 */
	    unsigned long pages_in_vram;		/* 60 */
	    unsigned long initrd_start;			/* 64 */
	    unsigned long initrd_size;			/* 68 */
	    unsigned long rd_start;				/* 72 */
	    unsigned long system_rev;			/* 76 */
	    unsigned long system_serial_low;	/* 80 */
	    unsigned long system_serial_high;	/* 84 */
	    unsigned long mem_fclk_21285;       /* 88 */
	} s;
	char unused[256];
    } u1;
    union {
	char paths[8][128];
	struct {
	    unsigned long magic;
	    char n[1024 - sizeof(unsigned long)];
	} s;
    } u2;
    char commandline[COMMAND_LINE_SIZE];
};

void initLinuxParam()
{
	int i;
	
	struct param_struct *params = (struct param_struct *)0x30000100;
	char *linux_params = globalSysInfo->BootParam;
	
	for(i=0; i<(sizeof(struct param_struct)>>2); i++)
		((u_int *)params)[i] = 0;
	params->u1.s.page_size = LINUX_PAGE_SIZE;
	params->u1.s.nr_pages = (0x04000000 >> LINUX_PAGE_SHIFT);
	for(i=0; linux_params[i]; i++)
		params->commandline[i] = linux_params[i];
		
	printf("Boot Parameter:%s\n\r",linux_params);
	
	
}

bool CheckImageHeader()
{
	
	
	ih=(ImageHeader *)globalSysInfo->ApplicationLoadAddress;
	if (ntohl(ih->ih_magic) != IH_MAGIC) return true;
	else return false;
}

void JumpToProgram()
{
	void (*fp)(u_int,u_int,u_int);
	
	initLinuxParam();
	if (CheckImageHeader())
		fp = (void (*)(u_int,u_int,u_int))globalSysInfo->ApplicationLoadAddress;
	else fp = (void (*)(u_int,u_int,u_int))ntohl(ih->ih_ep);
	CacheCleanInvalidateAll();
	TLBInvalidateAll();
	__asm
	{
		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 */
	}
	Delay(100);
	(*fp)(0,193,0x30000100);//193 is the linux machine type of 2410
	return;
}

void WriteNANDFlash(u_int address,u_int size)
{
	u_int StartAddress,EndAddress,StartBlock,EndBlock,i;
	char buffer[512];
	int ret;	
	
	//First we erase the block we want to override
	StartAddress=linearAddressConvert(address);
	StartBlock=blockAddressConvert(address);
	EndAddress=linearAddressConvert(address+size);
	EndBlock=blockAddressConvert(address+size);
	
	printf("Erasing blocks...\n\r");
	for (i=StartBlock;i<=EndBlock;i++)
	{
		ret=EraseBlock(i);
		if (ret==SUCCESS)
			printf(".");
		else printf("*");
	}	
	printf("Erase finished\n\r");
	printf("Start writing image %d size at NAND %d\n\r",size,address);
	for (i=globalSysInfo->ApplicationLoadAddress;i<(globalSysInfo->ApplicationLoadAddress+size);i+=512)
	{
		memset(buffer,0,512);
		StartAddress=linearAddressConvert(address);
		memcpy(buffer,i,512);
		ret=WritePage(StartAddress,buffer);
		if (ret==SUCCESS) printf(".");
		else printf("*");
		address+=512;
	}
	printf("\n\rUpgrading Success!!\n\r");
	
	
}

bool NANDFlashUpgrade(int area,int size)
{
	if (area==LKIM)
	{
		WriteNANDFlash(globalSysInfo->LinuxKernelImageStart,size);
		globalSysInfo->LinuxKernelImageSize=size;
		return true;
	}
	else if (area==LKFS)
	{
		WriteNANDFlash(globalSysInfo->LinuxFileSystemStart,size);
		globalSysInfo->LinuxFileSystemSize=size;
		return true;
	
	}
	else if (area==OKIM)
	{
		WriteNANDFlash(globalSysInfo->OtherKernelImageStart,size);
		globalSysInfo->OtherKernelImageSize=size;
		return true;
	}
	else if (area==BLIM)
	{
		WriteNANDFlash(globalSysInfo->bootImageStart,size);
		globalSysInfo->bootImageSize=size;
		return true;
	}
	else 
	{
		printf("Wrong Area to upgrade\n\r");
		return false;
	}
}

⌨️ 快捷键说明

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