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 <getopt.h> 18780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <stdio.h> 19780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <stdlib.h> 20780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include <stdint.h> 21780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 22780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include "libfdt.h" 23780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 24780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin#include "dt_table.h" 25780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 26780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 27780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstruct dump_params { 28780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *img_filename; 29780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *out_filename; 30780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *out_dtb_filename; 31780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin}; 32780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 33780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic const char short_options[] = "o:b:"; 34780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic struct option options[] = { 35780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin { "output", required_argument, NULL, 'o' }, 36780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin { "dtb", required_argument, NULL, 'b' }, 37780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin { 0, 0, NULL, 0 } 38780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin}; 39780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 40780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 41780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void *read_fdt_from_image(FILE *img_fp, 42780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t dt_offset, uint32_t dt_size) { 43780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin void *fdt = NULL; 44780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 45780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fdt = malloc(dt_size); 46780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 47780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fseek(img_fp, dt_offset, SEEK_SET); 48780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (fread(fdt, dt_size, 1, img_fp) == 0) { 49780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Read FDT data error.\n"); 50780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 51780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin free(fdt); 52780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return NULL; 53780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 54780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 55780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return fdt; 56780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 57780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 58780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int write_fdt_to_file(const char *filename, const void *fdt) { 59780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int ret = -1; 60780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin FILE *out_fp = NULL; 61780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 62780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin out_fp = fopen(filename, "wb"); 63780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (!out_fp) { 64780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not create file: %s\n", filename); 65780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 66780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 67780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 68780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin size_t fdt_size = fdt_totalsize(fdt); 69780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (fwrite(fdt, fdt_size, 1, out_fp) < 1) { 70780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Write FDT data error.\n"); 71780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 72780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 73780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 74780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin ret = 0; 75780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 76780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linend: 77780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (out_fp) fclose(out_fp); 78780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 79780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return ret; 80780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 81780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 82780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void free_fdt(void *fdt) { 83780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (fdt == NULL) { 84780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* do nothing */ 85780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return; 86780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 87780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 88780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin free(fdt); 89780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 90780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 91780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 92780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void output_prop_int(FILE *out_fp, const char *name, uint32_t value) { 93780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, "%+20s = %d\n", name, fdt32_to_cpu(value)); 94780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 95780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 96780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void output_prop_int_cpu(FILE *out_fp, const char *name, uint32_t value) { 97780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, "%+20s = %d\n", name, value); 98780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 99780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 100780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void output_prop_hex(FILE *out_fp, const char *name, uint32_t value) { 101780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, "%+20s = %08x\n", name, fdt32_to_cpu(value)); 102780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 103780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 104780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void output_prop_str(FILE *out_fp, const char *name, const char *value) { 105780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, "%+20s = %s\n", name, value); 106780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 107780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 108780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void output_table_header(FILE *out_fp, const struct dt_table_header *header) { 109780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, "dt_table_header:\n"); 110780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "magic", header->magic); 111780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "total_size", header->total_size); 112780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "header_size", header->header_size); 113780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "dt_entry_size", header->dt_entry_size); 114780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "dt_entry_count", header->dt_entry_count); 115780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "dt_entries_offset", header->dt_entries_offset); 116780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "page_size", header->page_size); 117780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "reserved[0]", header->reserved[0]); 118780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 119780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 120780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic void output_table_entry(FILE *out_fp, int index, const struct dt_table_entry *entry) { 121780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, "dt_table_entry[%d]:\n", index); 122780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "dt_size", entry->dt_size); 123780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int(out_fp, "dt_offset", entry->dt_offset); 124780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "id", entry->id); 125780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "rev", entry->rev); 126780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "custom[0]", entry->custom[0]); 127780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "custom[1]", entry->custom[1]); 128780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "custom[2]", entry->custom[2]); 129780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_hex(out_fp, "custom[3]", entry->custom[3]); 130780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 131780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 132780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int output_fdt_info(FILE *out_fp, void *fdt) { 133780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin size_t fdt_size = fdt_totalsize(fdt); 134780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_int_cpu(out_fp, "(FDT)size", fdt_size); 135780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 136780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int root_node_off = fdt_path_offset(fdt, "/"); 137780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (root_node_off < 0) { 138780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not get the root node.\n"); 139780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return -1; 140780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 141780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 142780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const char *compatible = 143780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin (const char *)fdt_getprop(fdt, root_node_off, "compatible", NULL); 144780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_prop_str(out_fp, "(FDT)compatible", compatible ? compatible : "(unknown)"); 145780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 146780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 0; 147780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 148780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 149780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int dump_image_from_fp(FILE *out_fp, FILE *img_fp, 150780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin const struct dump_params *params) { 151780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin struct dt_table_header header; 152780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (fread(&header, sizeof(header), 1, img_fp) != 1) { 153780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Read error.\n"); 154780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return -1; 155780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 156780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* TODO: check header */ 157780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_table_header(out_fp, &header); 158780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 159780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t entry_size = fdt32_to_cpu(header.dt_entry_size); 160780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t entry_offset = fdt32_to_cpu(header.dt_entries_offset); 161780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t entry_count = fdt32_to_cpu(header.dt_entry_count); 162780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t i; 163780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin for (i = 0; i < entry_count; i++) { 164780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin struct dt_table_entry entry; 165780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fseek(img_fp, entry_offset, SEEK_SET); 166780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fread(&entry, sizeof(entry), 1, img_fp); 167780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_table_entry(out_fp, i, &entry); 168780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 169780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t dt_size = fdt32_to_cpu(entry.dt_size); 170780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin uint32_t dt_offset = fdt32_to_cpu(entry.dt_offset); 171780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (dt_size > 0 && dt_offset > 0) { 172780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin void *fdt = read_fdt_from_image(img_fp, dt_offset, dt_size); 173780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin output_fdt_info(out_fp, fdt); 174780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 175780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (params->out_dtb_filename != NULL) { 176780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin char filename[256]; 177780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin snprintf(filename, sizeof(filename), "%s.%d", 178780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params->out_dtb_filename, i); 179780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin write_fdt_to_file(filename, fdt); 180780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 181780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 182780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin free_fdt(fdt); 183780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 184780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 185780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin entry_offset += entry_size; 186780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 187780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 188780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 0; 189780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 190780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 191780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linstatic int process_command_dump(const struct dump_params *params) { 192780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int ret = -1; 193780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin FILE *out_fp = NULL; 194780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin FILE *img_fp = NULL; 195780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 196780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin img_fp = fopen(params->img_filename, "rb"); 197780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (img_fp == NULL) { 198780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not open image file: %s\n", params->img_filename); 199780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 200780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 201780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 202780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (params->out_filename != NULL) { 203780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin out_fp = fopen(params->out_filename, "w"); 204780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (out_fp == NULL) { 205780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(stderr, "Can not create file: %s\n", params->out_filename); 206780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin goto end; 207780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 208780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 209780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 210780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin ret = dump_image_from_fp(out_fp ? out_fp : stdout, img_fp, params); 211780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 212780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linend: 213780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (img_fp) fclose(img_fp); 214780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (out_fp) fclose(out_fp); 215780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 216780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return ret; 217780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 218780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 219780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linvoid handle_usage_dump(FILE *out_fp, const char *prog_name) { 220780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, " %s dump <image_file> (<option>...)\n\n", prog_name); 221780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin fprintf(out_fp, 222780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " options:\n" 223780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " -o, --output <filename> Output file name.\n" 224780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " Default is output to stdout.\n" 225780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " -b, --dtb <filename> Dump dtb/dtbo files from image.\n" 226780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin " Will output to <filename>.0, <filename>.1, etc.\n"); 227780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 228780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 229780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Linint handle_command_dump(int argc, char *argv[], int arg_start) { 230780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (argc - arg_start < 1) { 231780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin handle_usage_dump(stderr, argv[0]); 232780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 1; 233780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 234780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 235780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin struct dump_params params; 236780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin memset(¶ms, 0, sizeof(params)); 237780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params.img_filename = argv[arg_start]; 238780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 239780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin optind = arg_start + 1; 240780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin while (1) { 241780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin int c = getopt_long(argc, argv, short_options, options, NULL); 242780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin if (c == -1) { 243780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin break; 244780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 245780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin switch (c) { 246780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin case 'o': 247780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params.out_filename = optarg; 248780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin break; 249780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin case 'b': 250780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin params.out_dtb_filename = optarg; 251780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin break; 252780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin default: 253780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin /* Unknown option, return error */ 254780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return 1; 255780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 256780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin } 257780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin 258780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin return process_command_dump(¶ms); 259780c3b0fba4bb4dbd39091ebbd1ddc3eacb2deb9SzuWei Lin} 260