[lantiq]
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-2.6.39 / 210-mtd_uimage_split.patch
1 --- a/drivers/mtd/Kconfig
2 +++ b/drivers/mtd/Kconfig
3 @@ -63,6 +63,10 @@
4 depends on MTD_PARTITIONS
5 default y
6
7 +config MTD_UIMAGE_SPLIT
8 + bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
9 + default y
10 +
11 config MTD_REDBOOT_PARTS
12 tristate "RedBoot partition table parsing"
13 depends on MTD_PARTITIONS
14 --- a/drivers/mtd/mtdpart.c
15 +++ b/drivers/mtd/mtdpart.c
16 @@ -724,6 +724,82 @@
17 }
18 #endif /* CONFIG_MTD_ROOTFS_SPLIT */
19
20 +
21 +#ifdef CONFIG_MTD_UIMAGE_SPLIT
22 +static unsigned long find_uimage_size(struct mtd_info *mtd,
23 + unsigned long offset)
24 +{
25 +#define UBOOT_MAGIC 0x56190527
26 + unsigned long magic = 0;
27 + unsigned long temp;
28 + size_t len;
29 + int ret;
30 +
31 + ret = mtd->read(mtd, offset, 4, &len, (void *)&magic);
32 + if (ret || len != sizeof(magic))
33 + return 0;
34 +
35 + if (le32_to_cpu(magic) != UBOOT_MAGIC)
36 + return 0;
37 +
38 + ret = mtd->read(mtd, offset + 12, 4, &len, (void *)&temp);
39 + if (ret || len != sizeof(temp))
40 + return 0;
41 +
42 + return temp + 0x40;
43 +}
44 +
45 +static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
46 +{
47 + unsigned long temp;
48 + size_t len;
49 + int ret;
50 +
51 + ret = mtd->read(mtd, offset, 4, &len, (void *)&temp);
52 + if (ret || len != sizeof(temp))
53 + return 0;
54 +
55 + return le32_to_cpu(temp) == SQUASHFS_MAGIC;
56 +}
57 +
58 +static int split_uimage(struct mtd_info *mtd,
59 + const struct mtd_partition *part)
60 +{
61 + static struct mtd_partition split_partitions[] = {
62 + {
63 + .name = "kernel",
64 + .offset = 0x0,
65 + .size = 0x0,
66 + }, {
67 + .name = "rootfs",
68 + .offset = 0x0,
69 + .size = 0x0,
70 + },
71 + };
72 +
73 + split_partitions[0].size = find_uimage_size(mtd, part->offset);
74 + if (!split_partitions[0].size) {
75 + printk(KERN_NOTICE "no uImage found in linux partition\n");
76 + return -1;
77 + }
78 +
79 + if (!detect_squashfs_partition(mtd,
80 + part->offset
81 + + split_partitions[0].size)) {
82 + split_partitions[0].size &= ~(mtd->erasesize - 1);
83 + split_partitions[0].size += mtd->erasesize;
84 + }
85 +
86 + split_partitions[0].offset = part->offset;
87 + split_partitions[1].offset = part->offset + split_partitions[0].size;
88 + split_partitions[1].size = part->size - split_partitions[0].size;
89 +
90 + add_mtd_partitions(mtd, split_partitions, 2);
91 +
92 + return 0;
93 +}
94 +#endif
95 +
96 /*
97 * This function, given a master MTD object and a partition table, creates
98 * and registers slave MTD objects which are bound to the master according to
99 @@ -748,6 +824,17 @@
100 if (!slave)
101 return -ENOMEM;
102
103 +#ifdef CONFIG_MTD_UIMAGE_SPLIT
104 + if (!strcmp(parts[i].name, "linux")) {
105 + ret = split_uimage(master, &parts[i]);
106 +
107 + if (ret) {
108 + printk(KERN_WARNING
109 + "Can't split linux partition\n");
110 + }
111 + }
112 +#endif
113 +
114 if (!strcmp(parts[i].name, "rootfs")) {
115 #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
116 if (ROOT_DEV == 0) {