269 lines
9.4 KiB
Diff
269 lines
9.4 KiB
Diff
From 4c73ce48d22cba69d775c7efe5bb20fdf38a5c7d Mon Sep 17 00:00:00 2001
|
|
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);
|
|
--
|
|
1.7.4.2
|
|
|