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

📄 linuxld.c

📁 Boot code for ADM5120 with serial console for Edimax router.
💻 C
字号:
/*****************************************************************************;;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.;;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.;;------------------------------------------------------------------------------;;    Project : Common platform;    Creator : Sumei Chung;    File    : loader.C;    Abstract: ;;Modification History:; ;;*****************************************************************************/#include <ctype.h>#include <mips4kc.h>#include <adm5120.h>#include <hw_profile.h>#include <bconfig.h>#ifdef NOR_FLASH#include <mx29lv160.h>#include <mx29lv320.h>#include <flash.h>#else#include <nand.h>#endif#include <img_header.h>#include <xmodem.h>#include <uartdrv.h>#include <stdlib.h>#include <zlib.h>#include <linuxld.h>#define AM5120_VINETIC	0/* linux boot defined *//* Address of "_start" in System.map */#define LINUX_ENTRY_POINT		0x800026D8#define LINUX_IMAGE_SIZE		LINUXLD_FLASH_KERNEL_SIZE/* gzip defined */#define _OFFSET(_t, _m)		((u_int) &(((_t *) 0)->_m))#define Z_EOF	0/* gzip flag byte */#define ASCII_FLAG   0x01		/* bit 0 set: file probably ascii text */#define HEAD_CRC     0x02		/* bit 1 set: header CRC present */#define EXTRA_FIELD  0x04		/* bit 2 set: extra field present */#define ORIG_NAME    0x08		/* bit 3 set: original file name present */#define COMMENT      0x10		/* bit 4 set: file comment present */#define RESERVED     0xE0		/* bits 5..7: reserved */static int gz_magic[2] = { 0x1f, 0x8b };	/* gzip magic header */unsigned int loader_heap = LINUXLD_GZIP_HEAP;char *pass = "PASS";char *fail = "FAIL";int ungzip(Byte * compr);extern void _icache_sync_all(void);void jump_up_map();void jump_low_map();/* * Update bootloader */int update_bootloader(){	void *flash = (void *) LINUXLD_FLASH_LOADER_START;	char *image = (char *) LINUXLD_DOWNLOAD_START;	int len, rc = 0;	/* download loader image to temp using xmodem */	buart_print("\n\rDownloading..........");	if ((len = xmodem(image, LINUXLD_FLASH_LOADER_SIZE)) == -1)		goto fail;	else		buart_print(pass);	/* erase flash */	buart_print("\n\rErasing flash.......");	if (nf_erase(flash, len) != 0)		goto fail;	else		buart_print(pass);	/* write flash */	buart_print("\n\rProgramming flash....");	if (nf_write_boot((UINT8 *) flash, image, len) != 0)		goto fail;	else		buart_print(pass);	goto ok;  fail:	buart_print(fail);	rc = -1;  ok:	return (rc);}int tftpc_download(void){	void *flash = (void *) LINUXLD_FLASH_KERNEL_START;	char *image = (char *) LINUXLD_DOWNLOAD_START;	char lenstr[9];	UINT32 len;	buart_print("\n\rStarting the TFTP download(ESC to stop)..");	if ((len = tftpc(image, LINUX_IMAGE_SIZE)) == 0)		goto fail;	else		buart_print(pass);	//print image length and starting address in sdram.	//ultoa(len,lenstr);	//lenstr[8]=0;	//buart_print("\n\rImage Total Length: ");	//buart_print(lenstr);	//ultoa(image,lenstr);	//buart_print("  Starting Address: ");	//buart_print(lenstr);	//erase flash 	buart_print("\n\r\n\rErasing flash.......");#ifdef AM5120_VINETIC	{		int remain;		if ((remain = len - LINUXLD_NORFLASH_REMAIN) > 0) {			jump_low_map();			if (nf_erase(flash, LINUXLD_NORFLASH_REMAIN) != 0)				goto fail;			jump_up_map();			if (nf_erase(LINUXLD_NORFLASH_LOADER_START, remain) != 0)				goto fail;			jump_low_map();			goto ERASE_PASS;		}	}#endif	if (nf_erase(flash, len) != 0)		goto fail;  ERASE_PASS:	buart_print(pass);	//write flash	buart_print("\n\rProgramming flash....");#ifdef AM5120_VINETIC	{		int remain;		if ((remain = len - LINUXLD_NORFLASH_REMAIN) > 0) {			jump_low_map();			if (nf_write(flash, image, LINUXLD_NORFLASH_REMAIN) != 0)				goto fail;			jump_up_map();			if (nf_write(LINUXLD_NORFLASH_LOADER_START, image + LINUXLD_NORFLASH_REMAIN, remain) != 0)				goto fail;			jump_low_map();			goto WRITE_PASS;		}	}#endif	if (nf_write(flash, image, len) != 0)		goto fail;  WRITE_PASS:	buart_print(pass);	goto ok;  fail:	jump_low_map();	buart_print(fail);	return -1;  ok:	return 0;}/* * download linux image to flash using xmodem */int xmodem_download(void){	void *flash = (void *) LINUXLD_FLASH_KERNEL_START;	char *image = (char *) LINUXLD_DOWNLOAD_START;	int len, rc = 0;	/* download linux image to temp using xmodem */	buart_print("\n\rDownloading..........");	if ((len = xmodem(image, LINUX_IMAGE_SIZE)) == -1)		goto fail;	else		buart_print(pass);	/* erase flash */	buart_print("\n\rErasing flash.......");#ifdef AM5120_VINETIC	{		int remain;		if ((remain = len - LINUXLD_NORFLASH_REMAIN) > 0) {			jump_low_map();			if (nf_erase(flash, LINUXLD_NORFLASH_REMAIN) != 0)				goto fail;			jump_up_map();			if (nf_erase(LINUXLD_NORFLASH_LOADER_START, remain) != 0)				goto fail;			jump_low_map();			goto ERASE_PASS;		}	}#endif	if (nf_erase(flash, len) != 0)		goto fail;  ERASE_PASS:	buart_print(pass);	/* write flash */	buart_print("\n\rProgramming flash....");#ifdef AM5120_VINETIC	{		int remain;		if ((remain = len - LINUXLD_NORFLASH_REMAIN) > 0) {			jump_low_map();			if (nf_write(flash, image, LINUXLD_NORFLASH_REMAIN) != 0)				goto fail;			jump_up_map();			if (nf_write(LINUXLD_NORFLASH_LOADER_START, image + LINUXLD_NORFLASH_REMAIN, remain) != 0)				goto fail;			jump_low_map();			goto WRITE_PASS;		}	}#endif	if (nf_write(flash, image, len) != 0)		goto fail;  WRITE_PASS:	buart_print(pass);	goto ok;  fail:	buart_print(fail);	rc = -1;  ok:	return (rc);}/* * linux boot function */void boot_linux(){	int status;	void (*funcptr) (void);	buart_print("\n\rBooting Linux... ");	// NAND flash cannot ungzip kernel as directly as NOR flash.	// NAND flash "must" copy kernel to sdram first.#ifdef NOR_FLASH	// decompressing	buart_print("\n\rKernel decompress ... ");#ifdef AM5120_VINETIC	{		char *image = (char *) LINUXLD_DOWNLOAD_START;		char *flash = (char *) LINUXLD_NORFLASH_KERNEL_START;		jump_low_map();		memcpy(image, flash, LINUXLD_NORFLASH_REMAIN);		jump_up_map();		image += LINUXLD_NORFLASH_REMAIN;		flash = (char *) LINUXLD_NORFLASH_LOADER_START;		memcpy(image, flash, LINUXLD_NORFLASH_MAP_SIZE);		jump_low_map();		status = ungzip((unsigned char *) LINUXLD_DOWNLOAD_START);	}#else	status = ungzip((unsigned char *) LINUXLD_NORFLASH_KERNEL_START);#endif#else	nf_read((UINT8 *) LINUXLD_DOWNLOAD_START, (UINT8 *) LINUXLD_FLASH_KERNEL_START, LINUX_IMAGE_SIZE);	// decompressing	buart_print("\n\rKernel decompress ... ");	//okay!");	status = ungzip((unsigned char *) LINUXLD_DOWNLOAD_START);#endif	if (status != Z_OK)			// failed in unzipping	{		buart_print(fail);		return;					// return if cannot boot	} else		buart_print(pass);	DisableTimer();	funcptr = (void *) LINUX_ENTRY_POINT;	_icache_sync_all();	funcptr();}/* * decompress function */int ungzip(unsigned char *zimg){	int i, err, gzflags;	z_stream d_stream;			// decompression stream	if ((zimg[0] != gz_magic[0]) || (zimg[1] != gz_magic[1]))		return (Z_DATA_ERROR);	if (zimg[2] != Z_DEFLATED)		return (Z_DATA_ERROR);	gzflags = zimg[3];	// Skip the gzip header	zimg += 10;	if ((gzflags & EXTRA_FIELD) != 0) {	/* skip the extra field */		i = (*zimg++) + (*zimg++) << 8;		while ((i-- != 0) && (*zimg++) != Z_EOF);	}	if ((gzflags & ORIG_NAME) != 0) {	/* skip the original file name */		while (*zimg++ != Z_EOF);	}	if ((gzflags & COMMENT) != 0) {	/* skip the .gz file comment */		while (*zimg++ != Z_EOF);	}	if ((gzflags & HEAD_CRC) != 0) {	/* skip the header crc */		zimg += 2;	}	/* Decompress the image now */	d_stream.zalloc = NULL;	d_stream.zfree = NULL;	d_stream.opaque = (voidpf) 0;	d_stream.next_in = zimg;	// address of compress image	d_stream.avail_in = LINUX_IMAGE_SIZE;	// size of compress image	if ((err = inflateInit2(&d_stream, -MAX_WBITS)) != Z_OK) {		return err;	}	d_stream.next_out = (char *) LINUXLD_KERNEL_START;	// address of decompress image	d_stream.avail_out = LINUXLD_KERNEL_SIZE;	// size of decompress space	if ((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_STREAM_END) {		return err;	}	err = inflateEnd(&d_stream);	return err;}/*  *  Because there is no OS support, the memory management functions in  *  STD C libray cann't be used. To overcome the problem, a very simple *  memory management skime is implemented here. */void *calloc(size_t items, size_t size){	size_t memsize = items * size;	size_t bkstart;	/* Make sure the memory block is always aligned on 4-byte boundry */	if (loader_heap & 0x03)		loader_heap = (loader_heap + 3) & ~0x03;	bkstart = loader_heap;	loader_heap += memsize;	return (void *) bkstart;}/*  * dummy function */void free(void *ptr){	return;}/* * Jump to no-flash upper 2MB */void jump_up_map(){	int i;	/* Set GPIO[3](CS) to high */	for (i = 0; i < 10000; i++);	ADM5120_SW_REG(GPIO_conf0_REG) = 0x080800f7;	for (i = 0; i < 10000; i++);}/* * Jump to no-flash upper 2MB */void jump_low_map(){	int i;	/* Set GPIO[3](CS) to low */	for (i = 0; i < 10000; i++);	ADM5120_SW_REG(GPIO_conf0_REG) = 0x3ff;	for (i = 0; i < 10000; i++);}

⌨️ 快捷键说明

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