328 lines
12 KiB
Diff
328 lines
12 KiB
Diff
From 730703eef88d4ed1d09d011ebaf0ba5b5976ad7f Mon Sep 17 00:00:00 2001
|
|
From: Hector Palacios <hector.palacios@digi.com>
|
|
Date: Tue, 19 Apr 2011 13:45:53 +0200
|
|
Subject: [PATCH] added verification of written data (only for v1 ROM)
|
|
|
|
Added new option to verify data committed to flash right after writing.
|
|
After each BCB or bootstream page write, the data is read back from flash
|
|
and verified against the written buffer in RAM.
|
|
If the verification fails the program exits.
|
|
|
|
Only added for v1_rom_mtd_commit_structures() -> MX28 arch.
|
|
|
|
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
|
|
---
|
|
src/main.c | 25 ++++++++++++++++------
|
|
src/mtd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++----------
|
|
src/mtd.h | 6 ++--
|
|
3 files changed, 75 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/src/main.c b/src/main.c
|
|
index eb9504d..bd0bac0 100644
|
|
--- a/src/main.c
|
|
+++ b/src/main.c
|
|
@@ -76,10 +76,12 @@ void usage(void)
|
|
" -v .................................... Verbose mode\n"
|
|
" -n .................................... Dry run (don't commit to flash)\n"
|
|
" -w .................................... Commit to flash\n"
|
|
+ " -c .................................... Check committed data in flash\n"
|
|
"\n"
|
|
" update [-v] [KEY] [KOBS] [-0|1] <file> .. Update a single bootstream\n"
|
|
" -v .................................... Verbose mode\n"
|
|
" -0|1 .................................. Update specified bootstream #\n"
|
|
+ " -c .................................... Check committed data in flash\n"
|
|
"\n"
|
|
" extract [-v] [KEY] [KOBS] [-0|1] <file> . Extract a bootstream from flash\n"
|
|
" -v .................................... Verbose mode\n"
|
|
@@ -378,7 +380,7 @@ int extract_main(int argc, char **argv)
|
|
return 0;
|
|
}
|
|
|
|
-static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_mask)
|
|
+static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_mask, int check)
|
|
{
|
|
int i, r;
|
|
unsigned int size, start, avail, end, update;
|
|
@@ -423,7 +425,7 @@ static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_
|
|
update |= UPDATE_BS(i);
|
|
}
|
|
|
|
- r = v0_rom_mtd_commit_structures(md, infp, UPDATE_LDLB | update);
|
|
+ r = v0_rom_mtd_commit_structures(md, infp, UPDATE_LDLB | update, check);
|
|
if (r < 0) {
|
|
fprintf(stderr, "FAILED to commit structures\n");
|
|
return -1;
|
|
@@ -445,6 +447,7 @@ int update_main(int argc, char **argv)
|
|
char ascii[20 * 2 + 1];
|
|
int device_key;
|
|
uint8_t *keyp;
|
|
+ int check;
|
|
|
|
memset(key, 0, sizeof(key));
|
|
device_key = 0;
|
|
@@ -461,6 +464,7 @@ int update_main(int argc, char **argv)
|
|
image_mask = 0; /* no image */
|
|
flags = 0;
|
|
j = 0;
|
|
+ check = 0;
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
if (argv[i][0] != '-') {
|
|
@@ -488,6 +492,9 @@ int update_main(int argc, char **argv)
|
|
exit(5);
|
|
}
|
|
break;
|
|
+ case 'c':
|
|
+ check = 1;
|
|
+ break;
|
|
case 'v':
|
|
flags |= F_VERBOSE;
|
|
break;
|
|
@@ -533,7 +540,7 @@ int update_main(int argc, char **argv)
|
|
if (flags & F_VERBOSE)
|
|
mtd_dump(md);
|
|
|
|
- r = perform_bootstream_update(md, infp, image_mask);
|
|
+ r = perform_bootstream_update(md, infp, image_mask, check);
|
|
if (r != 0) {
|
|
fprintf(stderr, "Unable to perform bootstream update\n");
|
|
usage();
|
|
@@ -555,7 +562,7 @@ int init_main(int argc, char **argv)
|
|
char *badlist = NULL;
|
|
FILE *infp;
|
|
loff_t ofs;
|
|
- int dryrun;
|
|
+ int dryrun, check;
|
|
struct mtd_config cfg;
|
|
uint8_t key[16];
|
|
char ascii[20 * 2 + 1];
|
|
@@ -577,6 +584,7 @@ int init_main(int argc, char **argv)
|
|
image = 0; /* first image */
|
|
flags = 0;
|
|
dryrun = 0;
|
|
+ check = 0;
|
|
j = 0;
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
@@ -598,6 +606,9 @@ int init_main(int argc, char **argv)
|
|
case 'w':
|
|
dryrun = 0;
|
|
break;
|
|
+ case 'c':
|
|
+ check = 1;
|
|
+ break;
|
|
case 'n':
|
|
dryrun = 1;
|
|
break;
|
|
@@ -692,13 +703,13 @@ int init_main(int argc, char **argv)
|
|
if (!dryrun) {
|
|
switch (rom_version) {
|
|
case ROM_Version_0:
|
|
- r = v0_rom_mtd_commit_structures(md, infp, UPDATE_ALL);
|
|
+ r = v0_rom_mtd_commit_structures(md, infp, UPDATE_ALL, check);
|
|
break;
|
|
case ROM_Version_1:
|
|
- r = v1_rom_mtd_commit_structures(md, infp, UPDATE_ALL);
|
|
+ r = v1_rom_mtd_commit_structures(md, infp, UPDATE_ALL, check);
|
|
break;
|
|
case ROM_Version_2:
|
|
- r = v2_rom_mtd_commit_structures(md, infp, UPDATE_ALL);
|
|
+ r = v2_rom_mtd_commit_structures(md, infp, UPDATE_ALL, check);
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Unknown ROM version: %d\n", rom_version);
|
|
diff --git a/src/mtd.c b/src/mtd.c
|
|
index bcbb8d3..4dbb878 100644
|
|
--- a/src/mtd.c
|
|
+++ b/src/mtd.c
|
|
@@ -1967,7 +1967,7 @@ int v2_rom_mtd_init(struct mtd_data *md, FILE *fp)
|
|
|
|
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)
|
|
+ loff_t end, size_t size, int ecc, int verify)
|
|
{
|
|
int chip;
|
|
loff_t end_index, search_area_indices[2], o;
|
|
@@ -1977,6 +1977,13 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name,
|
|
unsigned stride_size_in_bytes;
|
|
unsigned search_area_size_in_strides;
|
|
unsigned search_area_size_in_bytes;
|
|
+ char *readbuf = NULL;
|
|
+
|
|
+ if (verify) {
|
|
+ readbuf = malloc(mtd_writesize(md));
|
|
+ if (NULL == readbuf)
|
|
+ return -1;
|
|
+ }
|
|
|
|
//----------------------------------------------------------------------
|
|
// Compute some important facts about geometry.
|
|
@@ -2072,6 +2079,21 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name,
|
|
err ++;
|
|
}
|
|
|
|
+ if (verify) {
|
|
+ //------------------------------------------------------
|
|
+ // Verify the written data
|
|
+ //------------------------------------------------------
|
|
+ r = pread(md->part[chip].fd, readbuf, mtd_writesize(md), o);
|
|
+ if (r != mtd_writesize(md)) {
|
|
+ fprintf(stderr, "mtd: Failed to read @0x%llx (%d)\n", o, r);
|
|
+ return -1;
|
|
+ }
|
|
+ if (memcmp(md->buf, readbuf, mtd_writesize(md))) {
|
|
+ fprintf(stderr, "mtd: Verification error @0x%llx\n", o);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
}
|
|
|
|
}
|
|
@@ -2218,7 +2240,7 @@ int mtd_read_bcb(struct mtd_data *md, char *bcb_name,
|
|
}
|
|
|
|
|
|
-int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
+int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
|
|
{
|
|
int startpage, start, size;
|
|
unsigned int search_area_sz, stride;
|
|
@@ -2317,7 +2339,7 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
if (r < 0)
|
|
return r;
|
|
|
|
- mtd_commit_bcb(md, "NCB", 0, 1, 0, 1, size, false);
|
|
+ mtd_commit_bcb(md, "NCB", 0, 1, 0, 1, size, false, verify);
|
|
}
|
|
|
|
if (flags & UPDATE_LDLB) {
|
|
@@ -2326,7 +2348,7 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
memset(md->buf, 0, mtd_writesize(md));
|
|
memcpy(md->buf, md->curr_ldlb, sizeof(*md->curr_ldlb));
|
|
|
|
- mtd_commit_bcb(md, "LDLB", 2, 3, 1, 1, mtd_writesize(md), true);
|
|
+ mtd_commit_bcb(md, "LDLB", 2, 3, 1, 1, mtd_writesize(md), true, verify);
|
|
}
|
|
|
|
if (flags & UPDATE_DBBT) {
|
|
@@ -2335,7 +2357,7 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
memset(md->buf, 0, mtd_writesize(md));
|
|
memcpy(md->buf, md->curr_dbbt, sizeof(*md->curr_dbbt));
|
|
|
|
- mtd_commit_bcb(md, "DBBT", 4, 5, 2, 1, mtd_writesize(md), true);
|
|
+ mtd_commit_bcb(md, "DBBT", 4, 5, 2, 1, mtd_writesize(md), true, verify);
|
|
for (i = 0; i < 2; i++) {
|
|
for (j = 0; j < 2; j++) {
|
|
if (md->flags & F_MULTICHIP) {
|
|
@@ -2369,14 +2391,20 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
return 0;
|
|
}
|
|
|
|
-int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
+int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
|
|
{
|
|
int startpage, start, size;
|
|
unsigned int search_area_size_in_bytes, stride_size_in_bytes;
|
|
int i, r, chunk;
|
|
loff_t ofs, end;
|
|
int chip = 0;
|
|
+ char *readbuf = NULL;
|
|
|
|
+ if (verify) {
|
|
+ readbuf = malloc(mtd_writesize(md));
|
|
+ if (NULL == readbuf)
|
|
+ return -1;
|
|
+ }
|
|
//----------------------------------------------------------------------
|
|
// Compute some important facts about geometry.
|
|
//----------------------------------------------------------------------
|
|
@@ -2403,7 +2431,7 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
// Write the FCB search area.
|
|
//----------------------------------------------------------------------
|
|
|
|
- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false);
|
|
+ mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false, verify);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Write the DBBT search area.
|
|
@@ -2412,7 +2440,7 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
memset(md->buf, 0, mtd_writesize(md));
|
|
memcpy(md->buf, &(md->dbbt28), sizeof(md->dbbt28));
|
|
|
|
- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
|
|
+ mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, verify);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Loop over the two boot streams.
|
|
@@ -2512,6 +2540,21 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
if (r != mtd_writesize(md)) {
|
|
fprintf(stderr, "mtd: Failed to write BS @0x%llx (%d)\n", ofs, r);
|
|
}
|
|
+
|
|
+ if (verify) {
|
|
+ //------------------------------------------------------
|
|
+ // Verify the written data
|
|
+ //------------------------------------------------------
|
|
+ r = pread(md->part[chip].fd, readbuf, mtd_writesize(md), ofs);
|
|
+ if (r != mtd_writesize(md)) {
|
|
+ fprintf(stderr, "mtd: Failed to read BS @0x%llx (%d)\n", ofs, r);
|
|
+ return -1;
|
|
+ }
|
|
+ if (memcmp(md->buf, readbuf, mtd_writesize(md))) {
|
|
+ fprintf(stderr, "mtd: Verification error @0x%llx\n", ofs);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
ofs += mtd_writesize(md);
|
|
size -= chunk;
|
|
|
|
@@ -2532,7 +2575,7 @@ int v1_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 v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify)
|
|
{
|
|
int startpage, start, size;
|
|
unsigned int search_area_size_in_bytes, stride_size_in_bytes;
|
|
@@ -2569,7 +2612,7 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
memset(md->buf, 0, mtd_writesize(md));
|
|
memcpy(md->buf, &(md->fcb), sizeof(md->fcb));
|
|
|
|
- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, mtd_writesize(md), true);
|
|
+ mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, mtd_writesize(md), true, verify);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Write the DBBT search area.
|
|
@@ -2578,7 +2621,7 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags)
|
|
memset(md->buf, 0, mtd_writesize(md));
|
|
memcpy(md->buf, &(md->dbbt28), sizeof(md->dbbt28));
|
|
|
|
- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true);
|
|
+ mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, verify);
|
|
|
|
//----------------------------------------------------------------------
|
|
// Write the DBBT table area.
|
|
diff --git a/src/mtd.h b/src/mtd.h
|
|
index cff09af..429078f 100644
|
|
--- a/src/mtd.h
|
|
+++ b/src/mtd.h
|
|
@@ -269,9 +269,9 @@ int mtd_markbad(struct mtd_data *md, int chip, loff_t ofs);
|
|
#define UPDATE_BS1 0x10
|
|
#define UPDATE_BS(x) (0x08 << ((x) & 1))
|
|
#define UPDATE_ALL (UPDATE_NCB | UPDATE_LDLB | UPDATE_DBBT | UPDATE_BS0 | UPDATE_BS1)
|
|
-int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags);
|
|
-int v1_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 v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
|
|
+int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
|
|
+int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify);
|
|
int mtd_set_ecc_mode(struct mtd_data *md, int ecc);
|
|
|
|
#ifndef ARRAY_SIZE
|
|
--
|
|
1.7.1
|
|
|