4 * Copyright (C) 2007 OpenWrt.org
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * TI AR7 flash partition table.
21 * Based on ar7 map by Felix Fietkau.
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
28 #include <linux/mtd/mtd.h>
29 #include <linux/mtd/partitions.h>
30 #include <linux/bootmem.h>
31 #include <linux/squashfs_fs.h>
32 #include <linux/root_dev.h>
35 unsigned int checksum
;
40 static struct mtd_partition ar7_parts
[5];
42 static int create_mtd_partitions(struct mtd_info
*master
,
43 struct mtd_partition
**pparts
,
47 struct ar7_bin_rec header
;
48 unsigned int offset
, new_offset
, len
;
49 struct squashfs_super_block sb
;
50 unsigned int block_size
= 0x10000, pre_size
= 0x10000,
51 post_size
= 0, root_offset
= 0xe0000;
54 printk("Parsing AR7 partition map...\n");
56 ar7_parts
[0].name
= "loader";
57 ar7_parts
[0].offset
= 0;
58 ar7_parts
[0].size
= block_size
;
59 ar7_parts
[0].mask_flags
= MTD_WRITEABLE
;
61 ar7_parts
[1].name
= "config";
62 ar7_parts
[1].size
= block_size
;
63 ar7_parts
[1].mask_flags
= 0;
65 master
->read(master
, block_size
, 8, &len
, sig
);
66 if (strncmp(sig
, "TIENV0.8", 8)) {
67 ar7_parts
[1].offset
= master
->size
- block_size
;
68 post_size
= block_size
;
70 ar7_parts
[1].offset
= block_size
;
71 pre_size
= block_size
* 2;
74 ar7_parts
[2].name
= "linux";
75 ar7_parts
[2].offset
= pre_size
;
76 ar7_parts
[2].size
= master
->size
- block_size
* 2;
77 ar7_parts
[2].mask_flags
= 0;
80 master
->read(master
, offset
, sizeof(header
), &len
, (u_char
*)&header
);
81 if (header
.checksum
!= 0xfeedfa42) {
82 printk("Unknown magic: %08x\n", header
.checksum
);
84 while (header
.length
) {
85 offset
+= sizeof(header
) + header
.length
;
86 master
->read(master
, offset
, sizeof(header
),
87 &len
, (u_char
*)&header
);
89 root_offset
= offset
+ sizeof(header
) + 4;
92 ar7_parts
[p
].name
= "rootfs";
93 ar7_parts
[p
].offset
= root_offset
;
94 ar7_parts
[p
].size
= master
->size
- root_offset
- post_size
;
95 ar7_parts
[p
++].mask_flags
= 0;
97 master
->read(master
, root_offset
, sizeof(sb
), &len
, (u_char
*)&sb
);
98 if (sb
.s_magic
== SQUASHFS_MAGIC
) {
99 printk("Squashfs detected (size %Ld)\n", sb
.bytes_used
);
100 new_offset
= root_offset
+ sb
.bytes_used
;
102 if ((new_offset
% master
->erasesize
) > 0)
103 new_offset
+= master
->erasesize
-
104 (new_offset
% master
->erasesize
);
106 ar7_parts
[p
].name
= "rootfs_data";
107 ar7_parts
[p
].offset
= new_offset
;
108 ar7_parts
[p
].size
= master
->size
- new_offset
- post_size
;
109 ar7_parts
[p
- 1].size
-= ar7_parts
[p
].size
;
110 ar7_parts
[p
- 1].mask_flags
|= MTD_WRITEABLE
;
111 ar7_parts
[p
++].mask_flags
= 0;
112 ROOT_DEV
= MKDEV(MTD_BLOCK_MAJOR
, p
- 1);
114 printk("Squashfs not found. Moving rootfs partition to next erase block\n");
115 if ((root_offset
% master
->erasesize
) > 0)
116 root_offset
+= master
->erasesize
-
117 (root_offset
% master
->erasesize
);
119 ar7_parts
[p
].offset
= root_offset
;
120 ar7_parts
[p
].size
= master
->size
- root_offset
- post_size
;
121 ROOT_DEV
= MKDEV(MTD_BLOCK_MAJOR
, p
);
127 static struct mtd_part_parser ar7_parser
= {
128 .owner
= THIS_MODULE
,
129 .parse_fn
= create_mtd_partitions
,
133 static int __init
ar7_parser_init(void)
135 return register_mtd_parser(&ar7_parser
);
138 module_init(ar7_parser_init
);
140 MODULE_LICENSE("GPL");
141 MODULE_AUTHOR("Felix Fietkau, Eugene Konev");
142 MODULE_DESCRIPTION("MTD partitioning for TI AR7");