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