/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "dt_table.h" #include "mkdtimg_core.h" static int calculate_args_entry_count(int argc, char *argv[], int arg_start) { int count = 0; int i; for (i = arg_start; i < argc; i++) { const char *arg = argv[i]; char c = arg[0]; /* Skip options starting with -- */ if (c == '-') continue; count++; } return count; } static int parse_arg(char **option, char **value, char *arg) { if (arg[0] != '-') { /* This is not a option */ *option = NULL; return 0; } /* An option must start with -- */ if (arg[1] != '-') { return -1; } return parse_option(option, value, arg + 2); } static int output_img_with_args(FILE *img_fp, int argc, char *argv[], int arg_start) { int entry_count = calculate_args_entry_count(argc, argv, arg_start); struct dt_image_writer *writer = dt_image_writer_start(img_fp, entry_count); int is_entry = 0; int i; for (i = arg_start; i < argc; i++) { char *arg = argv[i]; char *option, *value; if (parse_arg(&option, &value, arg) != 0) { fprintf(stderr, "Wrong syntax: %s\n", arg); return -1; } if (option == NULL) { /* This is a file name */ if (dt_image_writer_add_entry(writer, arg) != 0) { return -1; } is_entry = 1; continue; } int ret = is_entry ? set_entry_options(writer, option, value) : set_global_options(writer, option, value); if (ret != 0) { fprintf(stderr, "Unknown option: %s\n", option); return -1; } } /* for all argv */ if (dt_image_writer_end(writer) != 0) { return -1; } return 0; } void handle_usage_create(FILE *out_fp, const char *prog_name) { fprintf(out_fp, " %s create <image_file> (<global_option>...) (<dtb_file> (<entry_option>...) ...)\n\n", prog_name); fprintf(out_fp, " global_options:\n" " --page_size <number> Output page size. Default: 2048\n" " --version <version> DTBO version. Default: 0\n" " --id=<number|path> The default value to set property id in dt_table_entry. Default: 0\n" " --rev=<number|path>\n" " --custom0=<number|path>\n" " --custom1=<number|path>\n" " --custom2=<number|path>\n" " --custom3=<number|path>\n\n" " The value could be a number or a DT node path.\n" " <number> could be a 32-bits digit or hex value, ex. 68000, 0x6800.\n" " <path> format is <full_node_path>:<property_name>, ex. /board/:id,\n" " will read the value in given FTB file with the path.\n"); } int handle_command_create(int argc, char *argv[], int arg_start) { int ret = -1; FILE *img_fp = NULL; if (argc - arg_start < 1) { handle_usage_create(stderr, argv[0]); goto end; } const char *img_filename = argv[arg_start]; printf("create image file: %s...\n", img_filename); img_fp = fopen(img_filename, "wb"); if (img_fp == NULL) { fprintf(stderr, "Can not create file: %s\n", img_filename); goto end; } ret = output_img_with_args(img_fp, argc, argv, arg_start + 1); end: if (img_fp) fclose(img_fp); return ret; }