14f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin/* 24f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * Copyright (C) 2017 The Android Open Source Project 34f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * 44f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * Licensed under the Apache License, Version 2.0 (the "License"); 54f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * you may not use this file except in compliance with the License. 64f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * You may obtain a copy of the License at 74f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * 84f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * http://www.apache.org/licenses/LICENSE-2.0 94f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * 104f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * Unless required by applicable law or agreed to in writing, software 114f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * distributed under the License is distributed on an "AS IS" BASIS, 124f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * See the License for the specific language governing permissions and 144f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * limitations under the License. 154f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin */ 164f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin 17780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <ctype.h> 18780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <getopt.h> 19780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <stdio.h> 20780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <stdlib.h> 21780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <string.h> 22780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <unistd.h> 23780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 24780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include "dt_table.h" 25780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include "mkdtimg_core.h" 26780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 27780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 28780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstruct cfg_create_params { 29780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *img_filename; 30780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *cfg_filename; 31780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *dtb_dir; 32780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin}; 33780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 34780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic const char short_options[] = "d:"; 35780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic struct option options[] = { 36780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin { "dtb-dir", required_argument, NULL, 'd' }, 37780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin { 0, 0, NULL, 0 } 38780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin}; 39780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 40780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 41780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic char *trim_line(char *line) { 42780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* Find the end of the string or the first of '#' */ 43780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char *end = line; 44780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin while (*end != '\0' && *end != '#') { 45780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin end++; 46780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 47780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin do { 48780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin end--; 49780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } while (end >= line && isspace(*end)); 50780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 51780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin *(end + 1) = '\0'; 52780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 53780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin while (isspace(*line)) { 54780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin line++; 55780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 56780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return line; 57780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 58780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 59780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int parse_config_entry_count(FILE *cfg_fp) { 60780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int count = 0; 61780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 62780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* Any line without prefix spaces is entry filename */ 63780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char line[1024]; 64780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin while (fgets(line, sizeof(line), cfg_fp) != NULL) { 65780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char c = line[0]; 66780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (c == '\0' || isspace(c) || c == '#') continue; 67780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin count++; 68780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 69780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 70780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return count; 71780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 72780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 73780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int output_img_with_config(FILE *img_fp, FILE *cfg_fp) { 74780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int entry_count = parse_config_entry_count(cfg_fp); 75780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin struct dt_image_writer *writer = dt_image_writer_start(img_fp, entry_count); 76780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 77780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fseek(cfg_fp, 0, SEEK_SET); /* Reset the file pos to head */ 78780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 79780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int is_entry = 0; 80780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char line[1024]; 81780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin while (fgets(line, sizeof(line), cfg_fp) != NULL) { 82780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char *trimmed = trim_line(line); 83780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (trimmed[0] == '\0') { 84780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* empty line, pass */ 85780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin continue; 86780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 87780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 88780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (trimmed == line) { 89780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* This line is a file name, 90780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin because it start from the first char of the line */ 91780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (dt_image_writer_add_entry(writer, trimmed) != 0) { 92780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return -1; 93780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 94780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin is_entry = 1; 95780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin continue; 96780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 97780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 98780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char *option, *value; 99780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (parse_option(&option, &value, trimmed) != 0) { 100780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Wrong syntax: %s\n", trimmed); 101780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return -1; 102780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 103780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 104780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int ret = is_entry ? 105780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin set_entry_options(writer, option, value) : 106780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin set_global_options(writer, option, value); 107780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (ret != 0) { 108780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Unknown option: %s\n", option); 109780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return -1; 110780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 111780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 112780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 113780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (dt_image_writer_end(writer) != 0) { 114780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return -1; 115780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 116780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 117780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 0; 118780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 119780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 120780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int process_command_cfg_create(const struct cfg_create_params *params) { 121780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int ret = -1; 122780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin FILE *cfg_fp = NULL; 123780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin FILE *img_fp = NULL; 124780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 125780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin cfg_fp = fopen(params->cfg_filename, "r"); 126780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (cfg_fp == NULL) { 127780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not open config file: %s\n", params->cfg_filename); 128780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 129780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 130780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 131780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin printf("create image file: %s...\n", params->img_filename); 132780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 133780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin img_fp = fopen(params->img_filename, "wb"); 134780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (img_fp == NULL) { 135780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not create file: %s\n", params->img_filename); 136780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 137780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 138780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 139780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (params->dtb_dir != NULL) { 140780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (chdir(params->dtb_dir) != 0) { 141780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not switch to directory: %s\n", params->dtb_dir); 142780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 143780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 144780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 145780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 146780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin ret = output_img_with_config(img_fp, cfg_fp); 147780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 148780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linend: 149780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (img_fp) fclose(img_fp); 150780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (cfg_fp) fclose(cfg_fp); 151780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 152780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return ret; 153780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 154780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 155780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linvoid handle_usage_cfg_create(FILE *out_fp, const char *prog_name) { 156780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, " %s cfg_create <image_file> <config_file> (<option>...)\n\n", prog_name); 157780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, 158780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " options:\n" 159780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " -d, --dtb-dir The path to load dtb files.\n" 160780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " Default is load from the current path.\n"); 161780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 162780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 163780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linint handle_command_cfg_create(int argc, char *argv[], int arg_start) { 164780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (argc - arg_start < 2) { 165780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin handle_usage_cfg_create(stderr, argv[0]); 166780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 1; 167780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 168780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 169780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin struct cfg_create_params params; 170780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin memset(¶ms, 0, sizeof(params)); 171780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params.img_filename = argv[arg_start]; 172780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params.cfg_filename = argv[arg_start + 1]; 173780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 174780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin optind = arg_start + 2; 175780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin while (1) { 176780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int c = getopt_long(argc, argv, short_options, options, NULL); 177780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (c == -1) { 178780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin break; 179780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 180780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin switch (c) { 181780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin case 'd': 182780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params.dtb_dir = optarg; 183780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin break; 184780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin default: 185780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* Unknown option, return error */ 186780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 1; 187780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 188780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 189780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 190780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return process_command_cfg_create(¶ms); 191780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 192