• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2017 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  #include <stdio.h>
18  #include <stdlib.h>
19  #include <string.h>
20  #include <unistd.h>
21  
22  #include "dt_table.h"
23  #include "mkdtimg_core.h"
24  
25  
26  static int calculate_args_entry_count(int argc, char *argv[], int arg_start) {
27    int count = 0;
28  
29    int i;
30    for (i = arg_start; i < argc; i++) {
31      const char *arg = argv[i];
32      char c = arg[0];
33      /* Skip options starting with -- */
34      if (c == '-') continue;
35      count++;
36    }
37  
38    return count;
39  }
40  
41  static int parse_arg(char **option, char **value, char *arg) {
42    if (arg[0] != '-') {
43      /* This is not a option */
44      *option = NULL;
45      return 0;
46    }
47  
48    /* An option must start with -- */
49    if (arg[1] != '-') {
50      return -1;
51    }
52  
53    return parse_option(option, value, arg + 2);
54  }
55  
56  static int output_img_with_args(FILE *img_fp, int argc, char *argv[], int arg_start) {
57    int entry_count = calculate_args_entry_count(argc, argv, arg_start);
58    struct dt_image_writer *writer = dt_image_writer_start(img_fp, entry_count);
59  
60    int is_entry = 0;
61    int i;
62    for (i = arg_start; i < argc; i++) {
63      char *arg = argv[i];
64      char *option, *value;
65      if (parse_arg(&option, &value, arg) != 0) {
66        fprintf(stderr, "Wrong syntax: %s\n", arg);
67        return -1;
68      }
69  
70      if (option == NULL) {
71        /* This is a file name */
72        if (dt_image_writer_add_entry(writer, arg) != 0) {
73          return -1;
74        }
75        is_entry = 1;
76        continue;
77      }
78  
79      int ret = is_entry ?
80        set_entry_options(writer, option, value) :
81        set_global_options(writer, option, value);
82      if (ret != 0) {
83        fprintf(stderr, "Unknown option: %s\n", option);
84        return -1;
85      }
86    } /* for all argv */
87  
88    if (dt_image_writer_end(writer) != 0) {
89      return -1;
90    }
91  
92    return 0;
93  }
94  
95  void handle_usage_create(FILE *out_fp, const char *prog_name) {
96    fprintf(out_fp, "  %s create <image_file> (<global_option>...) (<dtb_file> (<entry_option>...) ...)\n\n", prog_name);
97    fprintf(out_fp,
98            "    global_options:\n"
99            "      --dt_type=<type>         Device Tree type (dtb|acpi). Default:"
100            " dtb\n"
101            "      --page_size=<number>     Output page size. Default: 2048\n"
102            "      --version=<version>      DTBO version. Default: 0\n"
103            "      --id=<number|path>       The default value to set property id "
104            "in dt_table_entry. Default: 0\n"
105            "      --rev=<number|path>\n"
106            "      --custom0=<number|path>\n"
107            "      --custom1=<number|path>\n"
108            "      --custom2=<number|path>\n"
109            "      --custom3=<number|path>\n\n"
110            "      The value could be a number or a DT node path.\n"
111            "      <number> could be a 32-bits digit or hex value, ex. 68000, "
112            "0x6800.\n"
113            "      <path> format is <full_node_path>:<property_name>, ex. "
114            "/board/:id,\n"
115            "      will read the value in given FTB file with the path.\n");
116  }
117  
118  int handle_command_create(int argc, char *argv[], int arg_start) {
119    int ret = -1;
120    FILE *img_fp = NULL;
121  
122    if (argc - arg_start < 1) {
123      handle_usage_create(stderr, argv[0]);
124      goto end;
125    }
126  
127    const char *img_filename = argv[arg_start];
128  
129    printf("create image file: %s...\n", img_filename);
130  
131    img_fp = fopen(img_filename, "wb");
132    if (img_fp == NULL) {
133      fprintf(stderr, "Can not create file: %s\n", img_filename);
134      goto end;
135    }
136  
137    ret = output_img_with_args(img_fp, argc, argv, arg_start + 1);
138    if (ret < 0) fprintf(stderr, "Can not output image with args\n");
139  
140  end:
141    if (img_fp) {
142      fclose(img_fp);
143      if (ret < 0) unlink(img_filename);
144    }
145  
146    return ret;
147  }
148