diff options
Diffstat (limited to 'target/linux/generic/patches-3.10/400-mtd-add-rootfs-split-support.patch')
-rw-r--r-- | target/linux/generic/patches-3.10/400-mtd-add-rootfs-split-support.patch | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/target/linux/generic/patches-3.10/400-mtd-add-rootfs-split-support.patch b/target/linux/generic/patches-3.10/400-mtd-add-rootfs-split-support.patch deleted file mode 100644 index e14e7c0..0000000 --- a/target/linux/generic/patches-3.10/400-mtd-add-rootfs-split-support.patch +++ /dev/null @@ -1,289 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -12,6 +12,32 @@ menuconfig MTD - - if MTD - -+menu "OpenWrt specific MTD options" -+ -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ default y -+ -+config MTD_ROOTFS_SPLIT -+ bool "Automatically split 'rootfs' partition for squashfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE -+ bool "Automatically split firmware partition for kernel+rootfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE_NAME -+ string "Firmware partition name" -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -+config MTD_UIMAGE_SPLIT -+ bool "Enable split support for firmware partitions containing a uImage" -+ depends on MTD_SPLIT_FIRMWARE -+ default y -+ -+endmenu -+ - config MTD_TESTS - tristate "MTD tests support (DANGEROUS)" - depends on m ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -29,9 +29,11 @@ - #include <linux/kmod.h> - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> -+#include <linux/magic.h> - #include <linux/err.h> - - #include "mtdcore.h" -+#include "mtdsplit/mtdsplit.h" - - /* Our partition linked list */ - static LIST_HEAD(mtd_partitions); -@@ -45,13 +47,14 @@ struct mtd_part { - struct list_head list; - }; - -+static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); -+ - /* - * Given a pointer to the MTD object in the mtd_part structure, we can retrieve - * the pointer to that structure with this macro. - */ - #define PART(x) ((struct mtd_part *)(x)) - -- - /* - * MTD methods which simply translate the effective address and pass through - * to the _real_ device. -@@ -533,8 +536,10 @@ out_register: - return slave; - } - --int mtd_add_partition(struct mtd_info *master, char *name, -- long long offset, long long length) -+ -+static int -+__mtd_add_partition(struct mtd_info *master, char *name, -+ long long offset, long long length, bool dup_check) - { - struct mtd_partition part; - struct mtd_part *p, *new; -@@ -566,21 +571,24 @@ int mtd_add_partition(struct mtd_info *m - end = offset + length; - - mutex_lock(&mtd_partitions_mutex); -- list_for_each_entry(p, &mtd_partitions, list) -- if (p->master == master) { -- if ((start >= p->offset) && -- (start < (p->offset + p->mtd.size))) -- goto err_inv; -- -- if ((end >= p->offset) && -- (end < (p->offset + p->mtd.size))) -- goto err_inv; -- } -+ if (dup_check) { -+ list_for_each_entry(p, &mtd_partitions, list) -+ if (p->master == master) { -+ if ((start >= p->offset) && -+ (start < (p->offset + p->mtd.size))) -+ goto err_inv; -+ -+ if ((end >= p->offset) && -+ (end < (p->offset + p->mtd.size))) -+ goto err_inv; -+ } -+ } - - list_add(&new->list, &mtd_partitions); - mutex_unlock(&mtd_partitions_mutex); - - add_mtd_device(&new->mtd); -+ mtd_partition_split(master, new); - - return ret; - err_inv: -@@ -590,6 +598,12 @@ err_inv: - } - EXPORT_SYMBOL_GPL(mtd_add_partition); - -+int mtd_add_partition(struct mtd_info *master, char *name, -+ long long offset, long long length) -+{ -+ return __mtd_add_partition(master, name, offset, length, true); -+} -+ - int mtd_del_partition(struct mtd_info *master, int partno) - { - struct mtd_part *slave, *next; -@@ -613,6 +627,144 @@ int mtd_del_partition(struct mtd_info *m - } - EXPORT_SYMBOL_GPL(mtd_del_partition); - -+static inline unsigned long -+mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len) -+{ -+ unsigned long mask = mtd->erasesize - 1; -+ -+ len += offset & mask; -+ len = (len + mask) & ~mask; -+ len -= offset & mask; -+ return len; -+} -+ -+#define ROOTFS_SPLIT_NAME "rootfs_data" -+ -+struct squashfs_super_block { -+ __le32 s_magic; -+ __le32 pad0[9]; -+ __le64 bytes_used; -+}; -+ -+ -+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) -+{ -+ struct squashfs_super_block sb; -+ int len, ret; -+ -+ ret = mtd_read(master, offset, sizeof(sb), &len, (void *) &sb); -+ if (ret || (len != sizeof(sb))) { -+ printk(KERN_ALERT "split_squashfs: error occured while reading " -+ "from \"%s\"\n", master->name); -+ return -EINVAL; -+ } -+ -+ if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) { -+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n", -+ master->name); -+ *split_offset = 0; -+ return 0; -+ } -+ -+ if (le64_to_cpu((sb.bytes_used)) <= 0) { -+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n", -+ master->name); -+ *split_offset = 0; -+ return 0; -+ } -+ -+ len = (u32) le64_to_cpu(sb.bytes_used); -+ len = mtd_pad_erasesize(master, offset, len); -+ *split_offset = offset + len; -+ -+ return 0; -+} -+ -+static void split_rootfs_data(struct mtd_info *master, struct mtd_part *part) -+{ -+ unsigned int split_offset = 0; -+ unsigned int split_size; -+ int ret; -+ -+ ret = split_squashfs(master, part->offset, &split_offset); -+ if (ret) -+ return; -+ -+ if (split_offset <= 0) -+ return; -+ -+ split_size = part->mtd.size - (split_offset - part->offset); -+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=0x%x, len=0x%x\n", -+ ROOTFS_SPLIT_NAME, split_offset, split_size); -+ -+ __mtd_add_partition(master, ROOTFS_SPLIT_NAME, split_offset, -+ split_size, false); -+} -+ -+#define UBOOT_MAGIC 0x27051956 -+ -+static void split_uimage(struct mtd_info *master, struct mtd_part *part) -+{ -+ struct { -+ __be32 magic; -+ __be32 pad[2]; -+ __be32 size; -+ } hdr; -+ size_t len; -+ -+ if (mtd_read(master, part->offset, sizeof(hdr), &len, (void *) &hdr)) -+ return; -+ -+ if (len != sizeof(hdr) || hdr.magic != cpu_to_be32(UBOOT_MAGIC)) -+ return; -+ -+ len = be32_to_cpu(hdr.size) + 0x40; -+ len = mtd_pad_erasesize(master, part->offset, len); -+ if (len + master->erasesize > part->mtd.size) -+ return; -+ -+ __mtd_add_partition(master, "rootfs", part->offset + len, -+ part->mtd.size - len, false); -+} -+ -+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#else -+#define SPLIT_FIRMWARE_NAME "unused" -+#endif -+ -+static void split_firmware(struct mtd_info *master, struct mtd_part *part) -+{ -+ if (config_enabled(CONFIG_MTD_UIMAGE_SPLIT)) -+ split_uimage(master, part); -+} -+ -+void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, -+ int offset, int size) -+{ -+} -+ -+static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) -+{ -+ static int rootfs_found = 0; -+ -+ if (rootfs_found) -+ return; -+ -+ if (!strcmp(part->mtd.name, "rootfs")) { -+ rootfs_found = 1; -+ -+ if (config_enabled(CONFIG_MTD_ROOTFS_SPLIT)) -+ split_rootfs_data(master, part); -+ } -+ -+ if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && -+ config_enabled(CONFIG_MTD_SPLIT_FIRMWARE)) -+ split_firmware(master, part); -+ -+ arch_split_mtd_part(master, part->mtd.name, part->offset, -+ part->mtd.size); -+} - /* - * This function, given a master MTD object and a partition table, creates - * and registers slave MTD objects which are bound to the master according to -@@ -642,6 +794,7 @@ int add_mtd_partitions(struct mtd_info * - mutex_unlock(&mtd_partitions_mutex); - - add_mtd_device(&slave->mtd); -+ mtd_partition_split(master, slave); - - cur_offset = slave->offset + slave->mtd.size; - } ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -84,5 +84,7 @@ int mtd_add_partition(struct mtd_info *m - long long offset, long long length); - int mtd_del_partition(struct mtd_info *master, int partno); - uint64_t mtd_get_device_size(const struct mtd_info *mtd); -+extern void __weak arch_split_mtd_part(struct mtd_info *master, -+ const char *name, int offset, int size); - - #endif |