| /*******************************************************************/ |
| /************************* 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" |
| #define TARGET_NVRAM_MTDC "/dev/mtd1" |
| |
| /* 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 */ |
| int libupgrade_verbose = 1; |
| /* End global variable */ |
| |
| |
| /*******************************************************************/ |
| /************************ static variables *************************/ |
| /*******************************************************************/ |
| /* Start static variable */ |
| int fd_kernel = 0; |
| int fd_rootfs = 0; |
| int fd_boorloader = 0; |
| int fd_nvram = 0; |
| int fd_nvram_c = -1; |
| |
| 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; |
| |
| if (libupgrade_verbose) 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; |
| } |
| } |
| |
| if ( fd_nvram_c < 0 ) |
| { |
| fd_nvram_c = open(TARGET_NVRAM_MTDC, (O_RDWR | O_SYNC) ); |
| if( fd_nvram_c < 0 ) |
| { |
| printf( "Failed to open!\n" ); |
| return -1; |
| } |
| } |
| |
| ret = ioctl(fd_nvram_c, 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; |
| } |
| |
| if (libupgrade_verbose) 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; |
| |
| if (libupgrade_verbose) 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; |
| |
| |
| } |
| |
| |
| |
| /*@}*/ |