blob: d0cc349be5cfce1eb992e9e631f3d6b262117fae [file] [log] [blame]
/*
* 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"
" --dt_type=<type> Device Tree type (dtb|acpi). Default:"
" dtb\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);
if (ret < 0) fprintf(stderr, "Can not output image with args\n");
end:
if (img_fp) {
fclose(img_fp);
if (ret < 0) unlink(img_filename);
}
return ret;
}