196 lines
6.5 KiB
Diff
196 lines
6.5 KiB
Diff
From: Hector Palacios <hector.palacios@digi.com>
|
|
Date: Tue, 15 Oct 2013 18:58:11 +0200
|
|
Subject: dump v1 boot structures
|
|
|
|
The kobs-ng that we received from Freescale did not support reading the
|
|
boot structures on the mx28. It could write them, but the function that
|
|
reads them was never updated to handle the updated structures used by
|
|
the mx28. This change adds basic support for reading these structures,
|
|
enough so that the dump command works.
|
|
|
|
(forward ported from kobs-ng-10.12.01 to kobs-ng-3.0.35_4.1.0)
|
|
|
|
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
|
|
Reviewed-by: Robert Hodaszi <robert.hodaszi@digi.com>
|
|
---
|
|
src/main.c | 5 ++-
|
|
src/mtd.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
src/mtd.h | 1 +
|
|
3 files changed, 131 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/src/main.c b/src/main.c
|
|
index 82b6f9e..70517b0 100644
|
|
--- a/src/main.c
|
|
+++ b/src/main.c
|
|
@@ -152,7 +152,10 @@ int dump_main(int argc, char **argv)
|
|
if (flags & F_VERBOSE)
|
|
mtd_dump(md);
|
|
|
|
- r = mtd_load_all_boot_structures(md);
|
|
+ if (ROM_Version_1 == plat_config_data->m_u32RomVer)
|
|
+ r = mtd_load_v1_boot_structures(md);
|
|
+ else
|
|
+ r = mtd_load_all_boot_structures(md);
|
|
if (r != 0) {
|
|
fprintf(stderr, "Unable to load boot structures\n");
|
|
exit(5);
|
|
diff --git a/src/mtd.c b/src/mtd.c
|
|
index f9e60a3..9ea92ad 100644
|
|
--- a/src/mtd.c
|
|
+++ b/src/mtd.c
|
|
@@ -975,6 +975,130 @@ void dump(const void *data, int size)
|
|
printf("\n");
|
|
}
|
|
|
|
+/*
|
|
+ * This function is a hack written by Digi because the original code from
|
|
+ * Freescale did not supporting reading the bootlet structures at all.
|
|
+ * This function reads the search areas for a given BCB. It will read the first
|
|
+ * search area and use it if the read succeeds. If the read fails, then it will
|
|
+ * try again with the second search area.
|
|
+ *
|
|
+ * md A pointer to the current struct mtd_data.
|
|
+ * bcb_name A pointer to a human-readable string that indicates what kind of
|
|
+ * BCB we're reading. This string will only be used in log messages.
|
|
+ * ofs1 If there is one chips, the index of the search area to read
|
|
+ * ofs2
|
|
+ * ofs_mchip If there are multiple chips, the index of the search area to read
|
|
+ * on both chips.
|
|
+ * end The number of consecutive search areas to be read.
|
|
+ * size The size of the BCB data to be read.
|
|
+ * ecc Indicates whether or not to use hardware ECC.
|
|
+ */
|
|
+int mtd_read_bcb(struct mtd_data *md, char *bcb_name,
|
|
+ loff_t ofs1, loff_t ofs2, loff_t ofs_mchip,
|
|
+ loff_t end, size_t size, int ecc)
|
|
+{
|
|
+ int chip;
|
|
+ loff_t end_index, search_area_indices[2], o;
|
|
+ int r;
|
|
+ int i;
|
|
+ int j;
|
|
+ unsigned stride_size_in_bytes;
|
|
+ unsigned search_area_size_in_strides;
|
|
+ unsigned search_area_size_in_bytes;
|
|
+
|
|
+ /* Compute some important facts about geometry */
|
|
+ if (plat_config_data->m_u32RomVer == ROM_Version_2) {
|
|
+ stride_size_in_bytes = mtd_erasesize(md);
|
|
+ search_area_size_in_strides = 4;
|
|
+ search_area_size_in_bytes = search_area_size_in_strides * stride_size_in_bytes;
|
|
+ } else {
|
|
+ stride_size_in_bytes = PAGES_PER_STRIDE * mtd_writesize(md);
|
|
+ search_area_size_in_strides = 1 << md->cfg.search_exponent;
|
|
+ search_area_size_in_bytes = search_area_size_in_strides * stride_size_in_bytes;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Check whether there are multiple chips and set up the two search area
|
|
+ * indices accordingly.
|
|
+ */
|
|
+ if (multichip(md))
|
|
+ search_area_indices[0] = search_area_indices[1] = ofs_mchip;
|
|
+ else {
|
|
+ search_area_indices[0] = ofs1;
|
|
+ search_area_indices[1] = ofs2;
|
|
+ }
|
|
+
|
|
+ /* Loop over search areas for this BCB. */
|
|
+ for (i = 0; i < 2; i++) {
|
|
+ /*
|
|
+ * Compute the search area index that marks the end of the
|
|
+ * writing on this chip.
|
|
+ */
|
|
+ end_index = search_area_indices[i] + end;
|
|
+
|
|
+ /* Figure out which chip we're writing */
|
|
+ chip = multichip(md) ? i : 0;
|
|
+
|
|
+ /* Loop over consecutive search areas to write. */
|
|
+ for (; search_area_indices[i] < end_index; search_area_indices[i]++) {
|
|
+ /*
|
|
+ * Compute the byte offset of the beginning of this
|
|
+ * search area
|
|
+ */
|
|
+ o = search_area_indices[i] * search_area_size_in_bytes;
|
|
+
|
|
+ /* Loop over strides in this search area. */
|
|
+ for (j = 0; j < search_area_size_in_strides; j++, o += stride_size_in_bytes) {
|
|
+ /*
|
|
+ * If we're crossing into a new block, erase it
|
|
+ * first.
|
|
+ */
|
|
+
|
|
+ /* Write the page */
|
|
+ vp(md, "mtd: Reading %s%d @%d:0x%llx(%x)\n",
|
|
+ bcb_name, j, chip, o, size);
|
|
+
|
|
+ r = mtd_read_page(md, chip, o, ecc);
|
|
+ if (r != size) {
|
|
+ fprintf(stderr, "\n%s r = 0x%8.8X, size = 0x%8.8X\n", __func__, r, size);
|
|
+ fprintf(stderr, "mtd: Failed to read %s @%d: 0x%llx (%d)\n",
|
|
+ bcb_name, chip, o, r);
|
|
+ } else
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return !(r == size);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function is a hack by Digi, written because the original code from
|
|
+ * Freescale did not support reading the v1 boot structures at all. Do not
|
|
+ * use the results from this function for anything other than browsing the
|
|
+ * boot structures.
|
|
+ */
|
|
+int mtd_load_v1_boot_structures(struct mtd_data *md)
|
|
+{
|
|
+ int err = 0;
|
|
+
|
|
+ /* read the FCB search area */
|
|
+ err = mtd_read_bcb(md, "FCB", 0, 0, 0, 1,
|
|
+ mtd_writesize(md) + mtd_oobsize(md), false);
|
|
+ memcpy(&md->fcb, md->buf, sizeof(md->fcb));
|
|
+
|
|
+ /* read the DBBT search area */
|
|
+ err |= mtd_read_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
|
|
+ memcpy(&md->dbbt28, md->buf, sizeof(md->dbbt28));
|
|
+
|
|
+ if ((err != 0) ||
|
|
+ (md->dbbt28.m_u32FingerPrint != DBBT_FINGERPRINT2)) {
|
|
+ err = -1;
|
|
+ }
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_t end,
|
|
uint32_t magic1, uint32_t magic2, uint32_t magic3, int use_ecc,
|
|
int magic_offset)
|
|
@@ -1083,9 +1207,8 @@ int mtd_load_all_boot_structures(struct mtd_data *md)
|
|
md->curr_ncb = NULL;
|
|
md->ncb_version = ncb_get_version(buf, &md->curr_ncb);
|
|
|
|
- if (md->flags & F_VERBOSE)
|
|
- printf("mtd: found NCB%d candidate version %d @%d:0x%llx\n",
|
|
- i, md->ncb_version, chip, ofs);
|
|
+ vp(md, "mtd: found NCB%d candidate version %d @%d:0x%llx\n",
|
|
+ i, md->ncb_version, chip, ofs);
|
|
|
|
if (md->ncb_version >= 0)
|
|
break;
|
|
diff --git a/src/mtd.h b/src/mtd.h
|
|
index bf6e53d..18e4d70 100644
|
|
--- a/src/mtd.h
|
|
+++ b/src/mtd.h
|
|
@@ -276,6 +276,7 @@ void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_
|
|
uint32_t magic1, uint32_t magic2, uint32_t magic3, int use_ecc,
|
|
int magic_offset);
|
|
int mtd_load_all_boot_structures(struct mtd_data *md);
|
|
+int mtd_load_v1_boot_structures(struct mtd_data *md);
|
|
int mtd_dump_structure(struct mtd_data *md);
|
|
|
|
int v0_rom_mtd_init(struct mtd_data *md, FILE *fp);
|