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
calculate_args_entry_count(int argc,char * argv[],int arg_start)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
parse_arg(char ** option,char ** value,char * arg)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
output_img_with_args(FILE * img_fp,int argc,char * argv[],int arg_start)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
handle_usage_create(FILE * out_fp,const char * prog_name)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
handle_command_create(int argc,char * argv[],int arg_start)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