| 1 | From a73c2d9dc7ea0d14fbf48db48e783d123162f5c3 Mon Sep 17 00:00:00 2001 |
| 2 | From: Jonas Gorski <jonas.gorski@gmail.com> |
| 3 | Date: Thu, 19 Apr 2012 13:15:57 +0200 |
| 4 | Subject: [PATCH] mtd: bcm63xxpart: handle Broadcom partition order |
| 5 | |
| 6 | The original Broadcom partition order has the root fs in front of the |
| 7 | kernel, which resulted in miscalculated partition sizes. |
| 8 | Detect when such an image is on the flash and also reorder the partitions |
| 9 | accordingly. |
| 10 | |
| 11 | Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> |
| 12 | Acked-by: Florian Fainelli <florian@openwrt.org> |
| 13 | Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com> |
| 14 | --- |
| 15 | drivers/mtd/bcm63xxpart.c | 41 ++++++++++++++++++++++++++++++----------- |
| 16 | 1 file changed, 30 insertions(+), 11 deletions(-) |
| 17 | |
| 18 | --- a/drivers/mtd/bcm63xxpart.c |
| 19 | +++ b/drivers/mtd/bcm63xxpart.c |
| 20 | @@ -4,7 +4,7 @@ |
| 21 | * Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org> |
| 22 | * Mike Albon <malbon@openwrt.org> |
| 23 | * Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> |
| 24 | - * Copyright © 2011 Jonas Gorski <jonas.gorski@gmail.com> |
| 25 | + * Copyright © 2011-2012 Jonas Gorski <jonas.gorski@gmail.com> |
| 26 | * |
| 27 | * This program is free software; you can redistribute it and/or modify |
| 28 | * it under the terms of the GNU General Public License as published by |
| 29 | @@ -82,6 +82,7 @@ static int bcm63xx_parse_cfe_partitions( |
| 30 | int namelen = 0; |
| 31 | int i; |
| 32 | u32 computed_crc; |
| 33 | + bool rootfs_first = false; |
| 34 | |
| 35 | if (bcm63xx_detect_cfe(master)) |
| 36 | return -EINVAL; |
| 37 | @@ -109,6 +110,7 @@ static int bcm63xx_parse_cfe_partitions( |
| 38 | char *boardid = &(buf->board_id[0]); |
| 39 | char *tagversion = &(buf->tag_version[0]); |
| 40 | |
| 41 | + sscanf(buf->flash_image_start, "%u", &rootfsaddr); |
| 42 | sscanf(buf->kernel_address, "%u", &kerneladdr); |
| 43 | sscanf(buf->kernel_length, "%u", &kernellen); |
| 44 | sscanf(buf->total_length, "%u", &totallen); |
| 45 | @@ -117,10 +119,19 @@ static int bcm63xx_parse_cfe_partitions( |
| 46 | tagversion, boardid); |
| 47 | |
| 48 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; |
| 49 | - rootfsaddr = kerneladdr + kernellen; |
| 50 | + rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; |
| 51 | spareaddr = roundup(totallen, master->erasesize) + cfelen; |
| 52 | sparelen = master->size - spareaddr - nvramlen; |
| 53 | - rootfslen = spareaddr - rootfsaddr; |
| 54 | + |
| 55 | + if (rootfsaddr < kerneladdr) { |
| 56 | + /* default Broadcom layout */ |
| 57 | + rootfslen = kerneladdr - rootfsaddr; |
| 58 | + rootfs_first = true; |
| 59 | + } else { |
| 60 | + /* OpenWrt layout */ |
| 61 | + rootfsaddr = kerneladdr + kernellen; |
| 62 | + rootfslen = spareaddr - rootfsaddr; |
| 63 | + } |
| 64 | } else { |
| 65 | pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", |
| 66 | buf->header_crc, computed_crc); |
| 67 | @@ -156,18 +167,26 @@ static int bcm63xx_parse_cfe_partitions( |
| 68 | curpart++; |
| 69 | |
| 70 | if (kernellen > 0) { |
| 71 | - parts[curpart].name = "kernel"; |
| 72 | - parts[curpart].offset = kerneladdr; |
| 73 | - parts[curpart].size = kernellen; |
| 74 | + int kernelpart = curpart; |
| 75 | + |
| 76 | + if (rootfslen > 0 && rootfs_first) |
| 77 | + kernelpart++; |
| 78 | + parts[kernelpart].name = "kernel"; |
| 79 | + parts[kernelpart].offset = kerneladdr; |
| 80 | + parts[kernelpart].size = kernellen; |
| 81 | curpart++; |
| 82 | } |
| 83 | |
| 84 | if (rootfslen > 0) { |
| 85 | - parts[curpart].name = "rootfs"; |
| 86 | - parts[curpart].offset = rootfsaddr; |
| 87 | - parts[curpart].size = rootfslen; |
| 88 | - if (sparelen > 0) |
| 89 | - parts[curpart].size += sparelen; |
| 90 | + int rootfspart = curpart; |
| 91 | + |
| 92 | + if (kernellen > 0 && rootfs_first) |
| 93 | + rootfspart--; |
| 94 | + parts[rootfspart].name = "rootfs"; |
| 95 | + parts[rootfspart].offset = rootfsaddr; |
| 96 | + parts[rootfspart].size = rootfslen; |
| 97 | + if (sparelen > 0 && !rootfs_first) |
| 98 | + parts[rootfspart].size += sparelen; |
| 99 | curpart++; |
| 100 | } |
| 101 | |
| 102 | |