OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [image_gen/] [image_gen.c] - Blame information for rev 68

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 zero_gravi
// #################################################################################################
2
// # << NEORV32 - Executable image generator tool >>                                               #
3
// # ********************************************************************************************* #
4
// # BSD 3-Clause License                                                                          #
5
// #                                                                                               #
6
// # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
7
// #                                                                                               #
8
// # Redistribution and use in source and binary forms, with or without modification, are          #
9
// # permitted provided that the following conditions are met:                                     #
10
// #                                                                                               #
11
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
// #    conditions and the following disclaimer.                                                   #
13
// #                                                                                               #
14
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
// #    conditions and the following disclaimer in the documentation and/or other materials        #
16
// #    provided with the distribution.                                                            #
17
// #                                                                                               #
18
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
// #    endorse or promote products derived from this software without specific prior written      #
20
// #    permission.                                                                                #
21
// #                                                                                               #
22
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
// # ********************************************************************************************* #
32
// # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
// #################################################################################################
34
 
35
#include <stdint.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
 
40
 
41
const uint32_t signature = 0x4788CAFE;
42
 
43
int main(int argc, char *argv[]) {
44
 
45
  if ((argc != 4) && (argc != 5)){
46
        printf("<<< NEORV32 executable image generator >>>\n"
47
                 "by Stephan Nolting\n"
48
                 "Three arguments are required.\n"
49
                 "1st: Option\n"
50
                 " -app_bin : Generate application executable binary (binary file, little-endian, with header) \n"
51
                 " -app_hex : Generate application raw executable (hex file, no header)\n"
52
                 " -app_img : Generate application raw executable memory image (vhdl file, no header)\n"
53
                 " -bld_img : Generate bootloader raw executable memory image (vdhl file, no header)\n"
54
                       "2nd: Input file (raw binary image)\n"
55
                       "3rd: Output file\n"
56
                       "4th: Project folder (optional)\n");
57
        return 0;
58
  }
59
 
60
  FILE *input, *output;
61
  unsigned char buffer[4];
62
  char tmp_string[1024];
63
  uint32_t tmp = 0, size = 0, checksum = 0;
64
  unsigned int i = 0;
65
  int option = 0;
66
  unsigned long raw_exe_size = 0;
67
 
68
  if (strcmp(argv[1], "-app_bin") == 0)
69
    option = 1;
70
  else if (strcmp(argv[1], "-app_img") == 0)
71
    option = 2;
72
  else if (strcmp(argv[1], "-bld_img") == 0)
73
    option = 3;
74
  else if (strcmp(argv[1], "-app_hex") == 0)
75
    option = 4;
76
  else {
77
        printf("Invalid option!");
78
        return 1;
79
  }
80
 
81
  // open input file
82
  input = fopen(argv[2], "rb");
83
  if(input == NULL){
84
    printf("Input file error!");
85
    return 2;
86
  }
87
 
88
  // open output file
89
  output = fopen(argv[3], "wb");
90
  if(output == NULL){
91
    printf("Output file error!");
92
    return 3;
93
  }
94
 
95
  // get input file size
96
  fseek(input, 0L, SEEK_END);
97
  unsigned int input_size = (unsigned int)ftell(input);
98
  rewind(input);
99
  unsigned int input_words = input_size / 4;
100
 
101
 
102
// ------------------------------------------------------------
103
// Get size of application (in bytes)
104
// ------------------------------------------------------------
105
  fseek(input, 0L, SEEK_END);
106
 
107
  // get file size (raw executable)
108
  raw_exe_size = (unsigned long)ftell(input);
109
 
110
  // go back to beginning
111
  rewind(input);
112
 
113
 
114
// ------------------------------------------------------------
115
// Generate BINARY executable (with header!!!) for bootloader upload
116
// ------------------------------------------------------------
117
  if (option == 1) {
118
 
119
    // reserve header space for signature
120
    fputc(char(0), output);
121
    fputc(char(0), output);
122
    fputc(char(0), output);
123
    fputc(char(0), output);
124
 
125
    // reserve header space for size
126
    fputc(char(0), output);
127
    fputc(char(0), output);
128
    fputc(char(0), output);
129
    fputc(char(0), output);
130
 
131
    // reserve header space for checksum
132
    fputc(char(0), output);
133
    fputc(char(0), output);
134
    fputc(char(0), output);
135
    fputc(char(0), output);
136
 
137
    buffer[0] = 0;
138
    buffer[1] = 0;
139
    buffer[2] = 0;
140
    buffer[3] = 0;
141
 
142
    checksum = 0;
143
    size = 0;
144
    rewind(input);
145
    while(fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
146
      tmp  = (uint32_t)(buffer[0] << 0);
147
      tmp |= (uint32_t)(buffer[1] << 8);
148
      tmp |= (uint32_t)(buffer[2] << 16);
149
      tmp |= (uint32_t)(buffer[3] << 24);
150
      checksum += tmp; // checksum: sum complement
151
      fputc(buffer[0], output);
152
      fputc(buffer[1], output);
153
      fputc(buffer[2], output);
154
      fputc(buffer[3], output);
155
      size += 4;
156
    }
157
 
158
    rewind(output);
159
    // header: signature
160
    fputc((unsigned char)((signature >>  0) & 0xFF), output);
161
    fputc((unsigned char)((signature >>  8) & 0xFF), output);
162
    fputc((unsigned char)((signature >> 16) & 0xFF), output);
163
    fputc((unsigned char)((signature >> 24) & 0xFF), output);
164
    // header: size
165
    fputc((unsigned char)((size >>  0) & 0xFF), output);
166
    fputc((unsigned char)((size >>  8) & 0xFF), output);
167
    fputc((unsigned char)((size >> 16) & 0xFF), output);
168
    fputc((unsigned char)((size >> 24) & 0xFF), output);
169
    // header: checksum (sum complement)
170
    checksum = (~checksum) + 1;
171
    fputc((unsigned char)((checksum >>  0) & 0xFF), output);
172
    fputc((unsigned char)((checksum >>  8) & 0xFF), output);
173
    fputc((unsigned char)((checksum >> 16) & 0xFF), output);
174
    fputc((unsigned char)((checksum >> 24) & 0xFF), output);
175
  }
176
 
177
 
178
// ------------------------------------------------------------
179
// Generate APPLICATION's executable memory init file (no header!!!)
180
// ------------------------------------------------------------
181
  if (option == 2) {
182
 
183
        // header
184
    sprintf(tmp_string, "-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32\n"
185
                                                            "-- Auto-generated memory init file (for APPLICATION) from source file <%s/%s>\n"
186
                                                            "-- Size: %lu bytes\n"
187
                                                            "\n"
188
                                                            "library ieee;\n"
189
                                                            "use ieee.std_logic_1164.all;\n"
190
                                                            "\n"
191
                        "library neorv32;\n"
192
                        "use neorv32.neorv32_package.all;\n"
193
                                                            "\n"
194
                                                            "package neorv32_application_image is\n"
195
                                                            "\n"
196
                                                            "  constant application_init_image : mem32_t := (\n", argv[4], argv[2], raw_exe_size);
197
    fputs(tmp_string, output);
198
 
199
        // data
200
    buffer[0] = 0;
201
    buffer[1] = 0;
202
    buffer[2] = 0;
203
    buffer[3] = 0;
204
    i = 0;
205
 
206
    while (i < (input_words-1)) {
207
      if (fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
208
        tmp  = (uint32_t)(buffer[0] << 0);
209
        tmp |= (uint32_t)(buffer[1] << 8);
210
        tmp |= (uint32_t)(buffer[2] << 16);
211
        tmp |= (uint32_t)(buffer[3] << 24);
212
        sprintf(tmp_string, "    %08d => x\"%08x\",\n", i, (unsigned int)tmp);
213
        fputs(tmp_string, output);
214
        buffer[0] = 0;
215
        buffer[1] = 0;
216
        buffer[2] = 0;
217
        buffer[3] = 0;
218
        i++;
219
      }
220
      else {
221
        printf("Unexpected input file end!\n");
222
        break;
223
      }
224
    }
225
 
226
    if (fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
227
      tmp  = (uint32_t)(buffer[0] << 0);
228
      tmp |= (uint32_t)(buffer[1] << 8);
229
      tmp |= (uint32_t)(buffer[2] << 16);
230
      tmp |= (uint32_t)(buffer[3] << 24);
231
      sprintf(tmp_string, "    %08d => x\"%08x\"\n", i, (unsigned int)tmp);
232
      fputs(tmp_string, output);
233
      buffer[0] = 0;
234
      buffer[1] = 0;
235
      buffer[2] = 0;
236
      buffer[3] = 0;
237
      i++;
238
    }
239
    else {
240
      printf("Unexpected input file end!\n");
241
    }
242
 
243
        // end
244
    sprintf(tmp_string, "  );\n"
245
                                                            "\n"
246
                                                            "end neorv32_application_image;\n");
247
    fputs(tmp_string, output);
248
  }
249
 
250
 
251
// ------------------------------------------------------------
252
// Generate BOOTLOADER's executable memory init file (no header!!!)
253
// ------------------------------------------------------------
254
  if (option == 3) {
255
 
256
        // header
257
    sprintf(tmp_string, "-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32\n"
258
                                                            "-- Auto-generated memory init file (for BOOTLOADER) from source file <%s/%s>\n"
259
                                                            "-- Size: %lu bytes\n"
260
                                                            "\n"
261
                                                            "library ieee;\n"
262
                                                            "use ieee.std_logic_1164.all;\n"
263
                                                            "\n"
264
                        "library neorv32;\n"
265
                        "use neorv32.neorv32_package.all;\n"
266
                                                            "\n"
267
                                                            "package neorv32_bootloader_image is\n"
268
                                                            "\n"
269
                                                            "  constant bootloader_init_image : mem32_t := (\n", argv[4], argv[2], raw_exe_size);
270
    fputs(tmp_string, output);
271
 
272
    // data
273
    buffer[0] = 0;
274
    buffer[1] = 0;
275
    buffer[2] = 0;
276
    buffer[3] = 0;
277
    i = 0;
278
 
279
    while (i < (input_words-1)) {
280
      if (fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
281
        tmp  = (uint32_t)(buffer[0] << 0);
282
        tmp |= (uint32_t)(buffer[1] << 8);
283
        tmp |= (uint32_t)(buffer[2] << 16);
284
        tmp |= (uint32_t)(buffer[3] << 24);
285
        sprintf(tmp_string, "    %08d => x\"%08x\",\n", i, (unsigned int)tmp);
286
        fputs(tmp_string, output);
287
        buffer[0] = 0;
288
        buffer[1] = 0;
289
        buffer[2] = 0;
290
        buffer[3] = 0;
291
        i++;
292
      }
293
      else {
294
        printf("Unexpected input file end!\n");
295
        break;
296
      }
297
    }
298
 
299
    if (fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
300
      tmp  = (uint32_t)(buffer[0] << 0);
301
      tmp |= (uint32_t)(buffer[1] << 8);
302
      tmp |= (uint32_t)(buffer[2] << 16);
303
      tmp |= (uint32_t)(buffer[3] << 24);
304
      sprintf(tmp_string, "    %08d => x\"%08x\"\n", i, (unsigned int)tmp);
305
      fputs(tmp_string, output);
306
      buffer[0] = 0;
307
      buffer[1] = 0;
308
      buffer[2] = 0;
309
      buffer[3] = 0;
310
      i++;
311
    }
312
    else {
313
      printf("Unexpected input file end!\n");
314
    }
315
 
316
        // end
317
    sprintf(tmp_string, "  );\n"
318
                                                            "\n"
319
                                                            "end neorv32_bootloader_image;\n");
320
    fputs(tmp_string, output);
321
  }
322
 
323
 
324
// ------------------------------------------------------------
325
// Generate APPLICATION's executable hex file (no header!!!)
326
// ------------------------------------------------------------
327
  if (option == 4) {
328
 
329
    // data
330
    buffer[0] = 0;
331
    buffer[1] = 0;
332
    buffer[2] = 0;
333
    buffer[3] = 0;
334
    i = 0;
335
 
336
    while(fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
337
      tmp  = (uint32_t)(buffer[0] << 0);
338
      tmp |= (uint32_t)(buffer[1] << 8);
339
      tmp |= (uint32_t)(buffer[2] << 16);
340
      tmp |= (uint32_t)(buffer[3] << 24);
341
      sprintf(tmp_string, "%08x\n", (unsigned int)tmp);
342
      fputs(tmp_string, output);
343
    }
344
  }
345
 
346
 
347
  fclose(input);
348
  fclose(output);
349
 
350
  return 0;
351
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.