关于MTD flash 格式化命令flash_eraseall 的问题

本文探讨了使用flash_eraseall命令时出现的错误问题:无法获取mtd设备信息。通过检查命令格式及使用cat /proc/mtd命令查看分区信息的方法来解决此问题。
部署运行你感兴趣的模型镜像

错误问题如下:

使用flash_eraseall  -j  /dev/mtdblock4出现错误   flash_eraseall  /dev/mtdblock4:unable to get mtd device info


使用cat /proc/mtd来查看分区消息和mtd 各设备块的大小,



开始的使用命令是错误的。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

Flash_Tool(V5.1)使用方法: 1、打开升级平台Flash_Tool(V5.1)然后在Download Agent处点击选MTK_ALLnOne_DA.bin文件。 2、点击Scatter File选升级软件自带的scatMTK53_09A_GEMINI.txt文件。随后平台会自动调用BIN文件(升级文件)。 3、第三个是选串口,(具体查看设备管理器里的升级线安装在哪个COM口)。 4、注意Options选项里的Format FAT中选Do Not Format FAT,意思是不要格式化,否则会导致信号弱,改变参数。 5、数据备份设置 点击Options,点选Backup and Restore,选择Backup—Download/Format—Restore。 6、升级:点击Download后,按开机键,首先出现灰色条(备份数据)然后出现红条(初始化),出现蓝条时开始升级,升级完成后出现绿色条(格式化),格式化后出现灰色条(数据还原),最后提示OK。 7、格式化:点击Format后,按开机键,首先出现灰色条(备份数据)然后出现红条(初始化),格式化时出现绿色条,格式化后出现灰色条(数据还原),最后提示OK。 8、读取BIN文件(软件) 找一台开机正常的手机,利用这个平台可将所有MTK手机的软件读取出来,作为其他手机升级之用。 连接好升级线和手机,点击Read Back选项,双击下面的勾选项,会弹出一个窗口,意思是保存的路径。选好保存的路径后,点击Read Back键,按开机键即可读取字库中的数据。 9、Memory Test 字库测试,可查看字库的分区结构,检测字库有无坏区。 按START后,再按开机键即可测试。
解析以下文件: #include <sys/ioctl.h> /* for ioctl() */ #include <fcntl.h> /* for O_RDONLY */ #include <unistd.h> /* for close() */ #include <stdio.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> #include <malloc.h> #include <arpa/inet.h> #include "flashio_name_path.h" #include "rax.h" #include "nvmp_utils.h" /* for NSD_DEBUG() */ #include "flashio.h" static rax *rax_ctx = NULL; static TP_HEAD_INFO *pt_header = NULL; #define UC_PART_PATH "/tmp/uc_file/UC" //通用接口返回当前分区有效数据大小,但是分区数据用文件系统存储的禁止用次接口获取(例如在ubifs中存储uc) int get_pt_table_size_general(char *name) { int pt_size = 0; pt_usr_table *pt_utb = NULL; char mtd_type = 0; if (rax_ctx == NULL || pt_header == NULL) return FLASH_INIT_ERROR; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if (pt_utb == raxNotFound) { FLASHIO_ERROR("not found %s",name); return FLASH_NOT_EXIT; } if (pt_utb->pt_table != NULL) mtd_type = GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->pt_table->partition_attribute); else if (pt_utb->vol_table != NULL) mtd_type = GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->vol_table->partition_attribute); else return FLASH_NORMAL; switch (mtd_type) { case PARTITION_ITEM_TYPE_MTD: pt_size = pt_utb->pt_table->valid_size; break; case PARTITION_ITEM_TYPE_UBI: pt_size = pt_utb->vol_table->valid_size; break; } return pt_size; } //通用接口返回当前分区有效长度大小,但是分区数据用文件系统存储的禁止用次接口获取(例如在ubifs中存储uc) int get_pt_table_all_size_general(char *name) { int pt_size = 0; pt_usr_table *pt_utb = NULL; char mtd_type = 0; if (rax_ctx == NULL || pt_header == NULL) return 0; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if (pt_utb == raxNotFound) { FLASHIO_ERROR("not found %s",name); return FLASH_INIT_ERROR; } if (pt_utb->pt_table != NULL) mtd_type = GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->pt_table->partition_attribute); else if (pt_utb->vol_table != NULL) mtd_type = GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->vol_table->partition_attribute); else return FLASH_NORMAL; switch (mtd_type) { case PARTITION_ITEM_TYPE_MTD: pt_size = pt_utb->pt_table->partition_valid_size; break; case PARTITION_ITEM_TYPE_UBI: pt_size = pt_utb->vol_table->vol_valid_size; break; } return pt_size; } //通用接口返回当前分区大小,但是分区数据用文件系统存储的禁止用次接口获取(例如在ubifs中存储uc) int get_pt_table_all_length_general(char *name) { int pt_size = 0; pt_usr_table *pt_utb = NULL; char mtd_type = 0; if (rax_ctx == NULL || pt_header == NULL) return FLASH_INIT_ERROR; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if (pt_utb == raxNotFound) { FLASHIO_ERROR("not found %s",name); return FLASH_NOT_EXIT; } if (pt_utb->pt_table != NULL) mtd_type = GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->pt_table->partition_attribute); else if (pt_utb->vol_table != NULL) mtd_type = GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->vol_table->partition_attribute); else return 0; switch (mtd_type) { case PARTITION_ITEM_TYPE_MTD: pt_size = pt_utb->pt_table->partition_length; break; case PARTITION_ITEM_TYPE_UBI: pt_size = pt_utb->vol_table->vol_size; break; } return pt_size; } //通用接口返回当前分区偏移值,但是分区数据用文件系统存储的禁止用次接口获取(例如在ubifs中存储uc) int get_pt_table_offset_general(char *name) { int pt_offset = 0; pt_usr_table *pt_utb = NULL; if (rax_ctx == NULL || pt_header == NULL) return FLASH_INIT_ERROR; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if (pt_utb == raxNotFound) { FLASHIO_ERROR("not found %s",name); return FLASH_NOT_EXIT; } switch (GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->pt_table->partition_attribute)) { case PARTITION_ITEM_TYPE_MTD: pt_offset = pt_utb->pt_table->partition_offset; break; case PARTITION_ITEM_TYPE_UBI: pt_offset = 0; } return pt_offset; } //通用接口读取当前flash数据 int read_flash_pt_data_general(void *arg_index,char *filename) { int fd = 0,ret = FLASH_IO_ERROR; ARG *arg = (ARG *)arg_index; pt_usr_table *pt_utb = NULL; if (filename) { fd = open(filename,O_RDONLY,0666); if (fd <= 0) { FLASHIO_ERROR("not open %s",filename); goto exit; } ret = read(fd,arg->rw_buf,arg->length); if (ret != arg->length) { FLASHIO_ERROR("read %d is not equal %d",arg->length,ret); goto exit; } ret = FLASH_NORMAL; } else { if (rax_ctx == NULL || pt_header == NULL) return FLASH_INIT_ERROR; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)arg->pt_name,strlen(arg->pt_name)); if (pt_utb == raxNotFound) goto exit; fd = open(FLASH_DEV,O_RDONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); goto exit; } arg->mtd_info = pt_utb->mtd_info; FLASHIO_INFO("will read %s 0x%x 0x%x",arg->pt_name,arg->offset,arg->length); ret = ioctl(fd,SLP_IOC_FLASH_READ,arg); if (ret) goto exit; ret = FLASH_NORMAL; } exit: if (fd > 0) close(fd); return ret; } //通用接口写入flash数据(新接口不进行擦除,调用需要先进行擦除) int write_pt_table_data_general(ARG *arg,char *file_name,char force_flag) { int fd = 0,ret = 0; if (file_name) { //清空文件 fd = open(file_name,O_CREAT | O_RDWR | O_SYNC,0666); if (fd <= 0) { FLASHIO_ERROR("pt %s is renew",file_name); ret = FLASH_IO_ERROR; goto exit; } ret = lseek(fd,arg->offset,SEEK_SET); if (ret != arg->offset) goto exit; ret = write(fd,arg->rw_buf,arg->length); if (ret != arg->length) goto exit; fsync(fd); } else { if (rax_ctx == NULL || pt_header == NULL) return FLASH_INIT_ERROR; pt_usr_table *pt_utb = NULL; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)arg->pt_name,strlen(arg->pt_name)); if (pt_utb == raxNotFound) goto exit; if (force_flag == 0 && ((pt_utb->vol_table != NULL && GET_PARTITION_ATTRIBUTE(DATA_FORBID,pt_utb->vol_table->partition_attribute)) || (pt_utb->pt_table != NULL && GET_PARTITION_ATTRIBUTE(DATA_FORBID,pt_utb->pt_table->partition_attribute)))) { FLASHIO_ERROR("the partition is forbid change"); return -1; } fd = open(FLASH_DEV,O_WRONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); ret = FLASH_IO_ERROR; goto exit; } arg->mtd_info = pt_utb->mtd_info; FLASHIO_INFO("will write %s 0x%x 0x%x",arg->pt_name,arg->offset,arg->length); ret = ioctl(fd,SLP_IOC_FLASH_WRITE,arg); if (ret) { FLASHIO_ERROR("write %s error",arg->pt_name); goto exit; } } ret = 0; exit: if (fd > 0) close(fd); return ret; } /* 通用接口擦除flash * note:nand可能有坏块,此时ubi格式化不能使用全长度,需要把坏块去除,引入最小长度参数保证能写入镜像 * 不依赖ubiformat格式化,因为ubiformat会使用scan测试块,此时可能会因为写入过垃圾数据失败 */ int erase_pt_table_data_general(ARG *arg,char *file_name,char force_flag,int min_erase_block) { int fd = 0,ret = 0; if (arg == NULL) return FLASH_IO_ERROR; if (file_name) { //清空文件 int byte = 0; char space = 0xff; if (arg->length == 0) { //全文件清空 fd = open(file_name,O_CREAT | O_RDWR | O_TRUNC,0666); if (fd <= 0) { FLASHIO_ERROR("pt %s is renew",file_name); ret = FLASH_IO_ERROR; goto exit; } } else { //模拟flash fd = open(file_name,O_CREAT | O_RDWR,0666); if (fd <= 0) { FLASHIO_ERROR("pt %s is renew",file_name); ret = FLASH_IO_ERROR; goto exit; } ret = lseek(fd,arg->offset,SEEK_SET); if (ret != arg->offset) goto exit; for (byte = 0;byte < arg->length;byte++) write(fd,&space,1); fsync(fd); } } else { pt_usr_table *pt_utb = NULL; if (rax_ctx == NULL || pt_header == NULL) return -1; pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)arg->pt_name,strlen(arg->pt_name)); if (pt_utb == raxNotFound) goto exit; if (force_flag == 0 && ((pt_utb->vol_table != NULL && GET_PARTITION_ATTRIBUTE(DATA_FORBID,pt_utb->vol_table->partition_attribute)) || (pt_utb->pt_table != NULL && GET_PARTITION_ATTRIBUTE(DATA_FORBID,pt_utb->pt_table->partition_attribute)))) { FLASHIO_ERROR("the partition is forbid change"); return FLASH_IO_ERROR; } fd = open(FLASH_DEV,O_WRONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); ret = FLASH_IO_ERROR; goto exit; } arg->mtd_info = pt_utb->mtd_info; arg->min_erase_block = min_erase_block; FLASHIO_INFO("will erase %s 0x%x 0x%x(0x%x)",arg->pt_name,arg->offset,arg->length,min_erase_block); ret = ioctl(fd,SLP_IOC_FLASH_ERASE,arg); if (ret) { FLASHIO_ERROR("not erase flash %s",arg->pt_name); goto exit; } } ret = 0; exit: if (fd > 0) close(fd); return ret; } void *get_tp_header_ctx() { return pt_header; } void* find_pt_table_from_tpheader(TP_HEAD_INFO *tpheader,char *pt_name) { partition_table_item *pt_table = NULL; int partition_id = 0; if (tpheader == NULL) return NULL; for (partition_id = 0;partition_id < tpheader->partition_num;partition_id++) { pt_table = &(tpheader->table[partition_id]); if (strcmp(pt_table->partition_name,pt_name) == 0) break; } if (partition_id == tpheader->partition_num) pt_table = NULL; return pt_table; } void* find_vol_table_from_pt_table(partition_table_item *pt_table,char *vol_name) { ubi_vol *vol = NULL; int vol_id = 0; if (pt_table == NULL) return NULL; for (vol_id = 0;vol_id < UBI_MAX_NUM;vol_id++) { vol = &(pt_table->vol_table[vol_id]); if (strcmp(vol->vol_name,vol_name) == 0) break; } if (vol_id == UBI_MAX_NUM) vol = NULL; return vol; } void *get_flash_partition_from_radix(char *name) { return raxFind(rax_ctx,(unsigned char *)name,strlen(name)); } static int init_pt_table() { int fd = 0,ret = 0; ARG arg = {0}; if (pt_header != NULL) free(pt_header); pt_header = malloc(sizeof(TP_HEAD_INFO)); if (pt_header == NULL) return FLASH_INIT_ERROR; fd = open(FLASH_DEV,O_RDONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); ret = FLASH_INIT_ERROR; goto exit; } strcpy(arg.pt_name,"pt_table"); ret = ioctl(fd,SLP_IOC_FLASH_GET_INFO,&arg); if (ret) { FLASHIO_ERROR("not found pt_table"); goto exit; } arg.offset = 0; arg.rw_buf = (unsigned char *)pt_header; arg.length = sizeof(TP_HEAD_INFO); ret = ioctl(fd,SLP_IOC_FLASH_READ,&arg); if (ret) goto exit; pt_header = realloc(pt_header,sizeof(TP_HEAD_INFO) + sizeof(partition_table_item) * ntohs(pt_header->partition_num)); if (pt_header == NULL) goto exit; arg.offset = 0; arg.rw_buf = (unsigned char *)pt_header; arg.length = sizeof(TP_HEAD_INFO) + sizeof(partition_table_item) * ntohs(pt_header->partition_num); ret = ioctl(fd,SLP_IOC_FLASH_READ,&arg); switch_partition_table_to_local(pt_header); if (ret || pt_header->partition_num > 32) { ret = FLASH_INIT_ERROR; goto exit; } FLASHIO_INFO("pt_tabel is init finish"); //factory启动阶段已保证分区数据可靠性,此处不在校验 close(fd); return 0; exit: if (pt_header) { free(pt_header); pt_header = NULL; } if(fd > 0) close(fd); return ret; } static int add_radix_node(pt_usr_table *utb,char *name) { pt_usr_table *pt_utb = NULL; int ret = 0; pt_utb = calloc(sizeof(pt_usr_table),1); if (pt_utb == NULL) { ret = FLASH_INIT_ERROR; goto exit; } memcpy(pt_utb,utb,sizeof(pt_usr_table)); ret = raxInsert(rax_ctx,(unsigned char *)name,strlen(name),pt_utb,NULL); if (ret == 1) ret = 0; FLASHIO_DEBUG("create %s node finish code %d",name,ret); exit: if (pt_utb && ret != 0) free(pt_utb); return ret; } static void destroy_radix_node(char *name) { pt_usr_table *pt_utb = raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if (pt_utb == raxNotFound) return; raxRemove(rax_ctx,(unsigned char *)name,strlen(name),NULL); if (pt_utb->free_flag && pt_utb->pt_table) free(pt_utb->pt_table); if (pt_utb->free_flag && pt_utb->vol_table) free(pt_utb->vol_table); free(pt_utb); FLASHIO_DEBUG("delete %s node finish\n",name); } static void destroy_all_radix_node() { raxIterator rax_it = {0}; pt_usr_table *pt_utb = NULL; raxStart(&rax_it,rax_ctx); raxSeek(&rax_it,"^",NULL,0); while (raxNext(&rax_it) != 0) { pt_utb = (pt_usr_table *)rax_it.data; if (pt_utb->free_flag && pt_utb->pt_table) free(pt_utb->pt_table); else if (pt_utb->free_flag && pt_utb->vol_table) free(pt_utb->pt_table); } raxStop(&rax_it); raxFree(rax_ctx); rax_ctx = NULL; FLASHIO_INFO("destroy all node,flash module is not use"); } static int create_pt_usr_manager() { partition_table_item *table = NULL; ubi_vol *vol_table = NULL; ARG arg = {0}; pt_usr_table pt_utb = {0}; int ret = 0,fd = 0; short pt_id = 0,vol_id = 0; fd = open(FLASH_DEV,O_RDONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); ret = -1; goto exit; } for (pt_id = 0;pt_id < pt_header->partition_num;pt_id++) { table = &(pt_header->table[pt_id]); if (table->partition_length == 0) continue; switch (GET_PARTITION_ATTRIBUTE(FLASH_TYPE,table->partition_attribute)) { case PARTITION_ITEM_TYPE_MTD: strcpy(arg.pt_name,table->partition_name); ret = ioctl(fd,SLP_IOC_FLASH_GET_INFO,&arg); if (ret) { FLASHIO_ERROR("not found %s",table->partition_name); goto exit; } pt_utb.pt_table = table; pt_utb.mtd_info = arg.mtd_info; pt_utb.free_flag = 0; pt_utb.mtd_id = arg.mtd_id; pt_utb.vol_table = NULL; ret = add_radix_node(&pt_utb,table->partition_name); if (ret) goto exit; break; case PARTITION_ITEM_TYPE_UBI: for (vol_id = 0;vol_id < UBI_MAX_NUM;vol_id++) { vol_table = &(table->vol_table[vol_id]); if (strlen(vol_table->vol_name) == 0) continue; strcpy(arg.pt_name,vol_table->vol_name); ret = ioctl(fd,SLP_IOC_FLASH_GET_INFO,&arg); if (ret) { FLASHIO_ERROR("not found %s",vol_table->vol_name); goto exit; } pt_utb.vol_table = vol_table; pt_utb.mtd_info = arg.mtd_info; pt_utb.free_flag = 0; pt_utb.mtd_id = arg.mtd_id; pt_utb.ubi_id = arg.ubi_id; pt_utb.pt_table = NULL; ret = add_radix_node(&pt_utb,arg.pt_name); if (ret) goto exit; } strcpy(arg.pt_name,table->partition_name); ret = ioctl(fd,SLP_IOC_FLASH_GET_INFO,&arg); if (ret) { FLASHIO_ERROR("not found %s",table->partition_name); goto exit; } pt_utb.pt_table = table; pt_utb.mtd_info = arg.mtd_info; pt_utb.free_flag = 0; pt_utb.mtd_id = arg.mtd_id; pt_utb.vol_table = NULL; ret = add_radix_node(&pt_utb,table->partition_name); if (ret) goto exit; break; default: ret = FLASH_INIT_ERROR; FLASHIO_ERROR("not known mtd %s type %x",table->partition_name,table->partition_attribute); goto exit; } } close(fd); FLASHIO_INFO("create all radix node finish\n"); return 0; exit: if (fd > 0) close(fd); destroy_all_radix_node(); return ret; } static int init_flash_io() { int ret = 0; rax_ctx = raxNew(); if (rax_ctx == NULL) { FLASHIO_ERROR("rax is not create"); goto exit; } ret = init_pt_table(); if (ret) goto exit; ret = create_pt_usr_manager(); if (ret) goto exit; flashio_test_register_handler(); FLASHIO_INFO("flash io module init finish\n"); return 0; exit: if (rax_ctx) { raxFree(rax_ctx); rax_ctx = NULL; } if (pt_header) { free(pt_header); pt_header = NULL; } FLASHIO_INFO("init flash module failed"); exit(EXIT_FAILURE); } void print_pt_table_debug(void) { raxIterator rax_it = {0}; pt_usr_table *pt_utb = NULL; if (rax_ctx == NULL) return; raxStart(&rax_it,rax_ctx); raxSeek(&rax_it,"^",NULL,0); printf("%-32s%-16s%-16s%-16s%-16s%-16s%-16s\n","pt_table_name","mtd_type","start","end","forbid","check","deled"); while (raxNext(&rax_it) != 0) { pt_utb = (pt_usr_table *)rax_it.data; if (pt_utb->pt_table) { printf("%-32s0x%-14x0x%-14x0x%-14x",pt_utb->pt_table->partition_name,GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->pt_table->partition_attribute),pt_utb->pt_table->partition_offset,pt_utb->pt_table->partition_offset + pt_utb->pt_table->partition_length); printf("0x%-14x0x%-14x0x%-14x\n",GET_PARTITION_ATTRIBUTE(DATA_FORBID,pt_utb->pt_table->partition_attribute),GET_PARTITION_ATTRIBUTE(DATA_CHECK,pt_utb->pt_table->partition_attribute),GET_PARTITION_ATTRIBUTE(DATA_DEL,pt_utb->pt_table->partition_attribute)); } else if (pt_utb->vol_table) { printf("%-32s0x%-14x0x%-14x0x%-14x",pt_utb->vol_table->vol_name,GET_PARTITION_ATTRIBUTE(FLASH_TYPE,pt_utb->vol_table->partition_attribute),0,pt_utb->vol_table->vol_size); printf("0x%-14x0x%-14x0x%-14x\n",GET_PARTITION_ATTRIBUTE(DATA_FORBID,pt_utb->vol_table->partition_attribute),GET_PARTITION_ATTRIBUTE(DATA_CHECK,pt_utb->vol_table->partition_attribute),GET_PARTITION_ATTRIBUTE(DATA_DEL,pt_utb->vol_table->partition_attribute)); } } raxStop(&rax_it); } S32 flash_write_tpheader(U8 *buf, U32 buflen) { ARG arg = {0}; int ret = 0; arg.offset = 0; arg.length = buflen; strcpy(arg.pt_name,"pt_table"); arg.rw_buf = buf; switch_partition_table_to_network((TP_HEAD_INFO *)buf); ret = write_pt_table_data_general(&arg,NULL,0); switch_partition_table_to_local((TP_HEAD_INFO *)buf); return ret; } S32 flash_read_tpheader(U8 *buf, U32 buflen) { ARG arg = {0}; int ret = 0; arg.offset = 0; arg.rw_buf = buf; arg.length = buflen; strcpy(arg.pt_name,"pt_table"); ret = read_flash_pt_data_general(&arg,NULL); if (ret == 0) switch_partition_table_to_local((TP_HEAD_INFO *)buf); return ret; } U32 get_tpheader_size(void) { return get_pt_table_all_size_general("pt_table"); } S32 flash_read_uc(U8 *buf, U32 buflen, U32 sub_index) { ARG arg = {0}; #ifdef USE_NAND_FLASH arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; if (sub_index == 0) return read_flash_pt_data_general(&arg,UC_USR_CONFIG); else return read_flash_pt_data_general(&arg,UC_USR_CONFIG_BAK); #else arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; if (sub_index == 0) strcpy(arg.pt_name,PT_UC); else strcpy(arg.pt_name,PT_UC_BAK); return read_flash_pt_data_general(&arg,NULL); #endif } U32 get_uc_size(void) { #ifdef USE_NAND_FLASH return UC_SIZE; #else return get_pt_table_all_size_general(PT_UC); #endif } S32 flash_write_uc(U8 *buf, U32 buflen, U32 sub_index) { ARG arg = {0}; #ifdef USE_NAND_FLASH arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; if (sub_index == 0) return write_pt_table_data_general(&arg,UC_USR_CONFIG,0); else return write_pt_table_data_general(&arg,UC_USR_CONFIG_BAK,0); #else arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; if (sub_index == 0) strcpy(arg.pt_name,PT_UC); else strcpy(arg.pt_name,PT_UC_BAK); return write_pt_table_data_general(&arg,NULL,1); #endif } S32 flash_erase_uc() { ARG arg = {0}; arg.offset = 0; #ifdef USE_NAND_FLASH arg.length = 0; int ret = erase_pt_table_data_general(&arg,UC_USR_CONFIG,0,0); if (ret) return ret; ret = erase_pt_table_data_general(&arg,UC_USR_CONFIG_BAK,0,0); return ret; #else strcpy(arg.pt_name,PT_UC); arg.length = get_uc_size(); return erase_pt_table_data_general(&arg,NULL,1,0); #endif } #ifdef MCU_SUPPORT S32 flash_read_mcu(U8 *buf,U32 buflen) { ARG arg = {0}; arg.offset = 0; arg.rw_buf = buf; arg.length = buflen; strcpy(arg.pt_name,PT_MCU); return read_flash_pt_data_general(&arg,NULL); } #endif S32 flash_write_radio(U8 *buf, U32 buflen) { ARG arg = {0}; arg.offset = 0; arg.rw_buf = buf; arg.length = buflen; strcpy(arg.pt_name,PT_ISP); return write_pt_table_data_general(&arg,NULL,0); } S32 flash_read_radio(U8 *buf, U32 buflen) { ARG arg = {0}; arg.offset = 0; arg.rw_buf = buf; arg.length = buflen; strcpy(arg.pt_name,PT_ISP); return read_flash_pt_data_general(&arg,NULL); } U32 get_radio_size(void) { return get_pt_table_all_size_general(PT_ISP); } S32 flash_write_af(U8 *buf, U32 buflen) { ARG arg = {0}; #ifdef USE_NAND_FLASH arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; return write_pt_table_data_general(&arg,PT_AF_FILE,0); #else arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; strcpy(arg.pt_name,PT_AF); return write_pt_table_data_general(&arg,NULL,0); #endif } S32 flash_read_af(U8 *buf, U32 buflen) { ARG arg = {0}; #ifdef USE_NAND_FLASH arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; return read_flash_pt_data_general(&arg,PT_AF_FILE); #else arg.offset = 0; arg.length = buflen; arg.rw_buf = buf; strcpy(arg.pt_name,PT_AF); return read_flash_pt_data_general(&arg,NULL); #endif } U32 get_af_size(void) { #ifdef USE_NAND_FLASH return AF_DATA_MAX_SIZE; #else return get_pt_table_all_size_general(PT_AF); #endif } #ifdef VIGI_USR_DEF_AUDIO_ALARM #define MAX_USR_ALARM_NUM 3 S32 flash_write_usr_audio(U8 *buf, U32 buflen, U32 sub_index) { ARG arg = {0}; char file_name[128] = {0}; arg.rw_buf = buf; arg.length = buflen; snprintf(file_name,128,"%s_%d.audio",USR_AUDIO_FILE,sub_index); return write_pt_table_data_general(&arg,file_name,0); } S32 flash_read_usr_audio(U8 *buf, U32 buflen, U32 sub_index) { ARG arg = {0}; char file_name[128] = {0}; arg.rw_buf = buf; arg.length = buflen; snprintf(file_name,128,"%s_%d.audio",USR_AUDIO_FILE,sub_index); return read_flash_pt_data_general(&arg,file_name); } S32 flash_erase_usr_audio() { int ret = 0; char file_name[128] = {0}; short usr_id = 0; for (usr_id = 0;usr_id < MAX_USR_ALARM_NUM;usr_id++) { sprintf(file_name,"%s_%d.audio",USR_AUDIO_FILE,usr_id); ret = erase_pt_table_data_general(NULL,file_name,0,0); if (ret) return ret; } return 0; } #endif S32 flash_write_facinfo(U8 *buf, U32 buflen) { ARG arg = {0}; arg.offset = 0; arg.rw_buf = buf; arg.length = buflen; strcpy(arg.pt_name,PT_FACTORY_INFO); return write_pt_table_data_general(&arg,NULL,1); } S32 flash_read_facinfo(U8 *buf, U32 buflen) { ARG arg = {0}; arg.offset = 0; arg.rw_buf = buf; arg.length = buflen; strcpy(arg.pt_name,PT_FACTORY_INFO); return read_flash_pt_data_general(&arg,NULL); } U32 get_facinfo_size(void) { return get_pt_table_all_size_general(PT_FACTORY_INFO); } int del_flash_partition(char *name,int mtd_type) { ARG arg = {0}; int fd = 0,ret = -1; pt_usr_table *pt_utb = NULL; char cmd_buf[128] = {0}; fd = open(FLASH_DEV,O_WRONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); ret = -1; goto exit; } switch (mtd_type) { case PARTITION_ITEM_TYPE_MTD: pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if ((pt_utb != raxNotFound && GET_PARTITION_ATTRIBUTE(DATA_DEL,pt_utb->pt_table->partition_attribute) == 1) || pt_utb == raxNotFound) { FLASHIO_ERROR("the pt %s is not in pt_table or is deleted",name); ret = 0; goto exit; } strcpy(arg.pt_name,name); arg.mtd_info = pt_utb->mtd_info; ret = ioctl(fd,SLP_DEL_PARTITION,&arg); if (ret) { FLASHIO_ERROR("del %s error",arg.pt_name); goto exit; } destroy_radix_node(name); break; case PARTITION_ITEM_TYPE_UBI: pt_utb = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)name,strlen(name)); if (pt_utb == raxNotFound || (pt_utb->pt_table == NULL && pt_utb->vol_table == NULL)) { FLASHIO_ERROR("the pt %s is not in pt_table or is deleted",name); ret = 0; goto exit; } if (pt_utb->vol_table) { sprintf(cmd_buf,"ubirmvol /dev/ubi%d -N %s",pt_utb->ubi_id,pt_utb->vol_table->vol_name); ret = system(cmd_buf); if (ret) goto exit; } else if (pt_utb->pt_table) { sprintf(cmd_buf,"ubidetach -p /dev/mtd%d",pt_utb->mtd_id); ret = system(cmd_buf); if (ret) goto exit; arg.mtd_info = pt_utb->mtd_info; strcpy(arg.pt_name,pt_utb->pt_table->partition_name); ret = ioctl(fd,SLP_DEL_PARTITION,&arg); if (ret) { FLASHIO_ERROR("not dele %s from ubi%d",name,pt_utb->ubi_id); goto exit; } } destroy_radix_node(name); break; } exit: if (fd > 0) close(fd); return ret; } int add_flash_partition(void *new_table,void *vol_table,int ubi_min_block) { ARG arg = {0}; int fd = 0,ret = -1; partition_table_item *table = NULL,*table_tmp = NULL; ubi_vol *vol = NULL,*vol_tmp = NULL; pt_usr_table pt_utb = {0},*pt_utb_tmp = NULL; char cmd_buf[128] = {0}; fd = open(FLASH_DEV,O_WRONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); ret = -1; goto exit; } table = (partition_table_item *)new_table; switch (GET_PARTITION_ATTRIBUTE(FLASH_TYPE,table->partition_attribute)) { case PARTITION_ITEM_TYPE_MTD: if (raxFind(rax_ctx,(unsigned char *)table->partition_name,strlen(table->partition_name)) != raxNotFound) { FLASHIO_ERROR("the pt %s is added",table->partition_name); goto exit; } pt_utb_tmp = raxFind(rax_ctx,(unsigned char *)"pt_table",strlen("pt_table")); if (pt_utb_tmp == raxNotFound) goto exit; strcpy(arg.pt_name,table->partition_name); arg.offset = table->partition_offset; arg.length = table->partition_length; arg.mtd_info = pt_utb_tmp->mtd_info; ret = ioctl(fd,SLP_ADD_PARTITION,&arg); if (ret) { FLASHIO_ERROR("add %s error",arg.pt_name); goto exit; } table_tmp = calloc(sizeof(partition_table_item),1); if (table_tmp == NULL) goto del_pt_exit; memcpy(table_tmp,table,sizeof(partition_table_item)); pt_utb.mtd_info = arg.mtd_info; pt_utb.pt_table = table_tmp; pt_utb.mtd_id = arg.mtd_id; pt_utb.free_flag = 1; table_tmp = NULL; ret = add_radix_node(&pt_utb,pt_utb.pt_table->partition_name); if (ret) goto del_pt_exit; break; case PARTITION_ITEM_TYPE_UBI: if (raxFind(rax_ctx,(unsigned char *)table->partition_name,strlen(table->partition_name)) == raxNotFound) { pt_utb_tmp = raxFind(rax_ctx,(unsigned char *)"pt_table",strlen("pt_table")); if (pt_utb_tmp == raxNotFound) goto exit; strcpy(arg.pt_name,table->partition_name); arg.mtd_info = pt_utb_tmp->mtd_info; arg.offset = table->partition_offset; arg.length = table->partition_length; arg.min_erase_block = ubi_min_block; ret = ioctl(fd,SLP_ADD_PARTITION,&arg); if (ret) { FLASHIO_ERROR("add %s error",arg.pt_name); goto exit; } arg.offset = 0; ret = ioctl(fd,SLP_IOC_FLASH_ERASE,&arg); if (ret) { FLASHIO_ERROR("erase %s error",arg.pt_name); goto del_pt_exit; } sprintf(cmd_buf,"ubiformat /dev/mtd%d -y",arg.mtd_id); ret = system(cmd_buf); if (ret) goto del_pt_exit; sprintf(cmd_buf,"ubiattach -p /dev/mtd%d",arg.mtd_id); ret = system(cmd_buf); if (ret) goto del_pt_exit; ret = ioctl(fd,SLP_IOC_FLASH_GET_INFO,&arg); if (ret) { FLASHIO_ERROR("get %s error",arg.pt_name); goto del_pt_exit; } pt_utb.ubi_id = arg.ubi_id; if (pt_utb.ubi_id == -1) { FLASHIO_ERROR("the mtd ubi is invalid"); goto del_pt_exit; } table_tmp = calloc(sizeof(partition_table_item),1); if (table_tmp == NULL) goto del_pt_exit; memcpy(table_tmp,table,sizeof(partition_table_item)); pt_utb.mtd_info = arg.mtd_info; pt_utb.pt_table = table_tmp; pt_utb.mtd_id = arg.mtd_id; pt_utb.free_flag = 1; ret = add_radix_node(&pt_utb,pt_utb.pt_table->partition_name); if (ret) goto del_pt_exit; table_tmp = NULL; pt_utb_tmp = &pt_utb; } else pt_utb_tmp = (pt_usr_table *)raxFind(rax_ctx,(unsigned char *)table->partition_name,strlen(table->partition_name)); vol = (ubi_vol *)vol_table; if (raxFind(rax_ctx,(unsigned char *)vol->vol_name,strlen(vol->vol_name)) == raxNotFound) { sprintf(cmd_buf,"ubimkvol -s %d /dev/ubi%d -N %s",vol->vol_size,pt_utb_tmp->ubi_id,vol->vol_name); ret = system(cmd_buf); if (ret) goto exit; strcpy(arg.pt_name,vol->vol_name); ret = ioctl(fd,SLP_IOC_FLASH_GET_INFO,&arg); if (ret) { FLASHIO_ERROR("get %s error",arg.pt_name); goto del_vol_exit; } pt_utb.ubi_id = arg.ubi_id; if (pt_utb.ubi_id == -1) { FLASHIO_ERROR("the mtd ubi is invalid"); goto del_vol_exit; } vol_tmp = calloc(sizeof(ubi_vol),1); if (vol_tmp == NULL) goto del_vol_exit; memcpy(vol_tmp,vol,sizeof(ubi_vol)); pt_utb.mtd_info = arg.mtd_info; pt_utb.vol_table = vol_tmp; pt_utb.mtd_id = arg.mtd_id; pt_utb.free_flag = 1; pt_utb.pt_table = NULL; ret = add_radix_node(&pt_utb,pt_utb.vol_table->vol_name); if (ret) goto del_vol_exit; vol_tmp = NULL; } break; } return 0; del_pt_exit: ioctl(fd,SLP_DEL_PARTITION,&arg); goto exit; del_vol_exit: sprintf(cmd_buf,"ubirmvol /dev/ubi%d -N %s",pt_utb_tmp->ubi_id,vol->vol_name); system(cmd_buf); exit: if (fd > 0) close(fd); if (table_tmp) free(table_tmp); if (vol_tmp) free(vol_tmp); return -1; } int flash_map_memory(char *pt_name) { ARG arg = {0}; int fd = 0,ret = -1; pt_usr_table *pt_utb = NULL; fd = open(FLASH_DEV,O_WRONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); goto exit; } pt_utb = raxFind(rax_ctx,(unsigned char *)pt_name,strlen(pt_name)); if (pt_utb == raxNotFound) goto exit; arg.mtd_info = pt_utb->mtd_info; if (pt_utb->pt_table != NULL) arg.length = pt_utb->pt_table->valid_size; else if (pt_utb->vol_table != NULL) arg.length = pt_utb->vol_table->valid_size; else { FLASHIO_ERROR("unknown flash type,map forbid"); ret = -1; goto exit; } arg.offset = 0; ret = ioctl(fd, SLP_MAP_FLASH, &arg); if (ret) { FLASHIO_ERROR("%s call ioctl failed", __func__); close(fd); return ERROR; } exit: if (fd > 0) close(fd); return ret; } void switch_partition_table_to_network(TP_HEAD_INFO *tpheader) { partition_table_item *table = NULL; ubi_vol *vol = NULL; short pt_id = 0,vol_id = 0; for (pt_id = 0;pt_id < tpheader->partition_num;pt_id++) { table = &(tpheader->table[pt_id]); table->partition_attribute = htonl(table->partition_attribute); table->partition_offset = htonl(table->partition_offset); table->partition_length = htonl(table->partition_length); table->partition_valid_size = htonl(table->partition_valid_size); table->valid_size = htonl(table->valid_size); table->version = htons(table->version); table->fw_offset = htonl(table->fw_offset); for (vol_id = 0;vol_id < UBI_MAX_NUM;vol_id++) { vol = &(table->vol_table[vol_id]); if (strlen(vol->vol_name) == 0) continue; vol->fw_offset = htonl(vol->fw_offset); vol->vol_size = htonl(vol->vol_size); vol->valid_size = htonl(vol->valid_size); vol->partition_attribute = htonl(vol->partition_attribute); vol->vol_valid_size = htonl(vol->vol_valid_size); vol->ubi_version = htons(vol->ubi_version); } } tpheader->partition_num = htons(tpheader->partition_num); } void switch_partition_table_to_local(TP_HEAD_INFO *tpheader) { partition_table_item *table = NULL; ubi_vol *vol = NULL; short pt_id = 0,vol_id = 0; tpheader->partition_num = ntohs(tpheader->partition_num); for (pt_id = 0;pt_id < tpheader->partition_num;pt_id++) { table = &(tpheader->table[pt_id]); table->partition_attribute = ntohl(table->partition_attribute); table->partition_offset = ntohl(table->partition_offset); table->partition_length = ntohl(table->partition_length); table->partition_valid_size = ntohl(table->partition_valid_size); table->valid_size = ntohl(table->valid_size); table->version = ntohs(table->version); table->fw_offset = ntohl(table->fw_offset); for (vol_id = 0;vol_id < UBI_MAX_NUM;vol_id++) { vol = &(table->vol_table[vol_id]); if (strlen(vol->vol_name) == 0) continue; vol->fw_offset = ntohl(vol->fw_offset); vol->vol_size = ntohl(vol->vol_size); vol->valid_size = ntohl(vol->valid_size); vol->partition_attribute = ntohl(vol->partition_attribute); vol->vol_valid_size = ntohl(vol->vol_valid_size); vol->ubi_version = ntohs(vol->ubi_version); } } } int mark_bad_block(char *pt_name,int bad_block) { ARG arg = {0}; int fd = 0,ret = -1; pt_usr_table *pt_utb = NULL; fd = open(FLASH_DEV,O_WRONLY); if (fd <= 0) { FLASHIO_ERROR("open flash dev error"); goto exit; } pt_utb = raxFind(rax_ctx,(unsigned char *)pt_name,strlen(pt_name)); if (pt_utb == raxNotFound) goto exit; arg.mtd_info = pt_utb->mtd_info; if (pt_utb->pt_table != NULL) arg.offset = bad_block; else { FLASHIO_ERROR("not flash type,mark bad forbid"); ret = -1; goto exit; } ret = ioctl(fd, SLP_MAP_MARK_BAD, &arg); if (ret) { FLASHIO_ERROR("%s call ioctl failed", __func__); close(fd); return ERROR; } exit: if (fd > 0) close(fd); return ret; } #ifdef FUNCTION_MODE #ifdef USE_NAND_FLASH S32 flash_write_tp_mode(U8 *buf, U32 buflen) { //可直接读写的分区都用ubifs struct stat st; if (stat(UC_PART_PATH,&st) != 0) { FLASHIO_ERROR("%s not exit", UC_PART_PATH); return ERROR; } char *name = TP_MODE_FILE_DIR "/" TP_MODE_FILE_PATH; FILE *cfg = fopen(name,"wb+"); if (cfg == NULL) { FLASHIO_ERROR("open %s failed",name); return ERROR; } int retLen = fwrite(buf,1,buflen,cfg); if (retLen != buflen) { FLASHIO_ERROR("file not write ok"); return ERROR; } int fd = fileno(cfg); drop_file_cache(fd,TRUE); //将缓存写入文件 fclose(cfg); return OK; } S32 flash_read_tp_mode(U8 *buf, U32 buflen) { //可直接读写的分区都用ubifs struct stat st; if (stat(UC_PART_PATH,&st) != 0) { FLASHIO_ERROR("%s not exit", UC_PART_PATH); return ERROR; } char *name = TP_MODE_FILE_DIR "/" TP_MODE_FILE_PATH; FILE *cfg = fopen(name,"rb"); if (cfg == NULL) { FLASHIO_ERROR("open %s failed",name); return ERROR; } int retLen = fread(buf,1,buflen,cfg); if (retLen <= 0) { FLASHIO_ERROR("file not read ok"); return ERROR; } fclose(cfg); return OK; } #else /*nor flash 读写tp_mode */ S32 flash_write_tp_mode(U8 *buf, U32 buflen) { ARG arg; S32 ret = -1; S32 fd = -1; arg.addr = (U32)TP_MODE_NOR_FLASH_OFFSET; arg.buf = buf; arg.len = buflen; fd = open(FLASH_DEV, O_RDONLY); if (-1 == fd) { FLASHIO_ERROR("open device failed"); return ERROR; } ret = ioctl(fd, SLP_IOC_FLASH_WRITE, &arg); if (ret) { FLASHIO_ERROR("ioctl failed, errcode %d", ret); close(fd); return ERROR; } printf("flash_write_tp_mode\n"); close(fd); return OK; } S32 flash_read_tp_mode(U8 *buf, U32 buflen) { ARG arg; S32 ret = -1; S32 fd = -1; arg.addr = (U32)TP_MODE_NOR_FLASH_OFFSET; arg.buf = buf; arg.len = buflen; fd = open(FLASH_DEV, O_RDONLY); if (-1 == fd) { FLASHIO_ERROR("open device failed"); return ERROR; } ret = ioctl(fd, SLP_IOC_FLASH_READ, &arg); if (ret) { FLASHIO_ERROR("ioctl failed, errcode %d", ret); close(fd); return ERROR; } printf("flash_read_tp_mode\n"); close(fd); return OK; } #endif #endif FLASH_USR_SPACE_MODULE_INIT(init_flash_io);
09-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值