Blame view
drivers/mtd/ar7part.c
4.1 KB
f0797881d [MTD] AR7 mtd par... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* * Copyright © 2007 Eugene Konev <ejka@openwrt.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * TI AR7 flash partition table. * Based on ar7 map by Felix Fietkau <nbd@openwrt.org> * */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/bootmem.h> #include <linux/magic.h> |
a0e5cc581 mtd: Add module.h... |
30 |
#include <linux/module.h> |
f0797881d [MTD] AR7 mtd par... |
31 32 33 34 35 36 |
#define AR7_PARTS 4 #define ROOT_OFFSET 0xe0000 #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) |
986ee0139 [MTD] Clean up AR... |
37 38 39 |
#ifndef SQUASHFS_MAGIC #define SQUASHFS_MAGIC 0x73717368 #endif |
f0797881d [MTD] AR7 mtd par... |
40 41 42 43 44 |
struct ar7_bin_rec { unsigned int checksum; unsigned int length; unsigned int address; }; |
f0797881d [MTD] AR7 mtd par... |
45 46 |
static int create_mtd_partitions(struct mtd_info *master, struct mtd_partition **pparts, |
c79753301 mtd: abstract las... |
47 |
struct mtd_part_parser_data *data) |
f0797881d [MTD] AR7 mtd par... |
48 49 |
{ struct ar7_bin_rec header; |
986ee0139 [MTD] Clean up AR... |
50 51 |
unsigned int offset; size_t len; |
f0797881d [MTD] AR7 mtd par... |
52 53 54 55 |
unsigned int pre_size = master->erasesize, post_size = 0; unsigned int root_offset = ROOT_OFFSET; int retries = 10; |
17b536cc4 [MTD] mtdpart: Ma... |
56 |
struct mtd_partition *ar7_parts; |
f0797881d [MTD] AR7 mtd par... |
57 |
|
17b536cc4 [MTD] mtdpart: Ma... |
58 59 60 |
ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL); if (!ar7_parts) return -ENOMEM; |
f0797881d [MTD] AR7 mtd par... |
61 62 63 64 65 66 67 68 69 70 71 72 |
ar7_parts[0].name = "loader"; ar7_parts[0].offset = 0; ar7_parts[0].size = master->erasesize; ar7_parts[0].mask_flags = MTD_WRITEABLE; ar7_parts[1].name = "config"; ar7_parts[1].offset = 0; ar7_parts[1].size = master->erasesize; ar7_parts[1].mask_flags = 0; do { /* Try 10 blocks starting from master->erasesize */ offset = pre_size; |
329ad399a mtd: introduce mt... |
73 74 |
mtd_read(master, offset, sizeof(header), &len, (uint8_t *)&header); |
f0797881d [MTD] AR7 mtd par... |
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
if (!strncmp((char *)&header, "TIENV0.8", 8)) ar7_parts[1].offset = pre_size; if (header.checksum == LOADER_MAGIC1) break; if (header.checksum == LOADER_MAGIC2) break; pre_size += master->erasesize; } while (retries--); pre_size = offset; if (!ar7_parts[1].offset) { ar7_parts[1].offset = master->size - master->erasesize; post_size = master->erasesize; } switch (header.checksum) { case LOADER_MAGIC1: while (header.length) { offset += sizeof(header) + header.length; |
329ad399a mtd: introduce mt... |
95 96 |
mtd_read(master, offset, sizeof(header), &len, (uint8_t *)&header); |
f0797881d [MTD] AR7 mtd par... |
97 98 99 100 101 102 |
} root_offset = offset + sizeof(header) + 4; break; case LOADER_MAGIC2: while (header.length) { offset += sizeof(header) + header.length; |
329ad399a mtd: introduce mt... |
103 104 |
mtd_read(master, offset, sizeof(header), &len, (uint8_t *)&header); |
f0797881d [MTD] AR7 mtd par... |
105 106 |
} root_offset = offset + sizeof(header) + 4 + 0xff; |
986ee0139 [MTD] Clean up AR... |
107 |
root_offset &= ~(uint32_t)0xff; |
f0797881d [MTD] AR7 mtd par... |
108 109 110 111 112 113 |
break; default: printk(KERN_WARNING "Unknown magic: %08x ", header.checksum); break; } |
329ad399a mtd: introduce mt... |
114 |
mtd_read(master, root_offset, sizeof(header), &len, (u8 *)&header); |
f0797881d [MTD] AR7 mtd par... |
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
if (header.checksum != SQUASHFS_MAGIC) { root_offset += master->erasesize - 1; root_offset &= ~(master->erasesize - 1); } ar7_parts[2].name = "linux"; ar7_parts[2].offset = pre_size; ar7_parts[2].size = master->size - pre_size - post_size; ar7_parts[2].mask_flags = 0; ar7_parts[3].name = "rootfs"; ar7_parts[3].offset = root_offset; ar7_parts[3].size = master->size - root_offset - post_size; ar7_parts[3].mask_flags = 0; *pparts = ar7_parts; return AR7_PARTS; } static struct mtd_part_parser ar7_parser = { .owner = THIS_MODULE, .parse_fn = create_mtd_partitions, .name = "ar7part", }; static int __init ar7_parser_init(void) { return register_mtd_parser(&ar7_parser); } module_init(ar7_parser_init); MODULE_LICENSE("GPL"); MODULE_AUTHOR( "Felix Fietkau <nbd@openwrt.org>, " "Eugene Konev <ejka@openwrt.org>"); MODULE_DESCRIPTION("MTD partitioning for TI AR7"); |