meta-digi/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-10.12.01/0001-dump-v1-boot-structure...

265 lines
9.3 KiB
Diff

From: Javier Viguera <javier.viguera@digi.com>
Date: Fri, 1 Apr 2011 14:45:52 +0200
Subject: [PATCH] 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. I would not recommend using
any of the other functions, such as extract or update though.
Signed-off-by: Javier Viguera <javier.viguera@digi.com>
---
src/main.c | 6 ++-
src/mtd.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/mtd.h | 1 +
3 files changed, 174 insertions(+), 4 deletions(-)
diff --git a/src/main.c b/src/main.c
index 0b83828..c21dece 100644
--- a/src/main.c
+++ b/src/main.c
@@ -146,7 +146,11 @@ int dump_main(int argc, char **argv)
if (flags & F_VERBOSE)
mtd_dump(md);
- r = mtd_load_all_boot_structures(md);
+ if (rom_version == ROM_Version_1) {
+ 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 b827a80..bcbb8d3 100644
--- a/src/mtd.c
+++ b/src/mtd.c
@@ -65,6 +65,11 @@ const struct mtd_config default_mtd_config = {
.boot_stream_2_address = 0,
};
+
+static 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);
+
static inline int multichip(struct mtd_data *md)
{
return md->flags & F_MULTICHIP;
@@ -932,6 +937,32 @@ void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_
return md->buf;
}
+// 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;
+
+ 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;
+}
+
/* single chip version */
int mtd_load_all_boot_structures(struct mtd_data *md)
{
@@ -1754,7 +1785,7 @@ int v1_rom_mtd_init(struct mtd_data *md, FILE *fp)
}
-v2_rom_mtd_init(struct mtd_data *md, FILE *fp)
+int v2_rom_mtd_init(struct mtd_data *md, FILE *fp)
{
unsigned int stride_size_in_bytes;
unsigned int search_area_size_in_bytes;
@@ -1774,7 +1805,7 @@ v2_rom_mtd_init(struct mtd_data *md, FILE *fp)
// Compute the geometry of a search area.
//----------------------------------------------------------------------
- stride_size_in_bytes = mtd_erasesize;
+ stride_size_in_bytes = mtd_erasesize(md);
search_area_size_in_bytes = 4 * stride_size_in_bytes;
search_area_size_in_pages = search_area_size_in_bytes / mtd_writesize(md);
@@ -2053,6 +2084,140 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name,
return err;
}
+
+//------------------------------------------------------------------------------
+// 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 (rom_version == 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.
+ //----------------------------------------------
+
+ if (md->flags & F_VERBOSE)
+ printf("mtd: Reading %s%d @%d:0x%llx(%x)\n",
+ bcb_name, j, chip, o, size);
+
+/*int mtd_commit_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) */
+/* mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false); */
+ 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);
+}
+
+
int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
{
int startpage, start, size;
@@ -2367,7 +2532,7 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
}
-v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
+int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
{
int startpage, start, size;
unsigned int search_area_size_in_bytes, stride_size_in_bytes;
diff --git a/src/mtd.h b/src/mtd.h
index b5c866e..cff09af 100644
--- a/src/mtd.h
+++ b/src/mtd.h
@@ -254,6 +254,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);