afs.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*======================================================================
  2.     drivers/mtd/afs.c: ARM Flash Layout/Partitioning
  3.   
  4.     Copyright (C) 2000 ARM Limited
  5.   
  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.
  10.   
  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.
  15.   
  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.   
  20.    This is access code for flashes using ARM's flash partitioning 
  21.    standards.
  22.    $Id: afs.c,v 1.7 2001/11/01 20:04:54 rmk Exp $
  23. ======================================================================*/
  24. #include <linux/module.h>
  25. #include <linux/types.h>
  26. #include <linux/kernel.h>
  27. #include <linux/slab.h>
  28. #include <linux/string.h>
  29. #include <linux/init.h>
  30. #include <linux/mtd/mtd.h>
  31. #include <linux/mtd/map.h>
  32. #include <linux/mtd/partitions.h>
  33. struct footer_struct {
  34. u32 image_info_base; /* Address of first word of ImageFooter  */
  35. u32 image_start; /* Start of area reserved by this footer */
  36. u32 signature; /* 'Magic' number proves it's a footer   */
  37. u32 type; /* Area type: ARM Image, SIB, customer   */
  38. u32 checksum; /* Just this structure                   */
  39. };
  40. struct image_info_struct {
  41. u32 bootFlags; /* Boot flags, compression etc.          */
  42. u32 imageNumber; /* Unique number, selects for boot etc.  */
  43. u32 loadAddress; /* Address program should be loaded to   */
  44. u32 length; /* Actual size of image                  */
  45. u32 address; /* Image is executed from here           */
  46. char name[16]; /* Null terminated                       */
  47. u32 headerBase; /* Flash Address of any stripped header  */
  48. u32 header_length; /* Length of header in memory            */
  49. u32 headerType; /* AIF, RLF, s-record etc.               */
  50. u32 checksum; /* Image checksum (inc. this struct)     */
  51. };
  52. static int
  53. afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
  54. u_int off, u_int mask)
  55. {
  56. struct footer_struct fs;
  57. u_int ptr = off + mtd->erasesize - sizeof(fs);
  58. size_t sz;
  59. int ret;
  60. ret = mtd->read(mtd, ptr, sizeof(fs), &sz, (u_char *) &fs);
  61. if (ret >= 0 && sz != sizeof(fs))
  62. ret = -EINVAL;
  63. if (ret < 0) {
  64. printk(KERN_ERR "AFS: mtd read failed at 0x%x: %dn",
  65. ptr, ret);
  66. return ret;
  67. }
  68. /*
  69.  * Does it contain the magic number?
  70.  */
  71. if (fs.signature != 0xa0ffff9f)
  72. ret = 1;
  73. /*
  74.  * Don't touch the SIB.
  75.  */
  76. if (fs.type == 2)
  77. ret = 1;
  78. *iis_start = fs.image_info_base & mask;
  79. *img_start = fs.image_start & mask;
  80. /*
  81.  * Check the image info base.  This can not
  82.  * be located after the footer structure.
  83.  */
  84. if (*iis_start >= ptr)
  85. ret = 1;
  86. /*
  87.  * Check the start of this image.  The image
  88.  * data can not be located after this block.
  89.  */
  90. if (*img_start > off)
  91. ret = 1;
  92. return ret;
  93. }
  94. static int
  95. afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
  96. {
  97. size_t sz;
  98. int ret;
  99. memset(iis, 0, sizeof(*iis));
  100. ret = mtd->read(mtd, ptr, sizeof(*iis), &sz, (u_char *) iis);
  101. if (ret >= 0 && sz != sizeof(*iis))
  102. ret = -EINVAL;
  103. if (ret < 0)
  104. printk(KERN_ERR "AFS: mtd read failed at 0x%x: %dn",
  105. ptr, ret);
  106. return ret;
  107. }
  108. int parse_afs_partitions(struct mtd_info *mtd, struct mtd_partition **pparts)
  109. {
  110. struct mtd_partition *parts;
  111. u_int mask, off, idx, sz;
  112. int ret = 0;
  113. char *str;
  114. /*
  115.  * This is the address mask; we use this to mask off out of
  116.  * range address bits.
  117.  */
  118. mask = mtd->size - 1;
  119. /*
  120.  * First, calculate the size of the array we need for the
  121.  * partition information.  We include in this the size of
  122.  * the strings.
  123.  */
  124. for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
  125. struct image_info_struct iis;
  126. u_int iis_ptr, img_ptr;
  127. ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
  128. if (ret < 0)
  129. break;
  130. if (ret == 1)
  131. continue;
  132. ret = afs_read_iis(mtd, &iis, iis_ptr);
  133. if (ret < 0)
  134. break;
  135. sz += sizeof(struct mtd_partition);
  136. sz += strlen(iis.name) + 1;
  137. idx += 1;
  138. }
  139. if (!sz)
  140. return ret;
  141. parts = kmalloc(sz, GFP_KERNEL);
  142. if (!parts)
  143. return -ENOMEM;
  144. str = (char *)(parts + idx);
  145. /*
  146.  * Identify the partitions
  147.  */
  148. for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
  149. struct image_info_struct iis;
  150. u_int iis_ptr, img_ptr, size;
  151. /* Read the footer. */
  152. ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
  153. if (ret < 0)
  154. break;
  155. if (ret == 1)
  156. continue;
  157. /* Read the image info block */
  158. ret = afs_read_iis(mtd, &iis, iis_ptr);
  159. if (ret < 0)
  160. break;
  161. strcpy(str, iis.name);
  162. size = mtd->erasesize + off - img_ptr;
  163. /*
  164.  * In order to support JFFS2 partitions on this layout,
  165.  * we must lie to MTD about the real size of JFFS2
  166.  * partitions; this ensures that the AFS flash footer
  167.  * won't be erased by JFFS2.  Please ensure that your
  168.  * JFFS2 partitions are given image numbers between
  169.  * 1000 and 2000 inclusive.
  170.  */
  171. if (iis.imageNumber >= 1000 && iis.imageNumber < 2000)
  172. size -= mtd->erasesize;
  173. parts[idx].name = str;
  174. parts[idx].size = size;
  175. parts[idx].offset = img_ptr;
  176. parts[idx].mask_flags = 0;
  177. printk("  mtd%d: at 0x%08x, %5dKB, %8u, %sn",
  178. idx, img_ptr, parts[idx].size / 1024,
  179. iis.imageNumber, str);
  180. idx += 1;
  181. str = str + strlen(iis.name) + 1;
  182. }
  183. if (!idx) {
  184. kfree(parts);
  185. parts = NULL;
  186. }
  187. *pparts = parts;
  188. return idx ? idx : ret;
  189. }
  190. EXPORT_SYMBOL(parse_afs_partitions);
  191. MODULE_AUTHOR("ARM Ltd");
  192. MODULE_DESCRIPTION("ARM Firmware Suite partition parser");
  193. MODULE_LICENSE("GPL");