0208-owrt-mtd-split.patch 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. From 2a295753a10823a47542c779a25bbb1f52c71281 Mon Sep 17 00:00:00 2001
  2. From: John Crispin <[email protected]>
  3. Date: Fri, 3 Aug 2012 10:27:13 +0200
  4. Subject: [PATCH 19/25] owrt mtd split
  5. ---
  6. .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 1 +
  7. arch/mips/lantiq/setup.c | 7 +
  8. drivers/mtd/Kconfig | 4 +
  9. drivers/mtd/mtdpart.c | 173 +++++++++++++++++++-
  10. 4 files changed, 184 insertions(+), 1 deletions(-)
  11. Index: linux-3.9-rc4/drivers/mtd/Kconfig
  12. ===================================================================
  13. --- linux-3.9-rc4.orig/drivers/mtd/Kconfig 2013-03-27 09:26:32.005789709 +0100
  14. +++ linux-3.9-rc4/drivers/mtd/Kconfig 2013-03-27 09:26:35.669789796 +0100
  15. @@ -31,6 +31,10 @@
  16. bool "Automatically split 'rootfs' partition for squashfs"
  17. default y
  18. +config MTD_UIMAGE_SPLIT
  19. + bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
  20. + default y
  21. +
  22. config MTD_REDBOOT_PARTS
  23. tristate "RedBoot partition table parsing"
  24. ---help---
  25. Index: linux-3.9-rc4/drivers/mtd/mtdpart.c
  26. ===================================================================
  27. --- linux-3.9-rc4.orig/drivers/mtd/mtdpart.c 2013-03-27 09:26:32.281789715 +0100
  28. +++ linux-3.9-rc4/drivers/mtd/mtdpart.c 2013-03-27 17:20:12.874466937 +0100
  29. @@ -844,6 +844,99 @@
  30. }
  31. #endif /* CONFIG_MTD_ROOTFS_SPLIT */
  32. +#ifdef CONFIG_MTD_UIMAGE_SPLIT
  33. +static unsigned long find_uimage_size(struct mtd_info *mtd,
  34. + unsigned long offset)
  35. +{
  36. +#define UBOOT_MAGIC 0x56190527
  37. + unsigned long magic = 0;
  38. + unsigned long temp;
  39. + size_t len;
  40. + int ret;
  41. +
  42. + ret = mtd_read(mtd, offset, 4, &len, (void *)&magic);
  43. + if (ret || len != sizeof(magic))
  44. + return 0;
  45. +
  46. + if (le32_to_cpu(magic) != UBOOT_MAGIC)
  47. + return 0;
  48. +
  49. + ret = mtd_read(mtd, offset + 12, 4, &len, (void *)&temp);
  50. + if (ret || len != sizeof(temp))
  51. + return 0;
  52. +
  53. + return be32_to_cpu(temp) + 0x40;
  54. +}
  55. +
  56. +static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
  57. +{
  58. + unsigned long temp;
  59. + size_t len;
  60. + int ret;
  61. +
  62. + ret = mtd_read(mtd, offset, 4, &len, (void *)&temp);
  63. + if (ret || len != sizeof(temp))
  64. + return 0;
  65. +
  66. + return le32_to_cpu(temp) == SQUASHFS_MAGIC;
  67. +}
  68. +
  69. +static unsigned long find_squashfs_offset(struct mtd_info *mtd, unsigned long _offset)
  70. +{
  71. + /* scan the first 2MB at 64K offsets */
  72. + int i;
  73. +
  74. + for (i = 0; i < 32; i++) {
  75. + unsigned long offset = i * 64 * 1024;
  76. + if (detect_squashfs_partition(mtd, _offset + offset))
  77. + return offset;
  78. + }
  79. + return 0;
  80. +}
  81. +
  82. +static int split_uimage(struct mtd_info *mtd,
  83. + const struct mtd_partition *part)
  84. +{
  85. + static struct mtd_partition split_partitions[] = {
  86. + {
  87. + .name = "kernel",
  88. + .offset = 0x0,
  89. + .size = 0x0,
  90. + }, {
  91. + .name = "rootfs",
  92. + .offset = 0x0,
  93. + .size = 0x0,
  94. + },
  95. + };
  96. +
  97. + split_partitions[0].size = find_uimage_size(mtd, part->offset);
  98. + if (!split_partitions[0].size) {
  99. + split_partitions[0].size = find_squashfs_offset(mtd, part->offset);
  100. + if (!split_partitions[0].size) {
  101. + pr_err("failed to split firmware partition\n");
  102. + return -1;
  103. + }
  104. + }
  105. +
  106. + if (!detect_squashfs_partition(mtd,
  107. + part->offset
  108. + + split_partitions[0].size)) {
  109. + split_partitions[0].size &= ~(mtd->erasesize - 1);
  110. + split_partitions[0].size += mtd->erasesize;
  111. + } else {
  112. + pr_info("found squashfs behind kernel\n");
  113. + }
  114. +
  115. + split_partitions[0].offset = part->offset;
  116. + split_partitions[1].offset = part->offset + split_partitions[0].size;
  117. + split_partitions[1].size = part->size - split_partitions[0].size;
  118. +
  119. + add_mtd_partitions(mtd, split_partitions, 2);
  120. +
  121. + return 0;
  122. +}
  123. +#endif
  124. +
  125. /*
  126. * This function, given a master MTD object and a partition table, creates
  127. * and registers slave MTD objects which are bound to the master according to
  128. @@ -860,7 +953,7 @@
  129. struct mtd_part *slave;
  130. uint64_t cur_offset = 0;
  131. int i;
  132. -#ifdef CONFIG_MTD_ROOTFS_SPLIT
  133. +#if defined(CONFIG_MTD_ROOTFS_SPLIT) || defined(CONFIG_MTD_UIMAGE_SPLIT)
  134. int ret;
  135. #endif
  136. @@ -877,6 +970,14 @@
  137. add_mtd_device(&slave->mtd);
  138. +#ifdef CONFIG_MTD_UIMAGE_SPLIT
  139. + if (!strcmp(parts[i].name, "firmware")) {
  140. + ret = split_uimage(master, &parts[i]);
  141. + if (ret)
  142. + printk(KERN_WARNING "Can't split firmware partition\n");
  143. + }
  144. +#endif
  145. +
  146. if (!strcmp(parts[i].name, "rootfs")) {
  147. #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
  148. if (ROOT_DEV == 0) {