/*******************************************************************/ | |
/************************* File Description ************************/ | |
/*******************************************************************/ | |
/* File Name: $Workfile: hmx_uprade_flash.c $ | |
* Version: $Revision: 1.0 $ | |
* Original Author: Yang Hyun Uk $ | |
* Current Author: $Author: huyang@humaxdigital.com $ | |
* Date: $Date: 2011.09.30 | |
* File Description: Humax Upgrade APIs | |
* Module: | |
* Remarks: | |
*/ | |
/** | |
* @defgroup UPGRADE_FLASH Flashing APIs for Upgrade Module | |
* @ingroup UPGRADE | |
* | |
*/ | |
/** | |
* @author Hyunuk Yang(huyang@humaxdigital.com) | |
* @date 30 Sept 2011 | |
*/ | |
/** | |
* @note | |
* Copyright (C) 2011 Humax Corporation. All Rights Reserved. <br> | |
* This software is the confidential and proprietary information | |
* of Humax Corporation. You may not use or distribute this software | |
* except in compliance with the terms and conditions of any applicable license | |
* agreement in writing between Humax Corporation and you. | |
*/ | |
/*@{*/ | |
/** | |
* @file hmx_upgrade_flash.c | |
*/ | |
/*******************************************************************/ | |
/**************************** Header Files *************************/ | |
/*******************************************************************/ | |
/* Start Including Header Files */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <sys/ioctl.h> | |
#include <sys/mount.h> | |
#include <mtd/mtd-user.h> | |
#include "hmx_upgrade_flash.h" | |
/* End Including Headers */ | |
/*******************************************************************/ | |
/****************************** define *****************************/ | |
/*******************************************************************/ | |
/* End #define */ | |
/* this is for test */ | |
#define TARGET_BOOT_LOADER_MTD "/dev/mtdblock0" | |
#define TARGET_NVRAM_MTD "/dev/mtdblock1" | |
/* this is for test */ | |
#define TARGET_KERNEL_MTD "/dev/mtdblock10" | |
/* this is for test ubi mapped */ | |
#define TARGET_ROOTFS_UBI_MTD "/dev/mtdblock11" | |
/*******************************************************************/ | |
/****************************** typedef ****************************/ | |
/*******************************************************************/ | |
/* Start typedef */ | |
/* End typedef */ | |
/*******************************************************************/ | |
/************************ global variables *************************/ | |
/*******************************************************************/ | |
/* Start global variable */ | |
/* End global variable */ | |
/*******************************************************************/ | |
/************************ static variables *************************/ | |
/*******************************************************************/ | |
/* Start static variable */ | |
int fd_kernel = 0; | |
int fd_rootfs = 0; | |
int fd_boorloader = 0; | |
int fd_nvram = 0; | |
static unsigned long s_FlashTotalSize; | |
static unsigned long s_FlashBlockSize; | |
static unsigned char *s_BlockBuff; | |
/* End static variable */ | |
int HMX_UPGRADE_Flash_Kernel(unsigned long offset, unsigned int size, unsigned char * data ); | |
int HMX_UPGRADE_Flash_Rootfs(unsigned long offset, unsigned int size, unsigned char * data ); | |
int HMX_UPGRADE_Flash_BootLoader(unsigned long offset, unsigned int size, unsigned char * data ); | |
unsigned char * HMX_UPGRADE_Get_Deactivated_Kernel_MTD(void) | |
{ | |
return TARGET_KERNEL_MTD; | |
} | |
unsigned char * HMX_UPGRADE_Get_Deactivated_Rootfs_MTD(void) | |
{ | |
return TARGET_ROOTFS_UBI_MTD; | |
} | |
/*******************************************************************/ | |
/************************ static funtions **************************/ | |
/*******************************************************************/ | |
int HMX_UPGRADE_NVRAM_Write(unsigned long offset, unsigned char * data, unsigned int size ) | |
{ | |
int ret; | |
struct mtd_info_user info; | |
unsigned long block_size, write_size; | |
unsigned long mov_offset, remain_size; | |
printf("[%s] offset %08x, size %d, data = %02x\n",__FUNCTION__, offset, size, data[0] ); | |
/* */ | |
if ( fd_nvram == 0 ) | |
{ | |
fd_nvram = open(TARGET_NVRAM_MTD, (O_RDWR | O_SYNC) ); | |
if( fd_nvram < 0 ) | |
{ | |
printf( "Failed to open!\n" ); | |
return -1; | |
} | |
} | |
ret = ioctl(fd_nvram, MEMGETINFO,(void *)&info); | |
if(ret < 0) | |
{ | |
printf("can't get info data! (%d)\n", ret); | |
return -1; | |
} | |
remain_size = size; | |
mov_offset = offset; | |
while(remain_size > 0) | |
{ | |
/* offsetÀÌ block ³Ñ¾î¼¸é ¾ÈµÈ´Ù.. */ | |
write_size = info.erasesize; | |
write_size -= ((mov_offset + info.erasesize)%info.erasesize); | |
/* ¸¶Áö¸·Àº ³ª¸ÓÁö ¸¸Å.. */ | |
if( remain_size < write_size) | |
{ | |
write_size = remain_size; | |
} | |
printf(" write : offset - 0x%x, size %d\n", mov_offset, write_size); | |
ret = lseek(fd_nvram, mov_offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("can't seek position! (%d)\n", ret); | |
return -1; | |
} | |
ret = write(fd_nvram, data+(mov_offset-offset), write_size); | |
if(ret < 0) | |
{ | |
printf("can't write data! (%d)\n", ret); | |
return -1; | |
} | |
mov_offset += write_size; | |
remain_size -= write_size; | |
} | |
return 0; | |
} | |
int HMX_UPGRADE_NVRAM_Read(unsigned long offset, unsigned char * data, unsigned int size ) | |
{ | |
int ret; | |
struct mtd_info_user info; | |
unsigned long block_size, write_size; | |
unsigned long mov_offset, remain_size; | |
printf("[%s] offset %08x, size %d, data = %02x\n",__FUNCTION__, offset, size, data[0] ); | |
/* */ | |
if ( fd_nvram == 0 ) | |
{ | |
fd_nvram = open(TARGET_NVRAM_MTD, (O_RDWR | O_SYNC) ); | |
if( fd_nvram < 0 ) | |
{ | |
printf( "Failed to open!\n" ); | |
return -1; | |
} | |
} | |
ret = lseek(fd_nvram, offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("can't seek position! (%d)\n", ret); | |
return -1; | |
} | |
ret = read(fd_nvram, data, size); | |
if(ret < 0) | |
{ | |
printf("can't read data! (%d)\n", ret); | |
return ret; | |
} | |
return 0; | |
} | |
int HMX_UPGRADE_Flash_Kernel(unsigned long offset, unsigned int size, unsigned char * data ) | |
{ | |
int ret; | |
unsigned char * com_buf; | |
printf("[%s] offset %08x, size %d, data = %02x\n",__FUNCTION__, offset, size, data[0] ); | |
/* */ | |
if ( fd_kernel == 0 ) | |
{ | |
fd_kernel = open(HMX_UPGRADE_Get_Deactivated_Kernel_MTD(), (O_RDWR | O_SYNC) ); | |
if( fd_kernel < 0 ) | |
{ | |
printf( "Failed to open fd_kernel!\n" ); | |
return -1; | |
} | |
} | |
ret = lseek(fd_kernel, offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("failed seeking position! (%d)\n", ret); | |
return ret; | |
} | |
ret = write(fd_kernel, data, size); | |
if(ret < 0) | |
{ | |
printf("can't write data! (%d)\n", ret); | |
return ret; | |
} | |
/* Read and Compare */ | |
ret = lseek(fd_kernel, offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("failed seeking position! (%d)\n", ret); | |
return ret; | |
} | |
com_buf = malloc(size); | |
if (com_buf == NULL ) | |
{ | |
printf("malloc faied!!! \n"); | |
return -1; | |
} | |
ret = read(fd_kernel, com_buf, size); | |
if(ret < 0) | |
{ | |
printf("can't read data! (%d)\n", ret); | |
return ret; | |
} | |
if ( memcmp(data, com_buf, size) != 0 ) | |
{ | |
printf("Written data is differnet!! \n"); | |
return -1; | |
} | |
free(com_buf); | |
return 0; | |
} | |
int HMX_UPGRADE_Flash_BootLoader(unsigned long offset, unsigned int size, unsigned char * data ) | |
{ | |
int ret; | |
struct mtd_info_user info; | |
unsigned long block_size, write_size; | |
unsigned long mov_offset, remain_size; | |
printf ( "SKIP BOOT LOADER... \n"); | |
printf("[%s] offset %08x, size %d, data = %02x\n",__FUNCTION__, offset, size, data[0] ); | |
return 0; | |
/* */ | |
if ( fd_boorloader == 0 ) | |
{ | |
fd_boorloader = open(TARGET_BOOT_LOADER_MTD, (O_RDWR | O_SYNC) ); | |
if( fd_boorloader < 0 ) | |
{ | |
printf( "Failed to open!\n" ); | |
return -1; | |
} | |
} | |
ret = ioctl(fd_boorloader, MEMGETINFO,(void *)&info); | |
if(ret < 0) | |
{ | |
printf("can't get info data! (%d)\n", ret); | |
return -1; | |
} | |
remain_size = size; | |
mov_offset = offset; | |
while(remain_size > 0) | |
{ | |
/* offsetÀÌ block ³Ñ¾î¼¸é ¾ÈµÈ´Ù.. */ | |
write_size = info.erasesize; | |
write_size -= ((mov_offset + info.erasesize)%info.erasesize); | |
/* ¸¶Áö¸·Àº ³ª¸ÓÁö ¸¸Å.. */ | |
if( remain_size < write_size) | |
{ | |
write_size = remain_size; | |
} | |
printf(" write : offset - 0x%x, size %d\n", mov_offset, write_size); | |
ret = lseek(fd_boorloader, mov_offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("can't seek position! (%d)\n", ret); | |
return -1; | |
} | |
ret = write(fd_boorloader, data+(mov_offset-offset), write_size); | |
if(ret < 0) | |
{ | |
printf("can't write data! (%d)\n", ret); | |
return -1; | |
} | |
mov_offset += write_size; | |
remain_size -= write_size; | |
} | |
return 0; | |
} | |
int HMX_UPGRADE_Flash_Rootfs(unsigned long offset, unsigned int size, unsigned char * data ) | |
{ | |
int ret; | |
unsigned char * com_buf; | |
printf("[%s] offset %08x, size %d, data = %02x\n",__FUNCTION__, offset, size, data[0] ); | |
/* */ | |
if ( fd_rootfs == 0 ) | |
{ | |
fd_rootfs = open(HMX_UPGRADE_Get_Deactivated_Rootfs_MTD(), (O_RDWR | O_SYNC) ); | |
if( fd_rootfs < 0 ) | |
{ | |
printf( "Failed to open fd_kernel!\n" ); | |
return -1; | |
} | |
} | |
ret = lseek(fd_rootfs, offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("failed seeking position! (%d)\n", ret); | |
return ret; | |
} | |
ret = write(fd_rootfs, data, size); | |
if(ret < 0) | |
{ | |
printf("can't write data! (%d)\n", ret); | |
return ret; | |
} | |
/* Read and Compare */ | |
ret = lseek(fd_rootfs, offset, SEEK_SET); | |
if(ret < 0) | |
{ | |
printf("failed seeking position! (%d)\n", ret); | |
return ret; | |
} | |
com_buf = malloc(size); | |
if (com_buf == NULL ) | |
{ | |
printf("malloc faied!!! \n"); | |
return -1; | |
} | |
ret = read(fd_rootfs, com_buf, size); | |
if(ret < 0) | |
{ | |
printf("can't read data! (%d)\n", ret); | |
return ret; | |
} | |
if ( memcmp(data, com_buf, size) != 0 ) | |
{ | |
printf("Written data is differnet!! \n"); | |
return -1; | |
} | |
free(com_buf); | |
return 0; | |
} | |
/*@}*/ |