📄 loader.c.svn-base
字号:
/*************************************************************** Loader.c - main loader routine*** History:* 10/23/2006 SH, Lee added flashsize/memsize/miisel commands. (00.01.11=>12)* 10/26/2006 SH, Lee Added big model support* 10/20/2006 SH, Lee Determine memory configration from flash (00.01.12=>00.01.12a)* 03/12/2007 SH Fix cannot upgrade fw from web if decompress failed* 06/26/2007 SH Added erase the last section while setting parameters (1.14->1.15)* 10/22/2007 SH Merge Kevin's Patch for TR068 and configure RTL8306 * 11/01/2007 SH Modify _PARM_START and _PARM_SZ for increaseing size of bootloader*************************************************************//*DESCRIPTIONInitialize user application code.*/ #include "../tcp/cc.h"#include "../tcp/err.h"#include "../tcp/def.h"#include "../tcp/http.h"#include "zlib.h"#include "board.h"#include "mib.h"#include "../tftpnaive/net.h"#include "../tftpnaive/tftpnaive.h"#if CONFIG_OSK_APP_SUPPORT #include "osk.h" #endif#ifndef ERROR#define ERROR -1#endif#ifndef OK#define OK 0#endifconst char logo_msg[] = { "(c)Copyright Realtek, Inc. 2007" "\n\rProject RTL8671 LOADER (LZMA)\n\rVersion "};const char version_msg[] ={ "00.01.16"};/* for loader debug function */board_param_t bParam;//board_param_t bdinfo;#define _PARM_START 0xbfc0f300#define _PARM_END 0xbfc10000#define _PARM_SZ 0x0d00#define _PARM_BACK_START 0x8000#define _PARM_BACK_SZ 0x8000int get_param(board_param_p buf){int ret;unsigned long addr;char id_buf[8];char *ptr; for(addr=_PARM_START; addr<_PARM_END; addr+=BOARD_PARAM_SZ) { ret = amd29lvReadNV(id_buf, addr, sizeof(id_buf)); if(ret!=OK) return ret; if(!strcmp(id_buf, BOARD_PARAM_ID)) { ret = amd29lvReadNV(buf, addr, BOARD_PARAM_SZ); if(ret!=OK) return ret; goto get_mac_ip; } } if(addr>=_PARM_END) { memset(buf, 0, sizeof(board_param_t)); strcpy(buf->id, BOARD_PARAM_ID); strcpy(buf->bootline, BOARD_PARAM_BOOT); memcpy(buf->mac[0], BOARD_PARAM_MAC, 6); buf->entry = BOARD_PARAM_ENTRY; buf->load = BOARD_PARAM_LOAD; buf->app = BOARD_PARAM_APP; buf->ip = BOARD_PARAM_IP; buf->flash_size = BOARD_PARAM_FLASHSIZE; buf->mem_size = BOARD_PARAM_MEMSIZE; buf->MII_select = BOARD_PARAM_MIISEL; }get_mac_ip: //read MAC of runtime config ptr = (char *)FLASH_BASE_ADDR+HW_SETTING_OFFSET; if( memcmp(ptr, HS_CONF_SETTING_SIGNATURE_TAG, SIGNATURE_LEN) == 0 ) { HW_MIB_Tp pHWMIB; ptr+=sizeof(PARAM_HEADER_T); pHWMIB = (HW_MIB_Tp)ptr; memcpy(buf->mac[0], pHWMIB->elanMacAddr, MAC_ADDR_LEN); } //read IP of runtime config ptr = (char *)FLASH_BASE_ADDR+CURRENT_SETTING_OFFSET; if( memcmp(ptr, CS_CONF_SETTING_SIGNATURE_TAG, SIGNATURE_LEN) == 0 ) { MIB_Tp pMIB; ptr+=sizeof(PARAM_HEADER_T); pMIB = (MIB_Tp)ptr; memcpy(&buf->ip, pMIB->ipAddr, IP_ADDR_LEN); } return OK;}int set_param(board_param_p buf){int ret;unsigned long addr;/* * Erase parameter section (the last section of bootloader flash layout) before set * the new one. If defined #if 1 that means using the old fashion. */#if 0 char id_buf[8]; for(addr=_PARM_END-BOARD_PARAM_SZ; addr>=_PARM_START; addr-=BOARD_PARAM_SZ) { ret = amd29lvReadNV(id_buf, addr, sizeof(id_buf)); if(ret!=OK) return ret; if(strcmp(id_buf, BOARD_PARAM_ID)) break; } if(addr<_PARM_START) { /* no free space */ /* erase flash last unit */ char *pBackup = malloc(_PARM_BACK_SZ); if(!pBackup) return ERROR; memcpy(pBackup, _PARM_BACK_START, _PARM_BACK_SZ); memset(pBackup+_PARM_BACK_SZ-_PARM_SZ, 0xff, _PARM_SZ); if(amd29lvEraseNV(0x8000, 0x8000) != OK) { free(pBackup); return ERROR; } amd29lvWriteNV(_PARM_BACK_START, pBackup, _PARM_BACK_SZ); free(pBackup); /* backup loader area */ addr = _PARM_END-BOARD_PARAM_SZ; } /* make board id */ strcpy(buf->id, BOARD_PARAM_ID); /* write flash last unit */ return amd29lvWriteNV(addr, buf, sizeof(board_param_t));#else addr = _PARM_START; char *pBackup = malloc(_PARM_BACK_SZ); if(!pBackup) return ERROR; //Clean memory backup section memset(pBackup, 0xff, _PARM_BACK_SZ); //Copy backup section from flash to memory memcpy(pBackup, FLASH_BASE_ADDR+_PARM_BACK_START, _PARM_BACK_SZ-_PARM_SZ); //Set modified parameters memcpy(pBackup+_PARM_BACK_START-_PARM_SZ, buf, sizeof(board_param_t)); if(amd29lvEraseNV(_PARM_BACK_START, _PARM_BACK_SZ) != OK) { free(pBackup); return ERROR; } if(amd29lvEraseNV(_PARM_BACK_START+_PARM_BACK_SZ-_PARM_SZ, _PARM_SZ) != OK) { free(pBackup); return ERROR; } //program the backup section and modified parameters amd29lvWriteNV(FLASH_BASE_ADDR+_PARM_BACK_START, pBackup,_PARM_BACK_SZ ); free(pBackup); return OK;#endif}/* This function writes hardware address to flash matching the OSK's internal configuration* */#define OSK_CFG_SIZE 0x2000#define OSK_CFG_ADDR 0xBFC04000int set_osk_hwaddr(unsigned char *hwaddr){ int ret = ERROR; char *pCfg; pCfg = malloc( OSK_CFG_SIZE ); if(!pCfg) goto ERROR1; memcpy(pCfg, OSK_CFG_ADDR, OSK_CFG_SIZE); // backup current config. memset(&pCfg[ 0x1f80 ], 0xff, 0x10); memcpy(&pCfg[ 0x1f80 ], hwaddr, 6); // append mac to the end. if (OK != amd29lvEraseNV(0x4000, OSK_CFG_SIZE)) goto ERROR2; // SST flash has uniform 4k block. if (OK != amd29lvEraseNV(0x5000, 0x1000)) goto ERROR2; ret = amd29lvWriteNV(OSK_CFG_ADDR, pCfg, OSK_CFG_SIZE);ERROR2: free(pCfg);ERROR1: return ret;}extern char cmd_prompt[];void print_banner(void){ printf( logo_msg ); printf( version_msg ); printf(" (%s %s)", __DATE__, __TIME__); printf("\n\r\n\r<RTL8671>");}int decompress_image(unsigned char *dest, unsigned int destLen, unsigned char *source, unsigned int sourceLen){int err;z_stream d_stream; /* decompression stream */ d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = source; d_stream.avail_in = 0; d_stream.next_out = dest; /* discard the output */ d_stream.avail_out = destLen; err = inflateInit(&d_stream); if (err != Z_OK) printf("inflateInit error!\n\r"); while(d_stream.total_in < sourceLen) { if(d_stream.avail_in ==0) d_stream.avail_in = 1024*32; err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END || err < 0) break; } err = inflateEnd(&d_stream); return err; }//these 2 are from linux-2.4.x/include/linux/cramfs_fs.h#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */#define CRAMFS_SIGNATURE "Compressed ROMFS"//this is from linux-2.4.x/include/linux/cramfs_fs.h#define SQUASHFS_MAGIC 0x73717368int run_gzip_file(unsigned int src, unsigned long entry){ int ret; unsigned int comprLen; unsigned int uncompressedLength; /* infate RAM file */ comprLen = 1024*1024*2; //11/06/04' hrchen, in C_Entry(), printf() will destory the value of uncompressedLength //reset uncompressedLength again uncompressedLength = 0xFFFFFFFF; //ret = uncompress(entry, &uncompressedLength, src, comprLen); printf("Decompress file... "); if ( CRAMFS_MAGIC==*((unsigned int*)src) ) { //10/19/05' hrchen, cramfs case //10/17/05' hrchen, +*((unsigned int)(src+4)) to skip file system src+=*((unsigned int*)(src+4)); //skip cramfs image } else if ( SQUASHFS_MAGIC==*((unsigned int*)src) ) { //11/14/05' hrchen, squashfs case src+=((*((unsigned int*)(src+8))+0x0FFF)&(~0x0FFF)); //skip squashfs image }; ret = uncompressLZMA(entry, &uncompressedLength, src, comprLen);#if CONFIG_OSK_APP_SUPPORT if (ret) { // try OSK if uClinux failed. IMGHDR *pImgHdr; pImgHdr = (IMGHDR *)src; //printf("Trying OSK...\n\r"); if (APPLICATION_IMAGE == pImgHdr->key) { entry = pImgHdr->address; src += HEADERSIZE; printf("OSK image found\n\r"); ret = uncompressLZMA(entry, &uncompressedLength, src, comprLen); entry = pImgHdr->entry; } } #endif if(!ret) { printf("ok!\n\r"); void (*appStart)(void);#ifdef Flash_AA21_GPA5 //big model //2/16/07' hrchen, write back all data in cache into DRAM to finish code decompress. //If not, OS will reset cache and lost data. It will cause system crash. __asm__ volatile( "mtc0 $0,$20\n\t" "nop\n\t" "li $8,0x00000100\n\t" "mtc0 $8,$20\n\t" "nop\n\t" "nop\n\t" "mtc0 $0,$20\n\t" "nop" : /* no output */ : /* no input */ );#endif //Flash_AA21_GPA5 /* jump to decompressed program */ appStart = (void*)entry; appStart(); } printf("failed!\n\r"); return ERROR; }/* console utility */int check_break(int val){char ch;int i; val = UpperChar(val); for(i=0; i<1000; i++); if(poll_cc()) { ch = getcc(); ch = UpperChar(ch); if(ch == val) return 1; } return 0;}int write_file(char* dest, char* src, int src_len){ char *ptr_src, *ptr_dst, buffer[0x10000]; int offset, copy_length; //10/25/05' hrchen, merge config space and bootloader //config is at 0xbfc04000~0xbfc07fff if (dest<0xbfc10000) { //update bootloader related stuff if ( (((unsigned int)dest+src_len)>0xbfc08000)&&((unsigned int)dest<0xbfc04000) ) { //assume dest always before 0xbfc04000, and dest+src_len is always behind 0xbfc08000 offset = (unsigned int)0xbfc04000-(unsigned int)dest; ptr_dst = (char *)((unsigned int)src+offset); ptr_src = (char *)0xbfc04000; copy_length = 0x4000; memcpy(ptr_dst, ptr_src, copy_length); } else if ( ((unsigned int)dest==0xbfc04000)&&(src_len==0x4000) ) { //write config space ptr_src = src; src = (char*)buffer; memcpy(src, FLASH_BASE_ADDR, 0x10000); memcpy(src+0x4000, ptr_src, 0x4000); dest = FLASH_BASE_ADDR; src_len = 0x10000; }; }; return amd29lvWrite(dest, src, src_len);}/*==== Andrew. Added to support OSK header ====>*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -