• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }