summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dtbtool.c253
1 files changed, 88 insertions, 165 deletions
diff --git a/dtbtool.c b/dtbtool.c
index 08a1b8a..af219ca 100644
--- a/dtbtool.c
+++ b/dtbtool.c
@@ -39,7 +39,6 @@
#include <getopt.h>
#include <errno.h>
#include <unistd.h>
-#include <limits.h>
#define QCDT_MAGIC "QCDT" /* Master DTB magic */
#define QCDT_VERSION 3 /* QCDT version */
@@ -105,23 +104,19 @@ struct chipPt_t {
char *input_dir;
char *output_file;
char *dtc_path;
-char *dt_tag = QCDT_DT_TAG;
int verbose;
int page_size = PAGE_SIZE_DEF;
-int version_override = 0;
+
void print_help()
{
- log_info("dtbTool version %d (kinda :) )\n", QCDT_VERSION);
+ log_info("dtbTool version %d\n", QCDT_VERSION);
log_info("dtbTool [options] -o <output file> <input DTB path>\n");
log_info(" options:\n");
log_info(" --output-file/-o output file\n");
log_info(" --dtc-path/-p path to dtc\n");
log_info(" --page-size/-s page size in bytes\n");
- log_info(" --dt-tag/-d alternate QCDT_DT_TAG\n");
log_info(" --verbose/-v verbose\n");
- log_info(" --force-v2/-2 output dtb v2 format\n");
- log_info(" --force-v3/-3 output dtb v3 format\n");
log_info(" --help/-h this help screen\n");
}
@@ -133,15 +128,12 @@ int parse_commandline(int argc, char *const argv[])
{"output-file", 1, 0, 'o'},
{"dtc-path", 1, 0, 'p'},
{"page-size", 1, 0, 's'},
- {"dt-tag", 1, 0, 'd'},
- {"force-v2", 0, 0, '2'},
- {"force-v3", 0, 0, '3'},
{"verbose", 0, 0, 'v'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
- while ((c = getopt_long(argc, argv, "-o:p:s:d:23vh", long_options, NULL))
+ while ((c = getopt_long(argc, argv, "-o:p:s:vh", long_options, NULL))
!= -1) {
switch (c) {
case 1:
@@ -161,17 +153,6 @@ int parse_commandline(int argc, char *const argv[])
return RC_ERROR;
}
break;
- case 'd':
- dt_tag = optarg;
- break;
- case '2':
- case '3':
- if (version_override != 0) {
- log_err("A version output argument may only be passed once\n");
- return RC_ERROR;
- }
- version_override = c - '0';
- break;
case 'v':
verbose = 1;
break;
@@ -329,8 +310,8 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi
/* Find "qcom,msm-id" */
while ((llen = getline(&line, &line_size, pfile)) != -1) {
if (msmversion == 1) {
- if ((pos = strstr(line, dt_tag)) != NULL) {
- pos += strlen(dt_tag);
+ if ((pos = strstr(line, QCDT_DT_TAG)) != NULL) {
+ pos += strlen(QCDT_DT_TAG);
entryEnded = 0;
while (1) {
@@ -388,12 +369,12 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi
}
}
- log_err("... skip, incorrect '%s' format\n", dt_tag);
+ log_err("... skip, incorrect '%s' format\n", QCDT_DT_TAG);
break;
}
} else if (msmversion == 2 || msmversion == 3) {
- if ((pos = strstr(line, dt_tag)) != NULL) {
- pos += strlen(dt_tag);
+ if ((pos = strstr(line, QCDT_DT_TAG)) != NULL) {
+ pos += strlen(QCDT_DT_TAG);
entryEndedDT = 0;
for (;entryEndedDT < 1;) {
@@ -536,7 +517,7 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi
free(line);
if (count1 == 0) {
- log_err("... skip, incorrect '%s' format\n", dt_tag);
+ log_err("... skip, incorrect '%s' format\n", QCDT_DT_TAG);
return NULL;
}
if (count2 == 0) {
@@ -657,7 +638,7 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi
}
/* Get the version-id based on dtb files */
-uint32_t GetVersionInfo(const char *filename)
+int GetVersionInfo(const char *filename)
{
const char str1[] = "dtc -I dtb -O dts \"";
const char str2[] = "\" 2>&1";
@@ -666,7 +647,7 @@ uint32_t GetVersionInfo(const char *filename)
size_t line_size;
FILE *pfile;
int llen;
- uint32_t v = 1;
+ int v = 1;
line_size = 1024;
line = (char *)malloc(line_size);
@@ -699,13 +680,13 @@ uint32_t GetVersionInfo(const char *filename)
} else {
/* Find the type of version */
while ((llen = getline(&line, &line_size, pfile)) != -1) {
- if ((pos = strstr(line,QCDT_BOARD_TAG)) != NULL) {
+ if ((pos = strstr(line,QCDT_BOARD_TAG)) != NULL) {
v = 2;
- }
- if ((pos = strstr(line,QCDT_PMIC_TAG)) != NULL) {
+ }
+ if ((pos = strstr(line,QCDT_PMIC_TAG)) != NULL) {
v = 3;
break;
- }
+ }
}
}
@@ -715,84 +696,94 @@ uint32_t GetVersionInfo(const char *filename)
return v;
}
-static int find_dtb(const char *path, uint32_t *version)
+/* Extract 'qcom,msm-id' 'qcom,board-id' parameter from DTB
+ v1 format:
+ qcom,msm-id = <x y z> [, <x2 y2 z2> ...];
+ v2 format:
+ qcom,msm-id = <x z> [, <x2 z2> ...;
+ qcom,board-id = <y y'> [, <y2 y2'> ...;
+ Fields:
+ x = chipset
+ y = platform
+ y' = subtype
+ z = soc rev
+ */
+int main(int argc, char **argv)
{
+ char buf[COPY_BLK];
+ struct chipInfo_t *chip, *t_chip;
struct dirent *dp;
- int flen;
+ FILE *pInputFile;
char *filename;
- struct chipInfo_t *chip, *t_chip;
+ int padding;
+ uint8_t *filler = NULL;
+ int numBytesRead = 0;
+ int totBytesRead = 0;
+ int out_fd;
+ int flen;
+ int rc = RC_SUCCESS;
+ int dtb_count = 0, dtb_offset = 0;
+ size_t wrote = 0, expected = 0;
struct stat st;
+ uint32_t version = QCDT_VERSION;
int num;
- int rc = RC_SUCCESS;
- uint32_t msmversion = 0;
- int dtb_count = 0;
+ uint32_t dtb_size;
+ int msmversion = 0;
+
+ log_info("DTB combiner:\n");
+
+ if (parse_commandline(argc, argv) != RC_SUCCESS) {
+ print_help();
+ return RC_ERROR;
+ }
- DIR *dir = opendir(path);
+ log_info(" Input directory: '%s'\n", input_dir);
+ log_info(" Output file: '%s'\n", output_file);
+
+ DIR *dir = opendir(input_dir);
if (!dir) {
- log_err("Failed to open input directory '%s'\n", path);
+ log_err("Failed to open input directory '%s'\n", input_dir);
+ return RC_ERROR;
+ }
+
+ filler = (uint8_t *)malloc(page_size);
+ if (!filler) {
+ log_err("Out of memory\n");
+ closedir(dir);
return RC_ERROR;
}
+ memset(filler, 0, page_size);
/* Open the .dtb files in the specified path, decompile and
extract "qcom,msm-id" parameter
*/
while ((dp = readdir(dir)) != NULL) {
- if (dp->d_type == DT_UNKNOWN) {
- struct stat statbuf;
- char name[PATH_MAX];
- snprintf(name, sizeof(name), "%s%s%s",
- path,
- (path[strlen(path) - 1] == '/' ? "" : "/"),
- dp->d_name);
- if (!stat(name, &statbuf)) {
- if (S_ISREG(statbuf.st_mode)) {
- dp->d_type = DT_REG;
- } else if (S_ISDIR(statbuf.st_mode)) {
- dp->d_type = DT_DIR;
- }
- }
- }
-
- if (dp->d_type == DT_DIR) {
- char name[PATH_MAX];
- if (dp->d_name[0] == '.') {
- continue;
- }
- snprintf(name, sizeof(name), "%s%s%s%s",
- path,
- (path[strlen(path) - 1] == '/' ? "" : "/"),
- dp->d_name,
- "/");
- log_info("Searching subdir: %s ... \n", name);
- dtb_count += find_dtb(name, version);
- } else if (dp->d_type == DT_REG) {
+ if ((dp->d_type == DT_REG)) {
flen = strlen(dp->d_name);
if ((flen > 4) &&
(strncmp(&dp->d_name[flen-4], ".dtb", 4) == 0)) {
log_info("Found file: %s ... \n", dp->d_name);
- flen = strlen(path) + strlen(dp->d_name) + 1;
+ flen = strlen(input_dir) + strlen(dp->d_name) + 1;
filename = (char *)malloc(flen);
if (!filename) {
log_err("Out of memory\n");
rc = RC_ERROR;
break;
}
- strncpy(filename, path, flen);
+ strncpy(filename, input_dir, flen);
strncat(filename, dp->d_name, flen);
/* To identify the version number */
msmversion = GetVersionInfo(filename);
- if (*version < msmversion) {
- *version = msmversion;
- }
num = 1;
chip = getChipInfo(filename, &num, msmversion);
if (msmversion == 1) {
if (!chip) {
- log_err("skip, failed to scan for '%s' tag\n", dt_tag);
+ log_err("skip, failed to scan for '%s' tag\n",
+ QCDT_DT_TAG);
free(filename);
continue;
}
@@ -800,7 +791,7 @@ static int find_dtb(const char *path, uint32_t *version)
if (msmversion == 2) {
if (!chip) {
log_err("skip, failed to scan for '%s' or '%s' tag\n",
- dt_tag, QCDT_BOARD_TAG);
+ QCDT_DT_TAG, QCDT_BOARD_TAG);
free(filename);
continue;
}
@@ -808,7 +799,7 @@ static int find_dtb(const char *path, uint32_t *version)
if (msmversion == 3) {
if (!chip) {
log_err("skip, failed to scan for '%s', '%s' or '%s' tag\n",
- dt_tag, QCDT_BOARD_TAG, QCDT_PMIC_TAG);
+ QCDT_DT_TAG, QCDT_BOARD_TAG, QCDT_PMIC_TAG);
free(filename);
continue;
}
@@ -847,7 +838,7 @@ static int find_dtb(const char *path, uint32_t *version)
for (t_chip = chip->t_next; t_chip; t_chip = t_chip->t_next) {
rc = chip_add(t_chip);
if (rc != RC_SUCCESS) {
- log_err("... duplicate info, skipped (chipset %u, rev: %u, platform: %u, subtype: %u\n",
+ log_err("... duplicate info, skipped (chipset %u, rev: %u, platform: %u, subtype %u:\n",
t_chip->chipset, t_chip->revNum, t_chip->platform, t_chip->subtype);
continue;
}
@@ -857,58 +848,6 @@ static int find_dtb(const char *path, uint32_t *version)
}
}
closedir(dir);
- return dtb_count;
-}
-
-/* Extract 'qcom,msm-id' 'qcom,board-id' parameter from DTB
- v1 format:
- qcom,msm-id = <x y z> [, <x2 y2 z2> ...];
- v2 format:
- qcom,msm-id = <x z> [, <x2 z2> ...;
- qcom,board-id = <y y'> [, <y2 y2'> ...;
- Fields:
- x = chipset
- y = platform
- y' = subtype
- z = soc rev
- */
-int main(int argc, char **argv)
-{
- char buf[COPY_BLK];
- struct chipInfo_t *chip;
- FILE *pInputFile;
- int padding;
- uint8_t *filler = NULL;
- int numBytesRead = 0;
- int totBytesRead = 0;
- int out_fd;
- int rc = RC_SUCCESS;
- int dtb_count = 0, dtb_offset = 0, entry_size;
- size_t wrote = 0, expected = 0;
- uint32_t dtb_size;
- uint32_t version = 0;
- char *filename;
-
- log_info("DTB combiner:\n");
-
- if (parse_commandline(argc, argv) != RC_SUCCESS) {
- print_help();
- return RC_ERROR;
- }
-
- log_info(" Input directory: '%s'\n", input_dir);
- log_info(" Output file: '%s'\n", output_file);
-
-
- filler = (uint8_t *)malloc(page_size);
- if (!filler) {
- log_err("Out of memory\n");
- return RC_ERROR;
- }
- memset(filler, 0, page_size);
-
- dtb_count = find_dtb(input_dir, &version);
-
log_info("=> Found %d unique DTB(s)\n", dtb_count);
if (!dtb_count)
@@ -923,25 +862,13 @@ int main(int argc, char **argv)
log_info("\nGenerating master DTB... ");
- out_fd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
- if (out_fd == -1) {
+ out_fd = open(output_file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
+ if (!out_fd < 0) {
log_err("Cannot create '%s'\n", output_file);
rc = RC_ERROR;
goto cleanup;
}
- if (version_override != 0) {
- version = version_override;
- }
-
- if (version == 1) {
- entry_size = 20;
- } else if (version == 2) {
- entry_size = 24;
- } else {
- entry_size = 40;
- }
-
/* Write header info */
wrote += write(out_fd, QCDT_MAGIC, sizeof(uint8_t) * 4); /* magic */
wrote += write(out_fd, &version, sizeof(uint32_t)); /* version */
@@ -949,9 +876,9 @@ int main(int argc, char **argv)
/* #DTB */
/* Calculate offset of first DTB block */
- dtb_offset = 12 + /* header */
- (entry_size * dtb_count) + /* DTB table entries */
- 4; /* end of table indicator */
+ dtb_offset = 12 + /* header */
+ (40 * dtb_count) + /* DTB table entries */
+ 4; /* end of table indicator */
/* Round up to page size */
padding = page_size - (dtb_offset % page_size);
@@ -961,28 +888,24 @@ int main(int argc, char **argv)
/* Write index table:
chipset
platform
- subtype (v2/v3 only)
+ subtype
soc rev
- pmic model0 (v3 only)
- pmic model1 (v3 only)
- pmic model2 (v3 only)
- pmic model3 (v3 only)
+ pmic model0
+ pmic model1
+ pmic model2
+ pmic model3
dtb offset
dtb size
*/
for (chip = chip_list; chip; chip = chip->next) {
wrote += write(out_fd, &chip->chipset, sizeof(uint32_t));
wrote += write(out_fd, &chip->platform, sizeof(uint32_t));
- if (version >= 2) {
- wrote += write(out_fd, &chip->subtype, sizeof(uint32_t));
- }
+ wrote += write(out_fd, &chip->subtype, sizeof(uint32_t));
wrote += write(out_fd, &chip->revNum, sizeof(uint32_t));
- if (version >= 3) {
- wrote += write(out_fd, &chip->pmic_model[0], sizeof(uint32_t));
- wrote += write(out_fd, &chip->pmic_model[1], sizeof(uint32_t));
- wrote += write(out_fd, &chip->pmic_model[2], sizeof(uint32_t));
- wrote += write(out_fd, &chip->pmic_model[3], sizeof(uint32_t));
- }
+ wrote += write(out_fd, &chip->pmic_model[0], sizeof(uint32_t));
+ wrote += write(out_fd, &chip->pmic_model[1], sizeof(uint32_t));
+ wrote += write(out_fd, &chip->pmic_model[2], sizeof(uint32_t));
+ wrote += write(out_fd, &chip->pmic_model[3], sizeof(uint32_t));
if (chip->master->master_offset != 0) {
wrote += write(out_fd, &chip->master->master_offset, sizeof(uint32_t));
} else {
@@ -1036,11 +959,11 @@ int main(int argc, char **argv)
close(out_fd);
if (expected != wrote) {
- log_err("error writing output file, please rerun: size mismatch %zu vs %zu\n",
+ log_err("error writing output file, please rerun: size mismatch %d vs %d\n",
expected, wrote);
rc = RC_ERROR;
} else
- log_dbg("Total wrote %zu bytes\n", wrote);
+ log_dbg("Total wrote %u bytes\n", wrote);
if (rc != RC_SUCCESS)
unlink(output_file);