bin文件合并
代码源处:https://gitee.com/sharkisyou/bin-merge.git。目的:完成多个bin文件的合并,并执行相关偏移地址。编译:Linux环境下使用gcc进行编译。
·
目的:完成多个bin文件的合并,并执行相关偏移地址
编译:Linux环境下使用gcc进行编译
生成可执行文件:
linux的可执行文件:gcc main.c -o binMerge.exe
windows的可执行文件:i686-w64-mingw32-gcc main.c -o bin_merge_Select.exe
(需要安装MinGW:sudo apt-get install mingw-w64
)
exe使用方式:./binMerge_T taget1.bin target2.bin target3.bin 0x0000000 0x10000000 0x20000000 merge.bin
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#define READ_LEN (1024) /*读取长度*/
#define FILL (uint8_t)0xff /*填充字符*/
//#define DEBUG
int cmp(const void* a, const void* b);
int main(int argc,char *argv[])
{
#ifdef DEBUG
argc = 8;
argv[1] = "./b.bin";
argv[2] = "./c.bin";
argv[3] = "./a.bin";
argv[4] = "0x20000";
argv[5] = "0x60000";
argv[6] = "0x0000";
argv[7] = "out1.bin";
#endif
if(argc <= 4)
{
printf("Please enter at least two file names");
return -1;
}
if(argc%2)
{
printf("参数缺少,需要为每个bin文件指定偏移地址,并且需要指定一个输出文件名\n");
return -1;
}
printf("选择填充值:1.0xFF 2.0x00\n");
uint8_t input_val = 0;
uint8_t fill_value = 0;
scanf("%d",&input_val);
if(input_val == 1){
fill_value = FILL;
}else if(input_val == 2){
fill_value = 0;
}else{
fill_value = FILL;
}
uint8_t read_buf[READ_LEN];/*读取缓冲*/
uint8_t fill_byte = fill_value;/*填充字节*/
uint8_t fill_array[READ_LEN] = {[0 ... READ_LEN-1] = FILL};/*填充数组*/
memset(fill_array,fill_value,sizeof(fill_array));
char output_filename[128];
/*文件数*/
uint8_t file_num = (argc-2)/2;
/*偏移地址数组*/
uint32_t offset[file_num];
uint32_t offset_sort[file_num];
/*文件*/
FILE *file[file_num];
/*文件名*/
char *filename[file_num];
char *sort_filename[file_num];
/*所有值初始化*/
memset(offset,0,sizeof(offset));
memset(offset_sort,0,sizeof(offset_sort));
memset(file,0,sizeof(file));
memset(filename,0,sizeof(filename));
/*获取输出文件名*/
strcpy(output_filename,argv[argc-1]);
/*获取文件名和偏移地址*/
for(int i = 0;i < file_num;i++)
{
char* endptr;
filename[i] = argv[i+1];
offset[i] = strtoimax(argv[i+1+file_num],&endptr,0);
}
memcpy(offset_sort,offset,sizeof(offset));
/*偏移地址大小排序,从最小地址开始偏移*/
qsort(offset_sort,sizeof(offset_sort)/sizeof(uint32_t),sizeof(uint32_t),cmp);
/*根据偏移地址进行文件对应排序*/
for(int i = 0;i < sizeof(offset_sort)/sizeof(uint32_t);i++)
{
for(int j = 0;j < sizeof(offset_sort)/sizeof(uint32_t);j++)
{
if(offset_sort[i] == offset[j])
{
sort_filename[i] = filename[j];
break;
}
}
}
/*打开需要生成的文件*/
FILE *fp_save = fopen(output_filename,"wb+");
if(fp_save == NULL)
{
perror("fopen fail");
return -1;
}
for(int i = 0;i < file_num;i++)
{
file[i] = fopen(sort_filename[i],"rb");
if(file[i] == NULL)
{
printf("open %s failed : %s\n", sort_filename[i],strerror(errno));
remove(output_filename);
return -1;
}
/*填充:将目标文件填充默认值*/
while((offset_sort[i] - ftell(fp_save)) > READ_LEN)
{
uint16_t write_len = fwrite(fill_array,sizeof(char),READ_LEN,fp_save);
}
while(offset_sort[i] - ftell(fp_save))
{
uint16_t write_len = fwrite(&fill_byte,sizeof(char),1,fp_save);
}
/*复制*/
while(1)
{
uint16_t read_len = fread(read_buf,sizeof(char),READ_LEN,file[i]);
uint16_t write_len = fwrite(read_buf,sizeof(char),read_len,fp_save);
if(write_len != read_len)
{
perror("fwrite fail");
fclose(file[i]);
remove(output_filename);
return -1;
}
if(read_len < READ_LEN)
{
fclose(file[i]);
break;
}
}
}
fclose(fp_save);
for(int i = 0;i < file_num;i++)
{
printf("%#010X \t%s\n",offset_sort[i],sort_filename[i]);
}
return 0;
}
int cmp(const void* a, const void* b)
{
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
// return (arg1 > arg2) - (arg1 < arg2); // 可行的简写
// return arg1 - arg2; // 错误的简写(若给出 INT_MIN 则会失败)
}
代码源处:https://gitee.com/sharkisyou/bin-merge.git
更多推荐
已为社区贡献1条内容
所有评论(0)