1 /*
2 * Copyright (c) 2022 Talkweb Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #define BOOTLOADER_OFFSET_SIZE 0x10000 // bootloader offset size
21 #define MAX_BUFFER_SIZE 1024
22 #define CHAR_RANG 256
23 #define ARGV_0 0
24 #define ARGV_1 1
25 #define ARGV_2 2
26 #define ARGV_3 3
27 #define INPUT_ARGC_NUM 4
28 #define FILL_CHAR 0xFF
29
30 FILE *g_fp_out;
31 FILE *g_fp_tmp;
32 int g_fill_size;
33 int g_buffer_len;
34 unsigned char g_buffer[MAX_BUFFER_SIZE];
35
Usage(void)36 static void Usage(void)
37 {
38 printf("Params error:\r\nFor usage example: ./merge_bin bootload.bin OHOS_Image.bin output.bin\r\n");
39 }
40
MergeFail(const char * output_file)41 static int MergeFail(const char *output_file)
42 {
43 if (g_fp_out) {
44 fclose(g_fp_out);
45 g_fp_out = NULL;
46 }
47 if (g_fp_tmp) {
48 fclose(g_fp_tmp);
49 g_fp_tmp = NULL;
50 }
51 if (output_file != NULL) {
52 char cmd[256] = {"rm -rf "};
53 int cmd_len = strlen(output_file);
54 for (int i = 0; i<cmd_len; i++) {
55 cmd[i+cmd_len-1] = output_file[i];
56 }
57 system(cmd);
58 }
59 return -1;
60 }
61
CopyBootloader(const char * bootloader_filename,const char * output_filename)62 static int CopyBootloader(const char *bootloader_filename, const char *output_filename)
63 {
64 int ret;
65 g_fp_tmp = fopen(bootloader_filename, "r");
66 if (g_fp_tmp == NULL) {
67 printf("merge_bin fail! because open %s fail!\r\n", bootloader_filename);
68 fclose(g_fp_out);
69 g_fp_out = NULL;
70 return -1;
71 }
72 g_fill_size = BOOTLOADER_OFFSET_SIZE;
73 do {
74 g_buffer_len = fread(g_buffer, 1, sizeof(g_buffer), g_fp_tmp); // Read from bootloader file
75 ret = fwrite(g_buffer, 1, g_buffer_len, g_fp_out); // Write to output file
76 if (ret != g_buffer_len) {
77 printf("merge_bin fail! because write %s fail!\r\n", output_filename);
78 return MergeFail(output_filename);
79 }
80 g_fill_size -= g_buffer_len;
81 } while (g_buffer_len>0);
82 if (g_fill_size<0) {
83 printf("merge_bin fail! because %s is too large more than 0x%02X!\r\n",
84 bootloader_filename, BOOTLOADER_OFFSET_SIZE);
85 return MergeFail(output_filename);
86 }
87 return 0;
88 }
89
FillEmpty(char * output_filename)90 static int FillEmpty(char *output_filename)
91 {
92 int ret;
93 unsigned char fill_ch = FILL_CHAR;
94 for (int i = 0; i<g_fill_size; i++) {
95 ret = fwrite(&fill_ch, 1, 1, g_fp_out);
96 if (ret != 1) {
97 printf("merge_bin fail! because write fillchar fail!\r\n");
98 return MergeFail(output_filename);
99 }
100 }
101 return 0;
102 }
103
CopyApp(const char * app_filename,const char * output_filename)104 static int CopyApp(const char *app_filename, const char *output_filename)
105 {
106 int ret;
107 if (g_fp_tmp != NULL) {
108 fclose(g_fp_tmp);
109 g_fp_tmp = NULL;
110 }
111 g_fp_tmp = fopen(app_filename, "r");
112 if (g_fp_tmp == NULL) {
113 printf("merge_bin fail! because open %s fail!\r\n", app_filename);
114 return MergeFail(output_filename);
115 }
116 do {
117 g_buffer_len = fread(g_buffer, 1, sizeof(g_buffer), g_fp_tmp); // Read from app file
118 ret = fwrite(g_buffer, 1, g_buffer_len, g_fp_out); // Write to output file
119 if (ret != g_buffer_len) {
120 printf("merge_bin fail! because write %s fail!\r\n", output_filename);
121 return MergeFail(output_filename);
122 }
123 } while (g_buffer_len > 0);
124 }
125
main(int argc,char * argv[])126 int main(int argc, char *argv[])
127 {
128 int ret;
129 if (argc != INPUT_ARGC_NUM) {
130 Usage();
131 return 0;
132 }
133 g_fp_out = fopen(argv[ARGV_3], "w+");
134 if (g_fp_out == NULL) {
135 printf("merge_bin fail! because open %s fail!\r\n", argv[ARGV_3]);
136 return -1;
137 }
138 if (CopyBootloader(argv[ARGV_1], argv[ARGV_3]) != 0) { // merge bootloader
139 return -1;
140 }
141 if (FillEmpty(argv[ARGV_3])!=0) { // fill empty size
142 return -1;
143 }
144 if (CopyApp(argv[ARGV_2], argv[ARGV_3])!=0) { // merge app
145 return -1;
146 }
147 if (g_fp_out) {
148 fclose(g_fp_out);
149 g_fp_out = NULL;
150 }
151 if (g_fp_tmp) {
152 fclose(g_fp_tmp);
153 g_fp_tmp = NULL;
154 }
155 printf("merge_bin to %s success!\r\n", argv[ARGV_3]);
156 return 0;
157 }