diff options
author | Jonas Gorski <jonas.gorski@gmail.com> | 2011-12-17 07:58:18 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-01-09 13:23:32 -0500 |
commit | f98872fc14ecb96f796443911b6bc4767e58e885 (patch) | |
tree | fac2482d883da626b8c0e1293b524ea90bbf796e /drivers | |
parent | 805166783893651e3352ee9e68ad5d0b68a769f1 (diff) |
mtd: bcm63xxpart: check the image tag's crc32
Only use the values from the image tag if it is valid. Always create
the CFE, NVRAM and linux partitions, to allow flashing a new image even
if the old is invalid without overwriting CFE or NVRAM.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/bcm63xxpart.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 6afc4aa3c622..9ee8bc426e93 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
26 | 26 | ||
27 | #include <linux/crc32.h> | ||
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
@@ -80,8 +81,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
80 | unsigned int cfelen, nvramlen; | 81 | unsigned int cfelen, nvramlen; |
81 | int namelen = 0; | 82 | int namelen = 0; |
82 | int i; | 83 | int i; |
83 | char *boardid; | 84 | u32 computed_crc; |
84 | char *tagversion; | ||
85 | 85 | ||
86 | if (bcm63xx_detect_cfe(master)) | 86 | if (bcm63xx_detect_cfe(master)) |
87 | return -EINVAL; | 87 | return -EINVAL; |
@@ -103,20 +103,33 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
103 | return -EIO; | 103 | return -EIO; |
104 | } | 104 | } |
105 | 105 | ||
106 | sscanf(buf->kernel_address, "%u", &kerneladdr); | 106 | computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, |
107 | sscanf(buf->kernel_length, "%u", &kernellen); | 107 | offsetof(struct bcm_tag, header_crc)); |
108 | sscanf(buf->total_length, "%u", &totallen); | 108 | if (computed_crc == buf->header_crc) { |
109 | tagversion = &(buf->tag_version[0]); | 109 | char *boardid = &(buf->board_id[0]); |
110 | boardid = &(buf->board_id[0]); | 110 | char *tagversion = &(buf->tag_version[0]); |
111 | 111 | ||
112 | pr_info("CFE boot tag found with version %s and board type %s\n", | 112 | sscanf(buf->kernel_address, "%u", &kerneladdr); |
113 | tagversion, boardid); | 113 | sscanf(buf->kernel_length, "%u", &kernellen); |
114 | 114 | sscanf(buf->total_length, "%u", &totallen); | |
115 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; | 115 | |
116 | rootfsaddr = kerneladdr + kernellen; | 116 | pr_info("CFE boot tag found with version %s and board type %s\n", |
117 | spareaddr = roundup(totallen, master->erasesize) + cfelen; | 117 | tagversion, boardid); |
118 | sparelen = master->size - spareaddr - nvramlen; | 118 | |
119 | rootfslen = spareaddr - rootfsaddr; | 119 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; |
120 | rootfsaddr = kerneladdr + kernellen; | ||
121 | spareaddr = roundup(totallen, master->erasesize) + cfelen; | ||
122 | sparelen = master->size - spareaddr - nvramlen; | ||
123 | rootfslen = spareaddr - rootfsaddr; | ||
124 | } else { | ||
125 | pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", | ||
126 | buf->header_crc, computed_crc); | ||
127 | kernellen = 0; | ||
128 | rootfslen = 0; | ||
129 | rootfsaddr = 0; | ||
130 | spareaddr = cfelen; | ||
131 | sparelen = master->size - cfelen - nvramlen; | ||
132 | } | ||
120 | 133 | ||
121 | /* Determine number of partitions */ | 134 | /* Determine number of partitions */ |
122 | namelen = 8; | 135 | namelen = 8; |