source: src/router/rc/mtd.c @ 9529

Last change on this file since 9529 was 9529, checked in by BrainSlayer, 5 years ago

take out unused code

File size: 11.1 KB
Line 
1
2#include <limits.h>
3#include <unistd.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <stdint.h>
7#include <fcntl.h>
8#include <errno.h>
9#include <error.h>
10#include <time.h>
11#include <sys/ioctl.h>
12#include <sys/types.h>
13#include <sys/param.h>
14#include <sys/mount.h>
15#include <sys/stat.h>
16#include <sys/reboot.h>
17#include <sys/sysinfo.h>
18
19#include <string.h>
20#include <linux/version.h>
21
22#if KERNEL_VERSION(2,6,0) <= LINUX_VERSION_CODE
23#define IS_KERNEL26 1
24#else
25#define IS_KERNEL26 0
26#endif
27
28#if IS_KERNEL26
29#include <linux/mtd/mtd-abi.h>
30#else
31#include <linux/mtd/mtd.h>
32#endif
33
34
35#include <trxhdr.h>
36#include <crc.h>
37#include <bcmutils.h>
38#include <bcmnvram.h>
39#include <shutils.h>
40
41#include <cy_conf.h>
42#include <utils.h>
43
44#include <endian.h>
45#include <byteswap.h>
46
47#if __BYTE_ORDER == __BIG_ENDIAN
48#define STORE32_LE(X)           bswap_32(X)
49#elif __BYTE_ORDER == __LITTLE_ENDIAN
50#define STORE32_LE(X)           (X)
51#else
52#error unkown endianness!
53#endif
54
55/*
56 * Open an MTD device
57 * @param       mtd     path to or partition name of MTD device
58 * @param       flags   open() flags
59 * @return      return value of open()
60 */
61int
62mtd_open (const char *mtd, int flags)
63{
64  FILE *fp;
65  char dev[PATH_MAX];
66  int i;
67
68  if ((fp = fopen ("/proc/mtd", "r")))
69    {
70      while (fgets (dev, sizeof (dev), fp))
71        {
72          if (sscanf (dev, "mtd%d:", &i) && strstr (dev, mtd))
73            {
74              snprintf (dev, sizeof (dev), "/dev/mtd/%d", i);
75              fclose (fp);
76              return open (dev, flags);
77            }
78        }
79      fclose (fp);
80    }
81
82  return open (mtd, flags);
83}
84
85/*
86 * Erase an MTD device
87 * @param       mtd     path to or partition name of MTD device
88 * @return      0 on success and errno on failure
89 */
90int
91mtd_erase (const char *mtd)
92{
93  int mtd_fd;
94  struct mtd_info_user mtd_info;
95  struct erase_info_user erase_info;
96  /*char *et0;
97     char *et1;
98
99     et0=nvram_safe_get("et0macaddr");
100     et1=nvram_safe_get("et1macaddr");
101     et0=strdup(et0);
102     et1=strdup(et1); */
103  /* Open MTD device */
104  if ((mtd_fd = mtd_open (mtd, O_RDWR)) < 0)
105    {
106      perror (mtd);
107      return errno;
108    }
109
110  /* Get sector size */
111  if (ioctl (mtd_fd, MEMGETINFO, &mtd_info) != 0)
112    {
113      perror (mtd);
114      close (mtd_fd);
115      return errno;
116    }
117
118  erase_info.length = mtd_info.erasesize;
119
120  for (erase_info.start = 0;
121       erase_info.start < mtd_info.size;
122       erase_info.start += mtd_info.erasesize)
123    {
124      fprintf (stderr, "erase[%d]\r", erase_info.start);
125      (void) ioctl (mtd_fd, MEMUNLOCK, &erase_info);
126      if (ioctl (mtd_fd, MEMERASE, &erase_info) != 0)
127        {
128          perror (mtd);
129          close (mtd_fd);
130          return errno;
131        }
132    }
133
134  close (mtd_fd);
135  fprintf (stderr, "erase[%d]\n", erase_info.start);
136  /*nvram_set("et0macaddr",et0);
137     nvram_set("et1macaddr",et1);
138     nvram_commit();
139     free(et0);
140     free(et1); */
141
142  return 0;
143}
144
145extern int http_get (const char *server, char *buf, size_t count,
146                     off_t offset);
147
148/*
149 * Write a file to an MTD device
150 * @param       path    file to write or a URL
151 * @param       mtd     path to or partition name of MTD device
152 * @return      0 on success and errno on failure
153 */
154
155struct img_info {
156        uint32_t lenght;
157        uint32_t CRC;
158        };
159
160#define SQUASHFS_MAGIC                  0x74717368
161
162int
163mtd_write (const char *path, const char *mtd)
164{
165  int mtd_fd = -1;
166  struct mtd_info_user mtd_info;
167  struct erase_info_user erase_info;
168
169  struct sysinfo info;
170  struct trx_header trx;
171  unsigned long crc;
172  int squashfound=0;
173  unsigned int crc_data=0;
174  unsigned int data_len=0;
175  FILE *fp;
176  char *buf = NULL;
177  long count, len, off;
178  long sum = 0;                 // for debug
179  int ret = -1;
180  int i;
181
182  /* Examine TRX header */
183  if ((fp = fopen (path, "r")))
184    count = safe_fread (&trx, 1, sizeof (struct trx_header), fp);
185  else
186   return -1;
187//    count = http_get (path, (char *) &trx, sizeof (struct trx_header), 0);
188  if (count < sizeof (struct trx_header))
189    {
190      fprintf (stderr, "%s: File is too small (%ld bytes)\n", path, count);
191      goto fail;
192    }
193  sysinfo (&info);
194#ifdef HAVE_MAGICBOX
195  trx.magic = STORE32_LE (trx.magic);
196  trx.len = STORE32_LE (trx.len);
197  trx.crc32 = STORE32_LE (trx.crc32);
198#elif HAVE_FONERA
199  trx.magic = STORE32_LE (trx.magic);
200  trx.len = STORE32_LE (trx.len);
201  trx.crc32 = STORE32_LE (trx.crc32);
202//  info.freeram = 64;          //fix, must be flashed in erase blocks
203#elif HAVE_MERAKI
204  trx.magic = STORE32_LE (trx.magic);
205  trx.len = STORE32_LE (trx.len);
206  trx.crc32 = STORE32_LE (trx.crc32);
207//  info.freeram = 64;          //fix, must be flashed in erase blocks
208#elif HAVE_LS2
209  trx.magic = STORE32_LE (trx.magic);
210  trx.len = STORE32_LE (trx.len);
211  trx.crc32 = STORE32_LE (trx.crc32);
212//  info.freeram = 64;          //fix, must be flashed in erase blocks
213#elif HAVE_LS5
214  trx.magic = STORE32_LE (trx.magic);
215  trx.len = STORE32_LE (trx.len);
216  trx.crc32 = STORE32_LE (trx.crc32);
217#elif HAVE_WHRAG108
218  trx.magic = STORE32_LE (trx.magic);
219  trx.len = STORE32_LE (trx.len);
220  trx.crc32 = STORE32_LE (trx.crc32);
221#elif HAVE_PB42
222  trx.magic = STORE32_LE (trx.magic);
223  trx.len = STORE32_LE (trx.len);
224  trx.crc32 = STORE32_LE (trx.crc32);
225//  info.freeram = 64;          //fix, must be flashed in erase blocks
226#elif HAVE_LSX
227  trx.magic = STORE32_LE (trx.magic);
228  trx.len = STORE32_LE (trx.len);
229  trx.crc32 = STORE32_LE (trx.crc32);
230//  info.freeram = 64;          //fix, must be flashed in erase blocks
231#elif HAVE_TW6600
232  trx.magic = STORE32_LE (trx.magic);
233  trx.len = STORE32_LE (trx.len);
234  trx.crc32 = STORE32_LE (trx.crc32);
235#elif HAVE_CA8
236  trx.magic = STORE32_LE (trx.magic);
237  trx.len = STORE32_LE (trx.len);
238  trx.crc32 = STORE32_LE (trx.crc32);
239#elif HAVE_XSCALE
240  trx.magic = STORE32_LE (trx.magic);
241  trx.len = STORE32_LE (trx.len);
242  trx.crc32 = STORE32_LE (trx.crc32);
243#endif
244
245
246  if (trx.magic != TRX_MAGIC || trx.len < sizeof (struct trx_header))
247    {
248      fprintf (stderr, "%s: Bad trx header\n", path);
249      goto fail;
250    }
251  /* Open MTD device and get sector size */
252  if ((mtd_fd = mtd_open (mtd, O_RDWR)) < 0 ||
253      ioctl (mtd_fd, MEMGETINFO, &mtd_info) != 0 ||
254      mtd_info.erasesize < sizeof (struct trx_header))
255    {
256      perror (mtd);
257      goto fail;
258    }
259  if (STORE32_LE (trx.flag_version) & TRX_NO_HEADER)
260    trx.len -= sizeof (struct trx_header);
261
262//#ifndef HAVE_WRK54G
263  if (mtd_info.size < trx.len)
264    {
265      fprintf (stderr, "Image too big for partition: %s\n", mtd);
266      close (mtd_fd);
267      return 0;
268    }
269//#endif
270
271
272  /* See if we have enough memory to store the whole file */
273  fprintf (stderr, "freeram=[%ld] bufferram=[%ld]\n", info.freeram,
274           info.bufferram);
275  int mul = 1; //temporarily use 1 instead of 4 until we found a a solution
276  if ((info.freeram + info.bufferram) >= (trx.len + 1 * 1024 * 1024))
277    {
278      fprintf (stderr, "The free memory is enough, writing image once.\n");
279      /* Begin to write image after all image be downloaded by web upgrade.
280       * In order to avoid upgrade fail if user unplug the ethernet cable during upgrading */
281      //if(check_action() == ACT_WEBS_UPGRADE || check_action() == ACT_WEB_UPGRADE)
282      erase_info.length = ROUNDUP (trx.len, mtd_info.erasesize);
283      //else
284      //      erase_info.length = mtd_info.erasesize;
285    }
286  else
287    {
288      erase_info.length = mtd_info.erasesize * mul;
289      fprintf (stderr,
290               "The free memory is not enough, writing image per %d bytes.\n",
291               erase_info.length);
292    }
293
294  /* Allocate temporary buffer */
295  if (!(buf = malloc (erase_info.length)))
296    {
297      mul = 1;
298      erase_info.length = mtd_info.erasesize * mul;
299      fprintf (stderr,
300               "The free memory is not enough, writing image per %d bytes.\n",
301               erase_info.length);
302      if (!(buf = malloc (erase_info.length)))
303        {
304          perror ("malloc");
305          goto fail;
306        }
307    }
308
309  /* Calculate CRC over header */
310  crc = crc32 ((uint8 *) & trx.flag_version,
311               sizeof (struct trx_header) - OFFSETOF (struct trx_header,
312                                                      flag_version),
313               CRC32_INIT_VALUE);
314  crc_data = 0;
315  /* Write file or URL to MTD device */
316  for (erase_info.start = 0; erase_info.start < trx.len;
317       erase_info.start += count)
318    {
319      len = MIN (erase_info.length, trx.len - erase_info.start);
320      if ((STORE32_LE (trx.flag_version) & TRX_NO_HEADER) || erase_info.start)
321        count = off = 0;
322      else
323        {
324          count = off = sizeof (struct trx_header);
325          memcpy (buf, &trx, sizeof (struct trx_header));
326        }
327//      if (fp)
328        count += safe_fread (&buf[off], 1, len - off, fp);
329//      else
330//      count +=
331//        http_get (path, &buf[off], len - off, erase_info.start + off);
332
333      /* for debug */
334      sum = sum + count;
335      fprintf (stderr, "write=[%ld]         \n", sum);
336
337      if (((count < len) && (len - off) > (mtd_info.erasesize * mul)) || (count == 0))
338        {
339          fprintf (stderr, "%s: Truncated file (actual %ld expect %ld)\n",
340                   path, count - off, len - off);
341          goto fail;
342        }
343      /* Update CRC */
344      crc = crc32 (&buf[off], count - off, crc);
345      if (!squashfound)
346      {
347      for (i=0;i<(count-off);i++)
348        {
349        unsigned int *sq = (unsigned int *)&buf[off+i];
350        if (*sq == SQUASHFS_MAGIC)
351            {
352            squashfound=1;
353            break;
354            }
355        crc_data+=(unsigned char)buf[off+i];
356        }
357      data_len+=i;
358      }
359      /* Check CRC before writing if possible */
360      if (count == trx.len)
361        {
362          if (crc != trx.crc32)
363            {
364              fprintf (stderr, "%s: Bad CRC\n", path);
365              goto fail;
366            }
367          else
368            {
369              fprintf (stderr, "%s: CRC OK\n", mtd);
370              fprintf (stderr,
371                       "Writing image to flash, waiting a moment...\n");
372            }
373        }
374      erase_info.length = ROUNDUP (count, mtd_info.erasesize);
375      /* Do it */
376      (void) ioctl (mtd_fd, MEMUNLOCK, &erase_info);
377      if (ioctl (mtd_fd, MEMERASE, &erase_info) != 0 ||
378          write (mtd_fd, buf, count) != count)
379        {
380          perror (mtd);
381          goto fail;
382        }
383    }
384
385  ret = 0;
386
387fail:
388  if (buf)
389    {
390      /* Dummy read to ensure chip(s) are out of lock/suspend state */
391      (void) read (mtd_fd, buf, 2);
392      free (buf);
393    }
394
395  if (mtd_fd >= 0)
396    close (mtd_fd);
397  if (fp)
398    fclose (fp);
399#ifdef HAVE_CA8
400buf = malloc(65536);
401FILE *in=fopen("/dev/mtdblock/2","rb");
402fread(buf,65536,1,in);
403fclose(in);
404struct img_info *image_info;
405image_info = buf+0x56;
406image_info->lenght = data_len;
407image_info->CRC = crc_data;
408in=fopen("/tmp/bdata","wb");
409fwrite(buf,65536,1,in);
410fclose(in);
411fprintf(stderr,"fixup CRC %X and LEN %X\n",crc_data,data_len);
412eval("mtd","-f","write","/tmp/bdata","bdata");
413#endif
414//    eval("fischecksum");
415
416
417  return ret;
418}
419
420
421/*
422 * Irving -  We need an unlock function in order to mount a r/w jffs2 partition
423 * Unlock an MTD device
424 * @param       mtd     path to or partition name of MTD device
425 * @return      0 on success and errno on failure
426 */
427int
428mtd_unlock (const char *mtd)
429{
430  int mtd_fd;
431  struct mtd_info_user mtd_info;
432  struct erase_info_user lock_info;
433
434  /* Open MTD device */
435  if ((mtd_fd = mtd_open (mtd, O_RDWR)) < 0)
436    {
437      perror (mtd);
438      return errno;
439    }
440
441  /* Get sector size */
442  if (ioctl (mtd_fd, MEMGETINFO, &mtd_info) != 0)
443    {
444      perror (mtd);
445      close (mtd_fd);
446      return errno;
447    }
448
449  lock_info.start = 0;
450  lock_info.length = mtd_info.size;
451
452  if (ioctl (mtd_fd, MEMUNLOCK, &lock_info))
453    {
454      fprintf (stderr, "Could not unlock MTD device: %s\n", mtd);
455      perror (mtd);
456      close (mtd_fd);
457      return errno;
458    }
459
460  close (mtd_fd);
461  return 0;
462}
Note: See TracBrowser for help on using the repository browser.